/// <summary>
        /// Read block data and parse
        /// </summary>
        /// <param name="stream">File stream used for read</param>
        /// <param name="blockIndex">Index of block in sequence</param>
        /// <param name="headerLength">Number of bytes of header</param>
        /// <param name="blockSize">One block size</param>
        /// <returns>(Block MetaHeader, DataItem in array)</returns>
        private static (BlockMeta blockMeta, DataItem[] blockdata) ReadBlock(FileStream stream, int blockIndex, int headerLength, int blockSize)
        {
            // Init array for full block bytes
            byte[] blockBytes = new byte[blockSize];

            // Read all bytes of specific block
            blockBytes = ReadBytes(stream, blockSize, headerLength + (blockSize * blockIndex));
            int offset = 0;

            // Read block metaHeader size
            int blockMetaSize = BitConverter.ToInt32(blockBytes, offset);

            offset += sizeof(int);

            // Read MetaHeader
            BlockMeta blockMeta = BytesToObject <BlockMeta>(blockBytes, offset, blockMetaSize);

            offset += blockMetaSize;

            // Read Data Size
            int blockDataSize = BitConverter.ToInt32(blockBytes, offset);

            offset += sizeof(int);

            // Read Data
            DataItem[] items = BytesToObject <DataItem[]>(blockBytes, offset, blockDataSize);

            return(blockMeta, items);
        }
Example #2
0
 /// <summary>
 /// 释放缓冲区
 /// </summary>
 /// <param name="blockMeta">区块元数据</param>
 private void ReleaseBlock(BlockMeta blockMeta)
 {
     if (blockMeta != null)
     {
         ReleaseBuffer(blockMeta.Storage);
     }
 }
Example #3
0
        public void SetBlockMeta(int x, int y, int z, BlockMeta meta)
        {
            x = NumericsHelper.Modulo(x, 16);
            z = NumericsHelper.Modulo(z, 16);
            var value = (short)((x << 8) | (z << 4) | y);

            this.BlockMetaStore[value] = meta;
        }
Example #4
0
    public BlockMeta Build()
    {
        var meta = new BlockMeta
        {
            Name           = this.Name,
            Lore           = this.lore,
            CanPlaceOn     = this.canPlaceOn,
            BlockEntityTag = this.BlockEntityTag,
            BlockStateTag  = this.BlockStateTag
        };

        return(meta);
    }
        /// <summary>
        /// Read block header
        /// </summary>
        /// <param name="stream">File stream used for read</param>
        /// <param name="blockIndex">Index of block in sequence</param>
        /// <param name="headerLength">Number of bytes of header</param>
        /// <param name="blockSize">One block size</param>
        /// <returns>(Block MetaHeader, DataItem in array)</returns>
        private static BlockMeta ReadBlockHeader(FileStream stream, int blockIndex, int headerLength, int blockSize)
        {
            // Read all bytes of specific block
            byte[] blockHeaderSizeBytes = ReadBytes(stream, sizeof(int), headerLength + (blockSize * blockIndex));

            // Read block metaHeader size
            int blockMetaSize = BitConverter.ToInt32(blockHeaderSizeBytes, 0);

            // Read block header bytes
            byte[] blockHeaderBytes = ReadBytes(stream, blockMetaSize, headerLength + (blockSize * blockIndex) + sizeof(int));

            // Deserialize MetaHeader
            BlockMeta blockMeta = BytesToObject <BlockMeta>(blockHeaderBytes);

            return(blockMeta);
        }
        /// <summary>
        /// Find block with valid range for finding value
        /// </summary>
        /// <param name="stream">File stream used for read</param>
        /// <param name="metadata">File metadata</param>
        /// <param name="keyHash">Searching hash value</param>
        /// <param name="headerLength">File header size (offset for first block)</param>
        /// <param name="method">Searching method</param>
        /// <returns>Data array of appropriate block</returns>
        private (int blockID, DataItem[] blockData) FindBlockData(FileStream stream, FileMeta metadata, int keyHash, int headerLength, SearchMethod method)
        {
            int left  = 0;
            int right = (metadata.BuildValuesCount - 1);
            int mid;
            int maxVal = metadata.BuildMax;
            int minVal = metadata.BuildMin;

            // While until search interval is valid
            while (left <= right && keyHash >= minVal && keyHash <= maxVal)
            {
                // Calculate middle index
                mid = CalculateMiddle(left, right, minVal, maxVal, keyHash, method);
                // Get blockID with item with middle index
                int blockId = mid / _itemsForBlock;

                if (mid < 0 && mid > metadata.ActualValuesCount)
                {
                    throw new ApplicationException("Invalid operation! Out of range!");
                }

                // Read block header
                BlockMeta block = ReadBlockHeader(stream, blockId, headerLength, metadata.BlockSize);

                if (block.Min <= keyHash && keyHash <= block.Max)
                {
                    // Read block data for search value (value is in this range)
                    DataItem[] data = ReadBlock(stream, blockId, headerLength, metadata.BlockSize).blockdata;
                    return(blockId, data);
                }

                if (block.Max < keyHash)
                {
                    // Is in the upper part
                    left = mid + 1;
                }
                else
                {
                    // Is in the lower part
                    right = mid - 1;
                }
            }

            // Valid block not found
            return(-1, null);
        }
