示例#1
0
        private DataBlockElement[] ReadExtensibleArrayDataBlock(ExtensibleArrayHeader header, uint chunkSizeLength, uint elementIndex)
        {
            var secondaryBlockIndex = header.ComputeSecondaryBlockIndex(elementIndex + header.IndexBlockElementsCount);
            var elementsCount       = header.SecondaryBlockInfos[secondaryBlockIndex].ElementsCount;
            var dataBlock           = new ExtensibleArrayDataBlock(this.Context.Reader,
                                                                   this.Context.Superblock,
                                                                   header,
                                                                   chunkSizeLength,
                                                                   elementsCount);

            if (dataBlock.PageCount > 0)
            {
                var pages = new List <DataBlockPage>((int)dataBlock.PageCount);

                for (int i = 0; i < (int)dataBlock.PageCount; i++)
                {
                    var page = new DataBlockPage(this.Context.Reader,
                                                 this.Context.Superblock,
                                                 header.DataBlockPageElementsCount,
                                                 dataBlock.ClientID,
                                                 chunkSizeLength);
                    pages.Add(page);
                }

                return(pages
                       .SelectMany(page => page.Elements)
                       .ToArray());
            }
            else
            {
                return(dataBlock.Elements);
            }
        }
示例#2
0
        // for later: H5EA__lookup_elmt

        private void ReadExtensibleArray(Span <byte> buffer, ulong chunkSize)
        {
            var chunkSizeLength = this.ComputeChunkSizeLength(chunkSize);
            var header          = new ExtensibleArrayHeader(this.Context.Reader, this.Context.Superblock, chunkSizeLength);
            var indexBlock      = header.IndexBlock;
            var elementIndex    = 0U;

            var elements = new List <DataBlockElement>()
                           .AsEnumerable();

            // elements
            elements = elements.Concat(indexBlock.Elements);

            // data blocks
            ReadDataBlocks(indexBlock.DataBlockAddresses);

            // secondary blocks
#warning Is there any precalculated way to avoid checking all addresses?
            var addresses = indexBlock
                            .SecondaryBlockAddresses
                            .Where(address => !this.Context.Superblock.IsUndefinedAddress(address));

            foreach (var secondaryBlockAddress in addresses)
            {
                this.Context.Reader.Seek((long)secondaryBlockAddress, SeekOrigin.Begin);
                var secondaryBlockIndex = header.ComputeSecondaryBlockIndex(elementIndex + header.IndexBlockElementsCount);
                var secondaryBlock      = new ExtensibleArraySecondaryBlock(this.Context.Reader, this.Context.Superblock, header, secondaryBlockIndex);
                ReadDataBlocks(secondaryBlock.DataBlockAddresses);
            }

            var offset = 0UL;

            foreach (var element in elements)
            {
                // if page/element is initialized (see also datablock.PageBitmap)
#warning Is there any precalculated way to avoid checking all addresses?
                if (element.Address > 0 && !this.Context.Superblock.IsUndefinedAddress(element.Address))
                {
                    this.SeekSliceAndReadChunk(offset, chunkSize, element.ChunkSize, element.Address, buffer);
                }

                offset += chunkSize;
            }

            void ReadDataBlocks(ulong[] dataBlockAddresses)
            {
#warning Is there any precalculated way to avoid checking all addresses?
                dataBlockAddresses = dataBlockAddresses
                                     .Where(address => !this.Context.Superblock.IsUndefinedAddress(address))
                                     .ToArray();

                foreach (var dataBlockAddress in dataBlockAddresses)
                {
                    this.Context.Reader.Seek((long)dataBlockAddress, SeekOrigin.Begin);
                    var newElements = this.ReadExtensibleArrayDataBlock(header, chunkSizeLength, elementIndex);
                    elements      = elements.Concat(newElements);
                    elementIndex += (uint)newElements.Length;
                }
            }
        }
