/// <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); }
/// <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(); }