Example #1
0
        Result <Pointer> ExpandLevel(string key, StoredValue value)
        {
            if (Level == 0)
            {
                return(new ArgumentOutOfRange <Pointer>(nameof(Level)));
            }

            var md          = InMemoryMd.Create(Level - 1);
            var leafPointer = (md as InMemoryMd).Add(key, value);

            if (!leafPointer.HasValue)
            {
                return(leafPointer);
            }

            switch (md.Type)
            {
            case MdType.Pointers:     // i.e. we have still not reached the end of the tree
                Add(new Pointer
                {
                    MdLocator = md.MdLocator,
                    ValueType = typeof(Pointer).Name
                });
                break;

            case MdType.Values:      // i.e. we are now right above leaf level
                Add(leafPointer.Value);
                break;

            default:
                return(new ArgumentOutOfRange <Pointer>(nameof(md.Type)));
            }

            return(leafPointer);
        }
Example #2
0
        Result <Pointer> Set(string key, StoredValue value)
        {
            switch (Type)
            {
            case MdType.Pointers:
                return(new InvalidOperation <Pointer>($"Cannot set values directly on pointers. Key {key}, value type {value.ValueType}"));

            case MdType.Values:
                _valueFields[key] = value;
                return(Result.OK(new Pointer
                {
                    MdLocator = this.MdLocator,
                    MdKey = key,
                    ValueType = value.ValueType
                }));

            default:
                return(new ArgumentOutOfRange <Pointer>(nameof(Type)));
            }
        }
Example #3
0
        // It will return the direct pointer to the stored value
        // which makes it readily available for indexing at higher levels.
        Result <Pointer> Add(string key, StoredValue value)
        {
            if (IsFull)
            {
                return(new MdOutOfEntriesError <Pointer>($"Filled: {Count}/{MdMetadata.Capacity}"));
            }
            switch (Type)
            {
            case MdType.Pointers:
                if (Count == 0)
                {
                    return(ExpandLevel(key, value));
                }

                var target = Locate(_pointerFields[Count].MdLocator);
                if (target.IsFull)
                {
                    return(ExpandLevel(key, value));
                }

                return((target as InMemoryMd).Add(key, value));

            case MdType.Values:
                if (_valueFields.ContainsKey(key))
                {
                    return(new ValueAlreadyExists <Pointer>($"Key: {key}."));
                }

                _valueFields[key] = value;
                Count++;
                return(Result.OK(new Pointer
                {
                    MdLocator = this.MdLocator,
                    MdKey = key,
                    ValueType = value.ValueType
                }));

            default:
                return(new ArgumentOutOfRange <Pointer>(nameof(Type)));
            }
        }
Example #4
0
        async Task <Result <Pointer> > DirectlyAddToLeaf(string key, StoredValue value)
        {
            if (_currentLeaf == null)
            {
                _currentLeaf = _head;
            }
            else if (_currentLeaf.IsFull)
            {
                var result = await _head.AddAsync(key, value).ConfigureAwait(false);

                var leafResult = await MdAccess.LocateAsync(result.Value.MdLocator);

                if (leafResult.HasValue)
                {
                    _currentLeaf = leafResult.Value;
                }
                return(result);
            }

            return(await _currentLeaf.AddAsync(key, value));
        }
Example #5
0
        public async Task <Result <Pointer> > AddAsync(string key, StoredValue value)
        {
            if (_head.IsFull)
            {
                // create new head, add pointer to current head in to it.
                // the level > 0 indicates its role as pointer holder
                var newHead = await MdAccess.CreateAsync(_head.Level + 1).ConfigureAwait(false);

                var pointer = new Pointer
                {
                    MdLocator = _head.MdLocator,
                    ValueType = typeof(Pointer).Name
                };
                await newHead.AddAsync(pointer).ConfigureAwait(false);

                _head = newHead;
                await _onHeadAddressChange(newHead.MdLocator).ConfigureAwait(false);
            }

            return(await DirectlyAddToLeaf(key, value).ConfigureAwait(false));
        }
Example #6
0
 private InMemoryMd(int level)
 {
     MdLocator = new MdLocator(new byte[32], DataProtocol.DEFAULT_PROTOCOL);
     _rand.NextBytes(MdLocator.XORName);
     _valueFields["0"] = new StoredValue(level);
 }
Example #7
0
 public Task <Result <Pointer> > AddAsync(string key, StoredValue value)
 {
     return(Task.FromResult(Add(key, value)));
 }
Example #8
0
 public Task <Result <Pointer> > SetAsync(string key, StoredValue value, long expectedVersion = -1)
 {
     return(Task.FromResult(Set(key, value)));
 }
Example #9
0
 public async Task AddAsync(string type, MdLocator location)
 {
     var value = new StoredValue(location);
     await _dataTree.AddAsync(type, value).ConfigureAwait(false);
 }