示例#3
0
        public ExtensibleArrayIndexBlock(
            H5BinaryReader reader,
            Superblock superblock,
            ExtensibleArrayHeader header,
            Func <H5BinaryReader, T> decode)
        {
            // H5EAiblock.c (H5EA__iblock_alloc)
            this.SecondaryBlockDataBlockAddressCount = 2 * (ulong)Math.Log(header.SecondaryBlockMinimumDataBlockPointerCount, 2);
            ulong dataBlockPointerCount      = (ulong)(2 * (header.SecondaryBlockMinimumDataBlockPointerCount - 1));
            ulong secondaryBlockPointerCount = header.SecondaryBlockCount - this.SecondaryBlockDataBlockAddressCount;

            // signature
            var signature = reader.ReadBytes(4);

            H5Utils.ValidateSignature(signature, ExtensibleArrayIndexBlock <T> .Signature);

            // version
            this.Version = reader.ReadByte();

            // client ID
            this.ClientID = (ClientID)reader.ReadByte();

            // header address
            this.HeaderAddress = superblock.ReadOffset(reader);

            // elements
            this.Elements = Enumerable
                            .Range(0, header.IndexBlockElementsCount)
                            .Select(i => decode(reader))
                            .ToArray();

            // data block addresses
            this.DataBlockAddresses = new ulong[dataBlockPointerCount];

            for (ulong i = 0; i < dataBlockPointerCount; i++)
            {
                this.DataBlockAddresses[i] = superblock.ReadOffset(reader);
            }

            // secondary block addresses
            this.SecondaryBlockAddresses = new ulong[secondaryBlockPointerCount];

            for (ulong i = 0; i < secondaryBlockPointerCount; i++)
            {
                this.SecondaryBlockAddresses[i] = superblock.ReadOffset(reader);
            }

            // checksum
            this.Checksum = reader.ReadUInt32();
        }
示例#4
0
        public ExtensibleArraySecondaryBlock(H5BinaryReader reader, Superblock superblock, ExtensibleArrayHeader header, uint index)
        {
            // H5EAsblock.c (H5EA__sblock_alloc)

            /* Compute/cache information */
            var dataBlocksCount              = header.SecondaryBlockInfos[index].DataBlockCount;
            var elementsCount                = header.SecondaryBlockInfos[index].ElementsCount;
            var dataBlockPageCount           = 0UL;
            var dataBlockPageInitBitMaskSize = 0UL;

            /* Check if # of elements in data blocks requires paging */
            if (elementsCount > header.DataBlockPageElementsCount)
            {
                /* Compute # of pages in each data block from this super block */
                dataBlockPageCount = elementsCount / header.DataBlockPageElementsCount;

                /* Sanity check that we have at least 2 pages in data block */
                if (dataBlockPageCount < 2)
                {
                    throw new Exception("There must be at least two pages in the data block.");
                }

                /* Compute size of buffer for each data block's 'page init' bitmask */
                dataBlockPageInitBitMaskSize = dataBlockPageCount + 7 / 8;
            }

            // signature
            var signature = reader.ReadBytes(4);

            H5Utils.ValidateSignature(signature, ExtensibleArraySecondaryBlock.Signature);

            // version
            this.Version = reader.ReadByte();

            // client ID
            this.ClientID = (ClientID)reader.ReadByte();

            // header address
            this.HeaderAddress = superblock.ReadOffset(reader);

            // block offset
            this.BlockOffset = H5Utils.ReadUlong(reader, header.ArrayOffsetsSize);

            // page bitmap
            // H5EAcache.c (H5EA__cache_sblock_deserialize)

            /* Check for 'page init' bitmasks for this super block */
            if (dataBlockPageCount > 0)
            {
                /* Compute total size of 'page init' buffer */
                var totalPageInitSize = dataBlocksCount * dataBlockPageInitBitMaskSize;

                /* Retrieve the 'page init' bitmasks */
                this.PageBitmap = reader.ReadBytes((int)totalPageInitSize);
            }

            // data block addresses
            this.DataBlockAddresses = new ulong[dataBlocksCount];

            for (ulong i = 0; i < dataBlocksCount; i++)
            {
                this.DataBlockAddresses[i] = superblock.ReadOffset(reader);
            }

            // checksum
            this.Checksum = reader.ReadUInt32();
        }
        public ExtensibleArrayIndexBlock(H5BinaryReader reader, Superblock superblock, ExtensibleArrayHeader header, uint chunkSizeLength)
        {
            // H5EAiblock.c (H5EA__iblock_alloc)
            ulong secondaryBlockDataBlockAddressCount = 2 * (ulong)Math.Log(header.SecondaryBlockMinimumDataBlockPointerCount, 2);
            ulong dataBlockPointerCount      = (ulong)(2 * (header.SecondaryBlockMinimumDataBlockPointerCount - 1));
            ulong secondaryBlockPointerCount = header.SecondaryBlockCount - secondaryBlockDataBlockAddressCount;

            // signature
            var signature = reader.ReadBytes(4);

            H5Utils.ValidateSignature(signature, ExtensibleArrayIndexBlock.Signature);

            // version
            this.Version = reader.ReadByte();

            // client ID
            this.ClientID = (ClientID)reader.ReadByte();

            // header address
            this.HeaderAddress = superblock.ReadOffset(reader);

            // elements
            this.Elements = ArrayIndexUtils.ReadElements(reader, superblock, header.IndexBlockElementsCount, this.ClientID, chunkSizeLength);

            // data block addresses
            this.DataBlockAddresses = new ulong[dataBlockPointerCount];

            for (ulong i = 0; i < dataBlockPointerCount; i++)
            {
                this.DataBlockAddresses[i] = superblock.ReadOffset(reader);
            }

            // secondary block addresses
            this.SecondaryBlockAddresses = new ulong[secondaryBlockPointerCount];

            for (ulong i = 0; i < secondaryBlockPointerCount; i++)
            {
                this.SecondaryBlockAddresses[i] = superblock.ReadOffset(reader);
            }

            // checksum
            this.Checksum = reader.ReadUInt32();
        }
