예제 #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;
                }
            }
        }