/// <summary> /// Creates block and reads its contents from index file /// </summary> /// <param name="offset">Offset of block in index file</param> /// <param name="length">Length of block in index file</param> /// <returns>New block instance</returns> /// <exception cref="IOException">not enough data in index file to fill the block</exception> public static T Read <T>(this IIndexFileBlockProvider blockProvider, long offset, int length) where T : ISerializableIndexData, new() { var result = new T(); blockProvider.Read(result, offset, length); return(result); }
/// <summary> /// Adds metadata of written stream to index file /// </summary> /// <param name="streamMetadata">stream metadata to be added to index</param> /// <exception cref="System.ArgumentException">An element with the same key already exists</exception> public void Set(StreamMetadata streamMetadata) { streamMetadata.ThrowIfNull(nameof(streamMetadata)); var key = streamMetadata.Key; if (Contains(key)) { throw new ArgumentException(nameof(key)); } var blockInfo = header.Get(key); var block = new IndexBlock(); var oldLength = 0; if (blockInfo.Offset > 0) { if (blockInfo.Length + streamMetadata.SerializedLength < MaxIndexBlockLength) { blockProvider.Read(block, blockInfo.Offset, blockInfo.Length); oldLength = blockInfo.Length; } else { block = new IndexBlock(blockInfo); } } block.Add(streamMetadata); var offset = blockProvider.Write(block); var length = block.SerializedLength; blockInfo = new BlockInfo() { Offset = offset, Length = length }; header.Set(key, blockInfo); header.IndexWrittenLength += length - oldLength; header.StorageWrittenLength += streamMetadata.Length; }
/// <summary> /// Initializes new instance of <see cref="StorageFileReader"/> class. /// </summary> /// <param name="streamFactory"><see cref="IStreamFactory"/> object used to create file streams</param> /// <exception cref="ArgumentNullException">factory is null</exception> public BinaryStorageIndex(IIndexFileBlockProvider blockProvider) { this.blockProvider = blockProvider.ThrowIfNull(nameof(blockProvider)); if (blockProvider.Length == 0) { header = new IndexHeader(); blockProvider.Write(header, 0); } else { header = blockProvider.Read <IndexHeader>(0, IndexHeader.FullHeaderSize); } }