示例#6
0
        public ExtensibleArrayDataBlock(H5BinaryReader reader, Superblock superblock, ExtensibleArrayHeader header, ulong elementCount, Func <H5BinaryReader, T> decode)
        {
            // H5EAdblock.c (H5EA__dblock_alloc)
            this.PageCount = 0UL;

            if (elementCount > header.DataBlockPageElementsCount)
            {
                /* Set the # of pages in the data block */
                this.PageCount = elementCount / header.DataBlockPageElementsCount;
            }

            // H5EAcache.c (H5EA__cache_dblock_deserialize)

            // signature
            var signature = reader.ReadBytes(4);

            H5Utils.ValidateSignature(signature, ExtensibleArrayDataBlock <T> .Signature);

            // version
            this.Version = reader.ReadByte();

            // client ID
            this.ClientID = (ClientID)reader.ReadByte();

            // header address
            this.HeaderAddress = superblock.ReadOffset(reader);

            // block offset
            this.BlockOffset = H5Utils.ReadUlong(reader, header.ArrayOffsetsSize);

            // elements
            if (this.PageCount == 0)
            {
                this.Elements = Enumerable
                                .Range(0, (int)elementCount)
                                .Select(i => decode(reader))
                                .ToArray();
            }
            else
            {
                this.Elements = new T[0];
            }

            // checksum
            this.Checksum = reader.ReadUInt32();
        }
示例#7
0
        public ExtensibleArrayDataBlock(H5BinaryReader reader, Superblock superblock, ExtensibleArrayHeader header, uint chunkSizeLength, ulong elementsCount)
        {
            // H5EAdblock.c (H5EA__dblock_alloc)
            this.PageCount = 0UL;

            if (elementsCount > header.DataBlockPageElementsCount)
            {
                /* Set the # of pages in the data block */
                this.PageCount = elementsCount / header.DataBlockPageElementsCount;
            }

            // H5EAcache.c (H5EA__cache_dblock_deserialize)

            // signature
            var signature = reader.ReadBytes(4);

            H5Utils.ValidateSignature(signature, ExtensibleArrayDataBlock.Signature);

            // version
            this.Version = reader.ReadByte();

            // client ID
            this.ClientID = (ClientID)reader.ReadByte();

            // header address
            this.HeaderAddress = superblock.ReadOffset(reader);

            // block offset
            this.BlockOffset = H5Utils.ReadUlong(reader, header.ArrayOffsetsSize);

            // elements
            if (this.PageCount == 0)
            {
                this.Elements = ArrayIndexUtils.ReadElements(reader, superblock, elementsCount, this.ClientID, chunkSizeLength);
            }

            // checksum
            this.Checksum = reader.ReadUInt32();
        }