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

            BPlusTreeLong tree = new BPlusTreeLong(fromFile, seekStart, 100, 7, (byte)1); // dummy values for nodesize, keysize

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

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

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

            return(tree);
        }
Exemplo n.º 2
0
        /// <summary>
        /// 创建B+树
        /// </summary>
        /// <param name="treeFileStream">指定树文件的文件流</param>
        /// <param name="blockFileStream">指定块文件的文件流</param>
        /// <param name="keyLength">树允许的键的长度</param>
        /// <param name="nodeCapacity">树允许的各子节点的最大容量</param>
        /// <param name="blockSize">块大小</param>
        /// <returns>B+树</returns>
        public static BPlusTreeBytes Create(Stream treeFileStream, Stream blockFileStream, int keyLength, int nodeCapacity, int blockSize)
        {
            BPlusTreeLong tree    = BPlusTreeLong.InitializeInStream(treeFileStream, (long)0, keyLength, nodeCapacity);
            LinkedFile    archive = LinkedFile.InitializeInStream(blockFileStream, (long)0, blockSize);

            return(new BPlusTreeBytes(tree, archive));
        }
Exemplo n.º 3
0
        /// <summary>
        /// 从文件打开B+树
        /// </summary>
        /// <param name="treeFileStream">指定树文件的文件流</param>
        /// <param name="blockFileStream">指定块文件的文件流</param>
        /// <returns>B+树</returns>
        public static BPlusTreeBytes Open(Stream treeFileStream, Stream blockFileStream)
        {
            BPlusTreeLong tree    = BPlusTreeLong.SetupFromExistingStream(treeFileStream, (long)0);
            LinkedFile    archive = LinkedFile.SetupFromExistingStream(blockFileStream, (long)0);

            return(new BPlusTreeBytes(tree, archive));
        }
Exemplo n.º 4
0
        /// <summary>
        /// 检测给定的键是否符合树要求键的长度
        /// </summary>
        /// <param name="key">给定的键</param>
        /// <param name="tree">给定的树</param>
        /// <returns>是否符合树要求键的长度</returns>
        public static bool ValidateKey(string key, BPlusTreeLong tree)
        {
            if (tree == null)
            {
                throw new ArgumentNullException("tree");
            }

            if (string.IsNullOrEmpty(key))
            {
                return(false);
            }

            int maxKeyLength  = tree.KeyLength;
            int maxKeyPayload = maxKeyLength - StoredConstants.ShortLength;

            char[] keyChars  = key.ToCharArray();
            int    charCount = Encoding.UTF8.GetEncoder().GetByteCount(keyChars, 0, keyChars.Length, true);

            if (charCount > maxKeyPayload)
            {
                return(false);
            }

            return(true);
        }
Exemplo n.º 5
0
        /// <summary>
        /// 从指定的流初始化树
        /// </summary>
        /// <param name="fromFile">指定的流</param>
        /// <param name="seekStart">流起始查询点</param>
        /// <param name="keyLength">键长度</param>
        /// <param name="nodeCapacity">节点容量</param>
        /// <returns>树</returns>
        public static BPlusTreeLong InitializeInStream(Stream fromFile, long seekStart, int keyLength, int nodeCapacity)
        {
            if (fromFile == null)
            {
                throw new ArgumentNullException("fromFile");
            }

            if (fromFile.Length > seekStart)
            {
                throw new BPlusTreeException("can't initialize tree inside written area of stream");
            }

            BPlusTreeLong tree = new BPlusTreeLong(fromFile, seekStart, keyLength, nodeCapacity, (byte)1);

            tree.WriteHeader();
            tree.BlockFile = BlockFile.InitializeInStream(fromFile, seekStart + HeaderSize, StoredConstants.BlockFileHeaderPrefix, tree.BlockSize);

            return(tree);
        }
