private static BlobIdentifier ComputeIdentifierBasedOnBlocks(IEnumerable <BlobBlockHash> blocks) { var rollingId = new VsoHash.RollingBlobIdentifier(); // ReSharper disable once GenericEnumeratorNotDisposed IEnumerator <BlobBlockHash> enumerator = blocks.GetEnumerator(); bool isLast = !enumerator.MoveNext(); if (isLast) { throw new InvalidDataException("Blob must have at least one block."); } BlobBlockHash current = enumerator.Current; isLast = !enumerator.MoveNext(); while (!isLast) { rollingId.Update(current); current = enumerator.Current; isLast = !enumerator.MoveNext(); } return(rollingId.Finalize(current)); }
public BlobIdentifierWithBlocks Finalize(BlobBlockHash currentBlockIdentifier) { _blockHashes.Add(currentBlockIdentifier); var blobId = _inner.Finalize(currentBlockIdentifier); return(new BlobIdentifierWithBlocks(blobId, _blockHashes)); }
private static async Task ReadBlockAsync( Stream stream, SemaphoreSlim?blockActionSemaphore, long bytesLeftInBlob, BlockReadCompleteAsync readCallback) { if (blockActionSemaphore != null) { await blockActionSemaphore.WaitAsync().ConfigureAwait(false); } bool disposeNeeded = true; try { Pool <byte[]> .PoolHandle blockBufferHandle = GlobalObjectPools.TwoMbByteArrayPool.Get(); try { byte[] blockBuffer = blockBufferHandle.Value; int bytesToRead = (int)Math.Min(BlockSize, bytesLeftInBlob); int bufferOffset = 0; while (bytesToRead > 0) { int bytesRead = await stream.ReadAsync(blockBuffer, bufferOffset, bytesToRead).ConfigureAwait(false); bytesToRead -= bytesRead; bufferOffset += bytesRead; if (bytesRead == 0) { // ReadAsync returns 0 when the stream has ended. if (bytesToRead > 0) { throw new EndOfStreamException(); } } } BlobBlockHash blockHash = HashBlock(blockBuffer, bufferOffset); disposeNeeded = false; // readCallback is now responsible for disposing the blockBufferHandle await readCallback(blockBufferHandle, bufferOffset, blockHash).ConfigureAwait(false); } finally { if (disposeNeeded) { blockBufferHandle.Dispose(); } } } finally { if (disposeNeeded) { blockActionSemaphore?.Release(); } } }
public BlobIdentifier Finalize(BlobBlockHash currentBlockIdentifier) { // TODO:if we want to enforce this we should implement BlobBlockHash.BlockSize (bug 1365340) // // if (blockSize > BlockSize) // { // throw new InvalidOperationException("Blocks cannot be bigger than BlockSize."); // } UpdateInternal(currentBlockIdentifier, true); return(new BlobIdentifier(_rollingId, VsoAlgorithmId)); }
public void Update(BlobBlockHash currentBlockIdentifier) { // TODO:if we want to enforce this we should implement BlobBlockHash.BlockSize (bug 1365340) // // var currentBlockSize = currentBlockIdentifier.BlockSize; // if (currentBlockSize != BlockSize) // { // throw new InvalidOperationException($"Non-final blocks must be of size {BlockSize}; but the given block has size {currentBlockSize}"); // } UpdateInternal(currentBlockIdentifier, false); }
private static void ReadBlock(Stream stream, SemaphoreSlim?blockActionSemaphore, long bytesLeftInBlob, BlockReadComplete readCallback) { blockActionSemaphore?.Wait(); bool disposeNeeded = true; try { Pool <byte[]> .PoolHandle blockBufferHandle = GlobalObjectPools.TwoMbByteArrayPool.Get(); try { byte[] blockBuffer = blockBufferHandle.Value; int bytesToRead = (int)Math.Min(BlockSize, bytesLeftInBlob); int bufferOffset = 0; while (bytesToRead > 0) { int bytesRead = stream.Read(blockBuffer, bufferOffset, bytesToRead); bytesToRead -= bytesRead; bufferOffset += bytesRead; if (bytesRead == 0) { // ReadAsync returns 0 when the stream has ended. if (bytesToRead > 0) { throw new EndOfStreamException(); } } } BlobBlockHash blockHash = HashBlock(blockBuffer, bufferOffset); disposeNeeded = false; readCallback(blockBufferHandle, bufferOffset, blockHash); } finally { if (disposeNeeded) { blockBufferHandle.Dispose(); } } } finally { if (disposeNeeded) { blockActionSemaphore?.Release(); } } }
private void UpdateInternal(BlobBlockHash currentBlockIdentifier, bool isFinalBlock) { if (_finalAdded && isFinalBlock) { throw new InvalidOperationException("Final block already added."); } int combinedBufferLength = _rollingId.Length + currentBlockIdentifier.HashBytes.Length + 1; var combinedBuffer = new byte[combinedBufferLength]; Array.Copy(_rollingId, combinedBuffer, _rollingId.Length); Array.Copy(currentBlockIdentifier.HashBytes, 0, combinedBuffer, _rollingId.Length, currentBlockIdentifier.HashBytes.Length); combinedBuffer[combinedBufferLength - 1] = Convert.ToByte(isFinalBlock); _rollingId = ComputeSHA256Hash(combinedBuffer); if (isFinalBlock) { _finalAdded = true; } }
public void Update(BlobBlockHash currentBlockIdentifier) { _blockHashes.Add(currentBlockIdentifier); _inner.Update(currentBlockIdentifier); }