示例#1
0
        // 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);
        }
示例#2
0
        // 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);
        }
示例#3
0
        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;
                }
            }
        }
示例#4
0
 public void AddDataRow(NodeKey key, Blob data)
 {
     bytesUsed += dataRowHeaderSize + data.ByteCount;
     dataRows.Add(key, data);
     dataKeys.Add(key);
 }
示例#5
0
 public void AddDataRow(NodeKey key, byte[] data) => AddDataRow(key, new Blob(data));
示例#6
0
 public Blob GetDataRow(NodeKey key) => dataRows.ContainsKey(key) ? dataRows[key] : new Blob(new byte[0]);
示例#7
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());
                }
            }
        }
示例#8
0
        public void ReplaceData(NodeKey key, byte[] data)
        {
            var leafNode = GetLeafNode(key);

            leafNode.ReplaceDataRow(key, data);
        }
示例#9
0
        public Blob GetData(NodeKey key)
        {
            var leafNode = GetLeafNode(key);

            return(leafNode.GetDataRow(key));
        }
示例#10
0
 public void AddNode(PageIndex pageIndex, NodeKey upperKey)
 {
     upperKeyValues.Add(upperKey);
     nodeIndices.Add(upperKey, pageIndex);
 }
示例#11
0
        public PageIndex GetPageIndexForKey(NodeKey key)
        {
            var upperRange = upperKeyValues.GetViewBetween(key, upperKeyValues.Max);

            return(nodeIndices[upperRange.Min]);
        }