Esempio n. 1
0
        public IRadixTreeNode Fetch(DbItemReference reference)
        {
            if (DbItemReference.IsNull(reference))
            {
                return(null);
            }

            var page = _pageManager.FetchPage(reference.PageIndex);

            if (page.BackingObject == null)
            {
                var obj1 = RadixTreePageBackingObject.FromPage(page);
                page = new Page(_pageManager, page.Index, () => Serialize(obj1), obj1);
            }

            var backingObject = (RadixTreePageBackingObject)page.BackingObject;

            var obj = backingObject.Items[reference.ItemIndex];

            var result = obj as IRadixTreeNode;

            if (result == null)
            {
                result           = NodeFromBytes((byte[])obj);
                result.Reference = (DbItemReference)reference.Clone();
                backingObject.Items[reference.ItemIndex] = result;
            }

            return(result);
        }
Esempio n. 2
0
        public bool Update(IRadixTreeNode node)
        {
            var page = _pageManager.FetchPage(node.Reference.PageIndex);

            if (page.BackingObject == null)
            {
                var obj = RadixTreePageBackingObject.FromPage(page);
                page = new Page(_pageManager, node.Reference.PageIndex, () => Serialize(obj), obj);
            }

            var backingObject = (RadixTreePageBackingObject)page.BackingObject;
            var oldNodeSize   = backingObject.GetNodeSize(node.Reference.ItemIndex);

            var newNodeSize = GetNodeSize((short)node.Prefix.Length, node.Entries.Count);

            var oldObjectSize = backingObject.Size;

            var newObjectSize = oldObjectSize + newNodeSize - oldNodeSize;

            if (newObjectSize > _pageManager.PageSize)
            {
                return(false);
            }

            backingObject.Items[node.Reference.ItemIndex] = node;

            _pageManager.UpdatePage(page);
            return(true);
        }
Esempio n. 3
0
        public IRadixTreeNode Create(int prefixSize, int childCapacity)
        {
            CheckRoot();

            IPage page;
            short itemIndex;
            var   node = NewNode(DbItemReference.Null);

            foreach (var pageIndex in _recentPages)
            {
                page = _pageManager.FetchPage(pageIndex);

                if (page.BackingObject == null)
                {
                    var obj = RadixTreePageBackingObject.FromPage(page);
                    page = new Page(_pageManager, pageIndex, () => Serialize(obj), obj);
                }

                var backingObject = (RadixTreePageBackingObject)page.BackingObject;

                itemIndex = AddNode(backingObject, node, prefixSize, childCapacity);

                if (itemIndex != -1)
                {
                    UpdateRecentPage(page.Index);
                    node.Reference = new DbItemReference(page.Index, itemIndex);
                    _pageManager.UpdatePage(page);
                    return(node);
                }
            }

            page = _pageManager.CreatePage();
            var  obj1   = new RadixTreePageBackingObject(page.Index);
            long index1 = page.Index;

            page = new Page(_pageManager, index1, () => Serialize(obj1), obj1);

            itemIndex = AddNode((RadixTreePageBackingObject)page.BackingObject, node, prefixSize, childCapacity);
            if (itemIndex != -1)
            {
                UpdateRecentPage(page.Index);
                node.Reference = new DbItemReference(page.Index, itemIndex);
                _pageManager.UpdatePage(page);
                return(node);
            }

            Debug.Fail("Should never get here");
            return(null);
        }
Esempio n. 4
0
        public void Remove(DbItemReference reference)
        {
            if (_rootNodeReference.Equals(reference))
            {
                throw new ArgumentOutOfRangeException(nameof(reference), "Unable to delete the root node");
            }

            var page = _pageManager.FetchPage(reference.PageIndex);

            if (page.BackingObject == null)
            {
                var obj = RadixTreePageBackingObject.FromPage(page);
                page = new Page(_pageManager, reference.PageIndex, () => Serialize(obj), obj);
            }

            var backingObject = (RadixTreePageBackingObject)page.BackingObject;

            if (backingObject.Items.Count == reference.ItemIndex + 1)
            {
                backingObject.Items.RemoveAt(reference.ItemIndex);
            }
            else
            {
                backingObject.Items[reference.ItemIndex] = null;
            }

            if (backingObject.Items.Any(item => item != null))
            {
                _pageManager.UpdatePage(page);
            }
            else
            {
                _pageManager.RemovePage(page.Index);
                if (_recentPages.Contains(page.Index))
                {
                    _recentPages.Remove(page.Index);
                }
            }
        }