Пример #1
0
        private void relocate(BPlusTreeNode parentNode)
        {
            // this node has outgrown its allotted space.
            // we need to move it to the end of the file and update everybody who points to it

            // so have to update the following:
            // 1. Parent node's pointer
            // 2. Left sibling's pointer
            // 3. Right sibling's pointer
            // 4. All children's parent pointer (which points at this node)

            _tree.Log("------------ BEGIN Relocating node ------------");
            _tree.Log("BEGIN Relocating node -> ".PadRight(50) + ToString());

            // get an abandoned node (or the end of the file, whichever comes first)
            BPlusAbandonedNode abandonedNode = _tree.GetNextAvailableNodeLocation(this);

            // mark this node as abandoned in the file (and remove from cache)
            _tree.AbandonNode(this);

            //if (this.IsRoot) {
            //    // we're relocating the root.
            //    _tree.Log("TODO: what to do here, if anything?");
            //}

            if (!IsLeaf)
            {
                // only leaf nodes should track left/right siblings.
                LeftSiblingFileOffset  = -1;
                RightSiblingFileOffset = -1;
            }

            if (LeftSiblingFileOffset > -1)
            {
                BPlusTreeNode originalLeftSibling = BPlusTreeNode.Read(_tree, this.LeftSiblingFileOffset, true);
                originalLeftSibling.RightSiblingFileOffset = originalLeftSibling.IsLeaf ? abandonedNode.FileOffset : -1;
                _tree.Log(("Updating left sibling node @ " + originalLeftSibling.FileOffset + " -> ").PadRight(50) + originalLeftSibling.ToString());
                originalLeftSibling.Write(null);
            }
            if (RightSiblingFileOffset > -1)
            {
                BPlusTreeNode originalRightSibling = BPlusTreeNode.Read(_tree, this.RightSiblingFileOffset, true);
                originalRightSibling.LeftSiblingFileOffset = originalRightSibling.IsLeaf ? abandonedNode.FileOffset : -1;
                _tree.Log(("Updating right sibling node @ " + originalRightSibling.FileOffset + " -> ").PadRight(50) + originalRightSibling.ToString());
                originalRightSibling.Write(null);
            }

            if (this.IsRoot)
            {
                // special case!  no parent means this is the root node.
                // update the int at the very beginning of the file to point at the new root node
                _tree.WriteRootNodeOffset(abandonedNode.FileOffset);
            }
            else
            {
                if (parentNode != null)
                {
                    for (int i = 0; i < parentNode.KeywordCount + 1; i++)
                    {
                        if (parentNode.ChildrenByteOffsets[i] == FileOffset)
                        {
                            parentNode.ChildrenByteOffsets[i] = abandonedNode.FileOffset;
                            _tree.Log(("Updating parent node @ " + parentNode.FileOffset + " -> ").PadRight(50) + parentNode.ToString());
                            parentNode.Write(null);
                            // the Root node is cached in the tree object -- udpate it if need be
                            if (parentNode.IsRoot)
                            {
                                _tree.Root = parentNode;
                            }
                            break;
                        }
                    }
                }
            }


            _tree.Writer.BaseStream.Position = abandonedNode.FileOffset;
            FileOffset = abandonedNode.FileOffset;
            //_chunkSize = abandonedNode.ByteCount;

            _tree.Log("END Relocating node (not written yet) -> ".PadRight(50) + ToString());
            _tree.Log("------------ END Relocating node ------------");
        }