Ejemplo n.º 1
0
        /// <summary>
        /// 读取块存储头部
        /// </summary>
        private void ReadFileHeader()
        {
            byte[] header = new byte[this.FileHeaderSize];

            this.Stream.Seek(this.SeekStart, SeekOrigin.Begin);
            this.Stream.Read(header, 0, this.FileHeaderSize);

            int index = 0;

            // 魔数前缀
            foreach (byte b in FileHeaderPrefix)
            {
                if (header[index] != b)
                {
                    throw new LinkedFileException("invalid header prefix");
                }
                index++;
            }

            // 块的大小
            this.BlockSize = StoredHelper.RetrieveInt(header, index);
            index         += StoredConstants.IntegerLength;

            // 空闲列表头序号
            this.FreeBlockHead = StoredHelper.RetrieveLong(header, index);
            index += StoredConstants.LongLength;

            this.IsHeaderDirty = false;

            if (this.BlockSize < StoredConstants.MinBlockSize)
            {
                throw new LinkedFileException("linked file block size too small " + this.BlockSize);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 读取B+树存储头
        /// </summary>
        private void ReadHeader()
        {
            // 魔数前缀 | 版本 | 节点容量 | 键大小 | 根节点块序号 | 空闲块头序号
            // prefix | version | node size | key size | block number of root | block number of free list head
            byte[] header = new byte[HeaderSize];

            this.Stream.Seek(this.SeekStart, SeekOrigin.Begin);
            this.Stream.Read(header, 0, HeaderSize);

            // 验证头前缀魔数
            int index = 0;

            foreach (byte b in StoredConstants.TreeFileHeaderPrefix)
            {
                if (header[index] != b)
                {
                    throw new BlockFileException("invalid header prefix");
                }
                index++;
            }

            // 版本
            this.Version = header[index];
            index       += 1;

            // 节点容量
            this.NodeCapacity = StoredHelper.RetrieveInt(header, index);
            index            += StoredConstants.IntegerLength;

            // 键大小
            this.KeyLength = StoredHelper.RetrieveInt(header, index);
            index         += StoredConstants.IntegerLength;

            // 根节点块序号
            this.RootNodeBlockNumber = StoredHelper.RetrieveLong(header, index);
            index += StoredConstants.LongLength;

            // 空闲块头序号
            this.FreeBlockHeadNumber = StoredHelper.RetrieveLong(header, index);
            index += StoredConstants.LongLength;

            if (this.NodeCapacity < 2)
            {
                throw new BPlusTreeException("node size must be larger than 2");
            }
            if (this.KeyLength < 5)
            {
                throw new BPlusTreeException("Key length must be larger than 5");
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 在指定的块序号之后,查找新的空闲块头序号
        /// </summary>
        /// <param name="blockNumber">指定的块序号</param>
        /// <returns>新的空闲块头序号</returns>
        private long ParseFreeBlock(long blockNumber)
        {
            int freeSize = 1 + StoredConstants.LongLength;

            byte[] block = new byte[freeSize];

            this.BlockFile.ReadBlock(blockNumber, block, 0, freeSize);
            if (block[0] != (byte)BPlusTreeNodeIndicator.Free)
            {
                throw new BPlusTreeException("free block not marked free");
            }

            long newHead = StoredHelper.RetrieveLong(block, 1);

            return(newHead);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 读取块
        /// </summary>
        /// <param name="blockNumber">块序号</param>
        /// <param name="blockFlag">块标记</param>
        /// <param name="nextBlockNumber">链接的下一个块</param>
        /// <returns>块数据</returns>
        private byte[] ReadBlock(long blockNumber, out LinkedFileBlockFlag blockFlag, out long nextBlockNumber)
        {
            byte[] fullBuffer = new byte[LinkedBlockOverhead + this.BlockSize];
            this.BlockFile.ReadBlock(blockNumber, fullBuffer, 0, fullBuffer.Length);

            // 读取块标记
            blockFlag = (LinkedFileBlockFlag)fullBuffer[0];

            // 读取链接的下一个块的序号
            nextBlockNumber = StoredHelper.RetrieveLong(fullBuffer, 1);

            // 读取数据
            byte[] buffer = new byte[this.BlockSize];
            Array.Copy(fullBuffer, LinkedBlockOverhead, buffer, 0, this.BlockSize);

            return(buffer);
        }