// Split off and return the lower half in a new node // We split off the lower half so that data about the upper key value of this node does not change public InternalNode Split() { var nodeCount = upperKeyValues.Count / 2; var splitKeys = new NodeKey[nodeCount]; upperKeyValues.CopyTo(splitKeys, 0, nodeCount); var splitNode = new InternalNode(); foreach (var upperKey in splitKeys) { splitNode.AddNode(nodeIndices[upperKey], upperKey); nodeIndices.Remove(upperKey); upperKeyValues.Remove(upperKey); } return(splitNode); }
// Split off and return the lower half in a new node // We split off the lower half so that data about the upper key value of this node does not change public LeafNode Split() { var keyCount = dataKeys.Count / 2; var upperKeys = new NodeKey[keyCount]; dataKeys.CopyTo(upperKeys, 0, keyCount); var splitNode = new LeafNode(); foreach (var upperKey in upperKeys) { splitNode.AddDataRow(upperKey, dataRows[upperKey]); dataKeys.Remove(upperKey); dataRows.Remove(upperKey); } return(splitNode); }
protected override void Deserialize(byte[] data) { var index = 1; // First byte indicates the node's type for (var i = 0; i < maxKeys; i++) { SharpDb.PageIndex pageIndex = Serializer.DeserializeInt(data, ref index); NodeKey upperKey = Serializer.DeserializeInt(data, ref index); if (upperKey != 0) { nodeIndices.Add(upperKey, pageIndex); upperKeyValues.Add(upperKey); } else { nodeIndices.Add(int.MaxValue, pageIndex); upperKeyValues.Add(int.MaxValue); break; } } }
public void AddDataRow(NodeKey key, Blob data) { bytesUsed += dataRowHeaderSize + data.ByteCount; dataRows.Add(key, data); dataKeys.Add(key); }
public void AddDataRow(NodeKey key, byte[] data) => AddDataRow(key, new Blob(data));
public Blob GetDataRow(NodeKey key) => dataRows.ContainsKey(key) ? dataRows[key] : new Blob(new byte[0]);
public void InsertData(NodeKey key, byte[] data) { if (root is LeafNode) { InsertDataInLeafRoot(key, data); return; } var nodeStack = new Stack <InternalNode>(); var currentNode = root; // Descend the btree, recording the path from root to leaf while (currentNode is InternalNode) { var currentInternalNode = (InternalNode)currentNode; nodeStack.Push(currentInternalNode); var childNodeIndex = currentInternalNode.GetPageIndexForKey(key); currentNode = GetNode(childNodeIndex); } var leafNode = (LeafNode)currentNode; if (leafNode.CanFitDataRow(data)) { var largestKey = leafNode.GetLargestKey(); leafNode.AddDataRow(key, data); } else // Split the leaf node in two and find a place for the lower-ordered one { var largestKey = leafNode.GetLargestKey(); leafNode.AddDataRow(key, data); var splitLeaf = leafNode.Split(); splitLeaf.PageIndex = pager.NewNodeIndex(); nodeCache.Add(splitLeaf.PageIndex, splitLeaf); var currentInternalNode = nodeStack.Pop(); // Take the parent to the leaf nodes if (!currentInternalNode.IsFull()) { currentInternalNode.AddNode(splitLeaf.PageIndex, splitLeaf.GetLargestKey()); } else // Keep splitting internal nodes and adding them to the parent until reaching one that can fit a new node without splitting { currentInternalNode.AddNode(splitLeaf.PageIndex, splitLeaf.GetLargestKey()); var splitInternalNode = currentInternalNode.Split(); splitInternalNode.PageIndex = pager.NewNodeIndex(); nodeCache.Add(splitInternalNode.PageIndex, splitInternalNode); currentInternalNode = GetParentNode(nodeStack, currentInternalNode); while (currentInternalNode.IsFull()) { currentInternalNode.AddNode(splitInternalNode.PageIndex, splitInternalNode.GetLargestKey()); splitInternalNode = currentInternalNode.Split(); splitInternalNode.PageIndex = pager.NewNodeIndex(); nodeCache.Add(splitInternalNode.PageIndex, splitInternalNode); currentInternalNode = GetParentNode(nodeStack, currentInternalNode); } currentInternalNode.AddNode(splitInternalNode.PageIndex, splitInternalNode.GetLargestKey()); } } }
public void ReplaceData(NodeKey key, byte[] data) { var leafNode = GetLeafNode(key); leafNode.ReplaceDataRow(key, data); }
public Blob GetData(NodeKey key) { var leafNode = GetLeafNode(key); return(leafNode.GetDataRow(key)); }
public void AddNode(PageIndex pageIndex, NodeKey upperKey) { upperKeyValues.Add(upperKey); nodeIndices.Add(upperKey, pageIndex); }
public PageIndex GetPageIndexForKey(NodeKey key) { var upperRange = upperKeyValues.GetViewBetween(key, upperKeyValues.Max); return(nodeIndices[upperRange.Min]); }