/// <summary> /// Chunks the buffer, calling back when chunks complete. /// </summary> public void PushBuffer(byte[] buffer, int startOffset, int count) { checked { while (count > 0) { while (count > 0 && _bytesInPushBuffer < MinPushBufferSize) { _pushBuffer.Value[_bytesInPushBuffer] = buffer[startOffset]; startOffset++; _bytesInPushBuffer++; count--; } if (_bytesInPushBuffer == MinPushBufferSize) { _regressionChunker.PushBuffer(new ArraySegment <byte>(_pushBuffer.Value)); _lastBufferFileOffset = _bufferFileOffset; _lastPushBuffer?.Dispose(); _lastPushBuffer = _pushBuffer; _bufferFileOffset += MinPushBufferSize; _pushBuffer = pool.Get(); _bytesInPushBuffer = 0; } } } }
private static void CleanupBufferAndSemaphore( Pool <byte[]> .PoolHandle blockBufferHandle, SemaphoreSlim?blockActionSemaphore) { blockBufferHandle.Dispose(); blockActionSemaphore?.Release(); }
void IHashAlgorithmWithCleanup.Cleanup() { if (_buffer is not null) { _buffer = null; _bufferHandle.Dispose(); } }
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(); } } }
/// <inheritdoc /> public void Dispose() { if (Hasher is IHashAlgorithmWithCleanup cleanUp) { cleanUp.Cleanup(); } _poolHandle.Dispose(); }
/// <inheritdoc/> public void Dispose() { if (_bytesInPushBuffer > 0) { _regressionChunker.PushBuffer(new ArraySegment <byte>(_pushBuffer.Value, 0, _bytesInPushBuffer)); } _regressionChunker.Complete(); _lastPushBuffer?.Dispose(); _pushBuffer.Dispose(); }
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(); } } }
public void Dispose() { if (_bytesInPushBuffer != 0) { using (var inner = _parent._chunker.BeginChunking(FoundChunk)) { inner.PushBuffer(_pushBuffer, 0, _bytesInPushBuffer); } ReportChunks(); } if (_pushBuffer != null) { _pushBufferHandle.Dispose(); _pushBuffer = null !; } if (_chunksSeen != null) { _chunksSeenHandle.Dispose(); _chunksSeen = null !; } }
/// <inheritdoc /> public void Dispose() { Hasher.Initialize(); _poolHandle.Dispose(); }