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); }
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); }
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); }
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); } } }