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); } }
private void ReadFixedArray(Span <byte> buffer, ulong chunkSize) { var chunkSizeLength = this.ComputeChunkSizeLength(chunkSize); var header = new FixedArrayHeader(this.Context.Reader, this.Context.Superblock, chunkSizeLength); var dataBlock = header.DataBlock; IEnumerable <DataBlockElement> elements; 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, dataBlock.ElementsPerPage, dataBlock.ClientID, chunkSizeLength); pages.Add(page); } elements = pages.SelectMany(page => page.Elements); } else { elements = dataBlock.Elements.AsEnumerable(); } var offset = 0UL; var index = 0UL; var enumerator = elements.GetEnumerator(); for (ulong i = 0; i < header.EntriesCount; i++) { enumerator.MoveNext(); var element = enumerator.Current; // if page/element is initialized (see also datablock.PageBitmap) if (element.Address > 0) { this.SeekSliceAndReadChunk(offset, chunkSize, element.ChunkSize, element.Address, buffer); } offset += chunkSize; index++; } }
private T?LookupElement <T>(ulong index, Func <H5BinaryReader, T> decode) where T : DataBlockElement { // H5FA.c (H5FA_get) /* Get the data block */ this.Dataset.Context.Reader.Seek((long)_header.DataBlockAddress, SeekOrigin.Begin); var dataBlock = new FixedArrayDataBlock <T>( this.Dataset.Context.Reader, this.Dataset.Context.Superblock, _header, decode); /* Check for paged data block */ if (dataBlock.PageCount > 0) { /* Compute the page index */ var pageIndex = index / dataBlock.ElementsPerPage; var pageBitmapEntry = dataBlock.PageBitmap[pageIndex / 8]; var bitMaskIndex = (int)pageIndex % 8; /* Check if the page is defined yet */ if ((pageBitmapEntry & H5Utils.SequentialBitMask[bitMaskIndex]) > 0) { /* Compute the element index */ var elementIndex = index % dataBlock.ElementsPerPage; /* Compute the address of the data block */ var pageSize = dataBlock.ElementsPerPage * _header.EntrySize + 4; var pageAddress = this.Dataset.Context.Reader.BaseStream.Position + (long)(pageIndex * pageSize); /* Check for using last page, to set the number of elements on the page */ ulong elementCount; if (pageIndex + 1 == dataBlock.PageCount) { elementCount = dataBlock.LastPageElementCount; } else { elementCount = dataBlock.ElementsPerPage; } /* Protect the data block page */ this.Dataset.Context.Reader.Seek(pageAddress, SeekOrigin.Begin); var page = new DataBlockPage <T>( this.Dataset.Context.Reader, elementCount, decode); /* Retrieve element from data block */ return(page.Elements[elementIndex]); } else { /* Call the class's 'fill' callback */ return(null); } } else { /* Retrieve element from data block */ return(dataBlock.Elements[index]); } }
private T?LookupElement <T>(ulong index, Func <H5BinaryReader, T> decode) where T : DataBlockElement { // H5EA.c (H5EA__lookup_elmt) var chunkSizeLength = H5Utils.ComputeChunkSizeLength(this.ChunkByteSize); /* Check if we should create the index block */ if (this.Dataset.Context.Superblock.IsUndefinedAddress(_header.IndexBlockAddress)) { return(null); } /* Protect index block */ if (_indexBlock is null) { this.Dataset.Context.Reader.Seek((long)_header.IndexBlockAddress, SeekOrigin.Begin); _indexBlock = new ExtensibleArrayIndexBlock <T>( this.Dataset.Context.Reader, this.Dataset.Context.Superblock, _header, decode); } var indexBlock = (ExtensibleArrayIndexBlock <T>)_indexBlock; /* Check if element is in index block */ if (index < _header.IndexBlockElementsCount) { return(indexBlock.Elements[index]); } else { /* Get super block index where element is located */ var secondaryBlockIndex = _header.ComputeSecondaryBlockIndex(index); /* Adjust index to offset in super block */ var elementIndex = index - (_header.IndexBlockElementsCount + _header.SecondaryBlockInfos[secondaryBlockIndex].ElementStartIndex); /* Check for data block containing element address in the index block */ if (secondaryBlockIndex < indexBlock.SecondaryBlockDataBlockAddressCount) { /* Compute the data block index in index block */ var dataBlockIndex = _header.SecondaryBlockInfos[secondaryBlockIndex].DataBlockStartIndex + elementIndex / _header.SecondaryBlockInfos[secondaryBlockIndex].ElementsCount; /* Check if the data block has been allocated on disk yet */ if (this.Dataset.Context.Superblock.IsUndefinedAddress(indexBlock.DataBlockAddresses[dataBlockIndex])) { return(null); } /* Protect data block */ this.Dataset.Context.Reader.Seek((long)indexBlock.DataBlockAddresses[dataBlockIndex], SeekOrigin.Begin); var elementsCount = _header.SecondaryBlockInfos[secondaryBlockIndex].ElementsCount; var dataBlock = new ExtensibleArrayDataBlock <T>( this.Dataset.Context.Reader, this.Dataset.Context.Superblock, _header, elementsCount, decode); /* Adjust index to offset in data block */ elementIndex %= _header.SecondaryBlockInfos[secondaryBlockIndex].ElementsCount; /* Set 'thing' info to refer to the data block */ return(dataBlock.Elements[elementIndex]); } else { /* Calculate offset of super block in index block's array */ var secondaryBlockOffset = secondaryBlockIndex - indexBlock.SecondaryBlockDataBlockAddressCount; /* Check if the super block has been allocated on disk yet */ if (this.Dataset.Context.Superblock.IsUndefinedAddress(indexBlock.SecondaryBlockAddresses[secondaryBlockOffset])) { return(null); } /* Protect super block */ this.Dataset.Context.Reader.Seek((long)indexBlock.SecondaryBlockAddresses[secondaryBlockOffset], SeekOrigin.Begin); var secondaryBlock = new ExtensibleArraySecondaryBlock( this.Dataset.Context.Reader, this.Dataset.Context.Superblock, _header, secondaryBlockIndex); /* Compute the data block index in super block */ var dataBlockIndex = elementIndex / secondaryBlock.ElementCount; /* Check if the data block has been allocated on disk yet */ if (this.Dataset.Context.Superblock.IsUndefinedAddress(secondaryBlock.DataBlockAddresses[dataBlockIndex])) { return(null); } /* Adjust index to offset in data block */ elementIndex %= secondaryBlock.ElementCount; /* Check if the data block is paged */ if (secondaryBlock.DataBlockPageCount > 0) { /* Compute page index */ var pageIndex = elementIndex / _header.DataBlockPageElementsCount; /* Compute 'page init' index */ var pageInitIndex = dataBlockIndex * secondaryBlock.DataBlockPageCount + pageIndex; /* Adjust index to offset in data block page */ elementIndex %= _header.DataBlockPageElementsCount; /* Compute data block page address */ var dataBlockPrefixSize = // H5EA_METADATA_PREFIX_SIZE 4UL + 1UL + 1UL + 4UL + // H5EA_DBLOCK_PREFIX_SIZE this.Dataset.Context.Superblock.OffsetsSize + _header.ArrayOffsetsSize + // H5EA_DBLOCK_SIZE secondaryBlock.ElementCount * _header.ElementSize + /* Elements in data block */ secondaryBlock.DataBlockPageCount * 4; /* Checksum for each page */ var dataBlockPageAddress = secondaryBlock.DataBlockAddresses[dataBlockIndex] + dataBlockPrefixSize + (pageIndex * secondaryBlock.DataBlockPageSize); /* Check if page has been initialized yet */ var pageBitmapEntry = secondaryBlock.PageBitmap[pageIndex / 8]; var bitMaskIndex = (int)pageIndex % 8; if ((pageBitmapEntry & H5Utils.SequentialBitMask[bitMaskIndex]) == 0) { return(null); } /* Protect data block page */ this.Dataset.Context.Reader.Seek((long)dataBlockPageAddress, SeekOrigin.Begin); var dataBlockPage = new DataBlockPage <T>( this.Dataset.Context.Reader, _header.DataBlockPageElementsCount, decode); /* Set 'thing' info to refer to the data block page */ return(dataBlockPage.Elements[elementIndex]); } else { /* Protect data block */ this.Dataset.Context.Reader.Seek((long)secondaryBlock.DataBlockAddresses[dataBlockIndex], SeekOrigin.Begin); var dataBlock = new ExtensibleArrayDataBlock <T>( this.Dataset.Context.Reader, this.Dataset.Context.Superblock, _header, secondaryBlock.ElementCount, decode); /* Set 'thing' info to refer to the data block */ return(dataBlock.Elements[elementIndex]); } } } }