Example #7
0
        /// <summary>
        /// 保障存储块满足存储条件
        /// </summary>
        /// <param name="value">总共需要占用的空间</param>
        private void EnsureStorageBlock(long value)
        {
            AssertMemoryUseable(value);

            if (value <= 0)
            {
                return;
            }

            var minBlockCount = (int)((value / BlockSize) + ((value % BlockSize) == 0 ? 0 : 1));

            if (storage.Length >= minBlockCount)
            {
                return;
            }

            var newStorage = new BlockMeta[minBlockCount.ToPrime()];

            Array.Copy(storage, 0, newStorage, 0, storage.Length);
            storage = newStorage;
        }
        /// <summary>
        /// Build binary data block
        /// </summary>
        /// <param name="data">Data to serialize for block</param>
        /// <returns>Block bytes</returns>
        private static byte[] BuildBlock(DataItem[] data, int?minVal = null, int?maxVal = null)
        {
            int offset = 0;

            // Prepare block meta data
            BlockMeta meta = new BlockMeta();

            meta.Min = (int)(minVal == null ? data[0].HashKey : minVal);
            meta.Max = (int)(maxVal == null ? data[data.Count() - 1].HashKey : maxVal);

            // Serialize objects
            byte[] metaBytes = ObjectToBytes(meta);
            byte[] metaSize  = BitConverter.GetBytes(metaBytes.Length);
            byte[] dataBytes = ObjectToBytes(data.ToArray());
            byte[] dataSize  = BitConverter.GetBytes(dataBytes.Length);

            // Prepare output array
            byte[] output = new byte[metaBytes.Length + metaSize.Length + dataBytes.Length + dataSize.Length];

            // Copy MetaDataSize bytes to output
            Array.Copy(metaSize, output, metaSize.Length);
            offset += metaSize.Length;

            // Copy MetaData bytes to output
            Array.Copy(metaBytes, 0, output, offset, metaBytes.Length);
            offset += metaBytes.Length;

            // Copy DataSize bytes to output
            Array.Copy(dataSize, 0, output, offset, dataSize.Length);
            offset += dataSize.Length;

            // Copy Data bytes to output
            Array.Copy(dataBytes, 0, output, offset, dataBytes.Length);
            offset += dataBytes.Length;

            return(output);
        }
Example #9
0
 /// <summary>
 /// String representation of the block
 /// </summary>
 public override string ToString()
 {
     return(BlockId.ToString() + (BlockMeta != 0 ? ":" + BlockMeta.ToString() : ""));
 }
Example #10
0
 public void SetBlockMeta(Vector position, BlockMeta meta) => SetBlockMeta(position.X, position.Y, position.Z, meta);
Example #11
0
 public void SetBlockMeta(Vector position, BlockMeta meta) => this.SetBlockMeta((int)position.X, (int)position.Y, (int)position.Z, meta);