Exemplo n.º 6
0
 public static void Check(BPlusTreeLong bpt)
 {
     Console.WriteLine(bpt.ToText());
       bpt.CheckFreeBlock();
       ArrayList allkeys = new ArrayList();
       foreach (DictionaryEntry d in AllInsertHashtable)
       {
     allkeys.Add(d.Key);
       }
       allkeys.Sort();
       allkeys.Reverse();
       foreach (object thing in allkeys)
       {
     string thekey = (string)thing;
     long thevalue = (long)AllInsertHashtable[thing];
     if (thevalue != bpt[thekey])
     {
       throw new ApplicationException("no match on retrieval " + thekey + " --> " + bpt[thekey] + " not " + thevalue);
     }
       }
       allkeys.Reverse();
       string currentkey = bpt.FirstKey();
       foreach (object thing in allkeys)
       {
     string testkey = (string)thing;
     if (currentkey == null)
     {
       throw new ApplicationException("end of keys found when expecting " + testkey);
     }
     if (!testkey.Equals(currentkey))
     {
       throw new ApplicationException("when walking found " + currentkey + " when expecting " + testkey);
     }
     currentkey = bpt.NextKey(testkey);
       }
 }
Exemplo n.º 7
0
 /// <summary>
 /// B+树,固定长度字符串为键,映射至Byte数组。
 /// </summary>
 /// <param name="tree">B+树</param>
 /// <param name="archive">链式块文件</param>
 internal BPlusTreeBytes(BPlusTreeLong tree, LinkedFile archive)
 {
     this.tree    = tree;
     this.archive = archive;
 }
Exemplo n.º 8
0
 /// <summary>
 /// B+树,固定长度字符串为键,映射至Byte数组。
 /// </summary>
 /// <param name="tree">B+树</param>
 /// <param name="archive">链式块文件</param>
 internal BPlusTreeBytes(BPlusTreeLong tree, LinkedFile archive)
 {
   this.tree = tree;
   this.archive = archive;
 }
Exemplo n.º 9
0
    /// <summary>
    /// B+树节点
    /// </summary>
    /// <param name="tree">包含该节点的树</param>
    /// <param name="parent">节点的父节点</param>
    /// <param name="indexInParent">在父节点中的索引</param>
    /// <param name="isLeaf">是否为叶子节点</param>
    public BPlusTreeNode(BPlusTreeLong tree, BPlusTreeNode parent, int indexInParent, bool isLeaf)
    {
      if(tree == null)
        throw new ArgumentNullException("tree");

      this.Tree = tree;
      this.Parent = parent;
      this.IsLeaf = isLeaf;

      this.IndexInParent = -1;
      this.BlockNumber = StoredConstants.NullBlockNumber;
      this.Capacity = tree.NodeCapacity;
      this.Dirty = true;

      this.Clear();

      // 存在父节点
      if (parent != null && indexInParent >= 0)
      {
        // B+树 父节点中键值数与子节点数量相等
        if (indexInParent > this.Capacity)
        {
          throw new BPlusTreeException("parent index too large");
        }
        // 建立与父节点关系
        this.Parent.ChildNodes[indexInParent] = this;
        this.BlockNumber = this.Parent.ChildValues[indexInParent];
        this.IndexInParent = indexInParent;
      }
    }
Exemplo n.º 10
0
    /// <summary>
    /// 从指定的流初始化树
    /// </summary>
    /// <param name="fromFile">指定的流</param>
    /// <param name="seekStart">流起始查询点</param>
    /// <param name="keyLength">键长度</param>
    /// <param name="nodeCapacity">节点容量</param>
    /// <returns>树</returns>
    public static BPlusTreeLong InitializeInStream(Stream fromFile, long seekStart, int keyLength, int nodeCapacity)
    {
      if (fromFile == null)
        throw new ArgumentNullException("fromFile");

      if (fromFile.Length > seekStart)
      {
        throw new BPlusTreeException("can't initialize tree inside written area of stream");
      }

      BPlusTreeLong tree = new BPlusTreeLong(fromFile, seekStart, keyLength, nodeCapacity, (byte)1);
      tree.WriteHeader();
      tree.BlockFile = BlockFile.InitializeInStream(fromFile, seekStart + HeaderSize, StoredConstants.BlockFileHeaderPrefix, tree.BlockSize);

      return tree;
    }
