/// <summary>
        /// 从指定的流初始化树
        /// </summary>
        /// <param name="fromFile">指定的流</param>
        /// <param name="seekStart">流起始查询点</param>
        /// <returns>树</returns>
        public static BPlusTree SetupFromExistingStream(Stream fromFile, long seekStart)
        {
            if (fromFile == null)
            {
                throw new ArgumentNullException("fromFile");
            }

            BPlusTree tree = new BPlusTree(fromFile, seekStart, 100, 7, (byte)1);

            tree.ReadHeader();
            tree.BlockFile = BlockFile.SetupFromExistingStream(
                fromFile, seekStart + HeaderSize, StorageConstants.BlockFileHeaderPrefix);

            if (tree.BlockFile.BlockSize != tree.BlockSize)
            {
                throw new BPlusTreeException("Inner and outer block sizes should match.");
            }

            if (tree.RootNodeBlockNumber != StorageConstants.NullBlockNumber)
            {
                tree.RootNode = BPlusTreeNode.MakeRoot(tree, true);
                tree.RootNode.LoadFromBlock(tree.RootNodeBlockNumber);
            }

            return(tree);
        }
Esempio n. 2
0
        /// <summary>
        /// 保存键值对
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        public void Set(string key, long value)
        {
            // 验证给定的键是否合法
            if (!ValidateKey(key, this))
            {
                throw new BPlusTreeBadKeyValueException(
                          string.Format("Null or too large key cannot be inserted into tree: {0}.", key));
            }

            // 指定根节点
            bool isRootInitialized = false;

            if (this.RootNode == null)
            {
                this.RootNode     = BPlusTreeNode.MakeRoot(this, true);
                isRootInitialized = true;
            }

            // 每个新键值均由根节点开始插入
            string        splitFirstKey;
            BPlusTreeNode splitNode;

            this.RootNode.Insert(key, (long)value, out splitFirstKey, out splitNode);

            // 发现根节点需要分割
            if (splitNode != null)
            {
                // 分割根节点,并二分构造一个新的根节点
                BPlusTreeNode oldRoot = this.RootNode;
                this.RootNode     = BPlusTreeNode.BinaryRoot(oldRoot, splitFirstKey, splitNode, this);
                isRootInitialized = true;
            }

            // 是否需要将根节点写入新的块
            if (isRootInitialized)
            {
                this.RootNodeBlockNumber = this.RootNode.DumpToNewBlock();
            }

            // 检测在内存中的大小 // TODO
            this.ShrinkFootprint();
        }