Exemplo n.º 1
0
        /// <summary>
        /// 分割当前节点
        /// </summary>
        /// <param name="splitFirstKey">新分割节点的第一个键,也就是最小的键</param>
        /// <param name="splitNode">新分割节点</param>
        private void SplitLeaf(ref string splitFirstKey, ref BPlusTreeNode splitNode)
        {
            // 从中间开始分割
            int splitPoint  = this._childKeys.Length / 2;
            int splitLength = this._childKeys.Length - splitPoint;

            // 新创建的分割出的节点
            splitNode = new BPlusTreeNode(this.Tree, this.Parent, -1, this.IsLeaf);

            // 将指定分割点右侧的数据拷贝至新的节点,新节点为当前节点的右兄弟节点
            Array.Copy(this._childKeys, splitPoint, splitNode._childKeys, 0, splitLength);
            Array.Copy(this._childValues, splitPoint, splitNode._childValues, 0, splitLength);
            Array.Copy(this._childNodes, splitPoint, splitNode._childNodes, 0, splitLength);

            // 记录分割节点的第一个键
            splitFirstKey = splitNode._childKeys[0];

            // 存储新节点至块文件
            splitNode.DumpToNewBlock();

            // 分割完毕,当前节点恢复之前的扩容,处理分割点左侧数据
            RepairAfterSplit(splitPoint);

            // 我可以被释放掉
            this.Tree.RecordTerminalNode(splitNode);

            // 新节点及其父节点需要标记为脏节点
            splitNode.Soil();
        }
Exemplo n.º 2
0
        /// <summary>
        /// 分割当前节点
        /// </summary>
        /// <param name="splitFirstKey">新分割节点的第一个键,也就是最小的键</param>
        /// <param name="splitNode">新分割节点</param>
        private void SplitInternal(ref string splitFirstKey, ref BPlusTreeNode splitNode)
        {
            // 从中间开始分割
            int splitPoint = this._childNodes.Length / 2 - 1;

            // 分割出的新节点的第一个键
            splitFirstKey = this._childKeys[splitPoint];

            // 新建节点,包含分割点右侧所有数据
            splitNode = new BPlusTreeNode(this.Tree, this.Parent, -1, this.IsLeaf);
            splitNode.Clear(); // redundant.

            // 记录已经扩充的数据结构
            long[]          values = this._childValues;
            string[]        keys   = this._childKeys;
            BPlusTreeNode[] nodes  = this._childNodes;

            // 重置和清空数据
            this.Clear();

            // 将分割点左侧的数据拷贝至此节点
            Array.Copy(keys, 0, this._childKeys, 0, splitPoint);
            Array.Copy(values, 0, this._childValues, 0, splitPoint + 1);
            Array.Copy(nodes, 0, this._childNodes, 0, splitPoint + 1);

            // 将分割点右侧的数据拷贝至新的分割节点
            int remainingKeys = this.Capacity - splitPoint;

            Array.Copy(keys, splitPoint + 1, splitNode._childKeys, 0, remainingKeys);
            Array.Copy(values, splitPoint + 1, splitNode._childValues, 0, remainingKeys + 1);
            Array.Copy(nodes, splitPoint + 1, splitNode._childNodes, 0, remainingKeys + 1);

            // 重置新节点中所有的子节点的父节点
            splitNode.ResetAllChildrenParent();

            // 存储新节点
            splitNode.DumpToNewBlock();
            splitNode.CheckIfTerminal();
            splitNode.Soil();

            this.CheckIfTerminal();
        }