Exemplo n.º 11
0
 /// <summary>
 /// 为指定树构造一个根节点
 /// </summary>
 /// <param name="tree">指定树</param>
 /// <param name="isLeaf">是否为叶子节点</param>
 /// <returns>根节点</returns>
 public static BPlusTreeNode MakeRoot(BPlusTreeLong tree, bool isLeaf)
 {
   return new BPlusTreeNode(tree, null, -1, isLeaf);
 }
Exemplo n.º 12
0
    /// <summary>
    /// 重新组织分割树,新的根节点将有两个子节点
    /// </summary>
    /// <param name="oldRoot">原根节点</param>
    /// <param name="splitFirstKey">新根节点的第一个Key</param>
    /// <param name="splitNode">新分割出的节点</param>
    /// <param name="tree">指定的树</param>
    /// <returns>新根节点</returns>
    public static BPlusTreeNode BinaryRoot(BPlusTreeNode oldRoot, string splitFirstKey, BPlusTreeNode splitNode, BPlusTreeLong tree)
    {
      if (oldRoot == null)
        throw new ArgumentNullException("oldRoot");
      if (splitNode == null)
        throw new ArgumentNullException("splitNode");

      // 已不是叶子节点
      BPlusTreeNode newRoot = MakeRoot(tree, false);

      // 新的跟记录分割节点的第一个Key
      newRoot.ChildKeys[0] = splitFirstKey;

      // 新旧节点分别为新的根节点的索引 0 1 位置
      oldRoot.ResetParent(newRoot, 0);
      splitNode.ResetParent(newRoot, 1);

      // new root is stored elsewhere
      return newRoot;
    }
Exemplo n.º 13
0
 public static void Delete(BPlusTreeLong bpt, string key)
 {
     bpt.RemoveKey(key);
       AllInsertHashtable.Remove(key);
       Check(bpt);
 }
Exemplo n.º 14
0
 public static void Commit(BPlusTreeLong bpt)
 {
     bpt.Commit();
       LastCommittedInsertHashtable = (Hashtable)AllInsertHashtable.Clone();
       Check(bpt);
 }
Exemplo n.º 15
0
    /// <summary>
    /// 从指定的流初始化树
    /// </summary>
    /// <param name="fromFile">指定的流</param>
    /// <param name="seekStart">流起始查询点</param>
    /// <returns>树</returns>
    public static BPlusTreeLong SetupFromExistingStream(Stream fromFile, long seekStart)
    {
      if (fromFile == null)
        throw new ArgumentNullException("fromFile");

      BPlusTreeLong tree = new BPlusTreeLong(fromFile, seekStart, 100, 7, (byte)1); // dummy values for nodesize, keysize
      tree.ReadHeader();
      tree.BlockFile = BlockFile.SetupFromExistingStream(fromFile, seekStart + HeaderSize, StoredConstants.BlockFileHeaderPrefix);

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

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

      return tree;
    }
Exemplo n.º 16
0
 public static void Insert(BPlusTreeLong bpt, string key, long map)
 {
     bpt.Set(key, map);
       AllInsertHashtable[key] = map;
       Check(bpt);
 }
Exemplo n.º 17
0
    /// <summary>
    /// 检测给定的键是否符合树要求键的长度
    /// </summary>
    /// <param name="key">给定的键</param>
    /// <param name="tree">给定的树</param>
    /// <returns>是否符合树要求键的长度</returns>
    public static bool ValidateKey(string key, BPlusTreeLong tree)
    {
      if (tree == null)
        throw new ArgumentNullException("tree");

      if (string.IsNullOrEmpty(key))
      {
        return false;
      }

      int maxKeyLength = tree.KeyLength;
      int maxKeyPayload = maxKeyLength - StoredConstants.ShortLength;

      char[] keyChars = key.ToCharArray();
      int charCount = Encoding.UTF8.GetEncoder().GetByteCount(keyChars, 0, keyChars.Length, true);
      if (charCount > maxKeyPayload)
      {
        return false;
      }

      return true;
    }