示例#1
0
            /// <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;
                        }
                    }
                }
            }
示例#2
0
 private static void CleanupBufferAndSemaphore(
     Pool <byte[]> .PoolHandle blockBufferHandle,
     SemaphoreSlim?blockActionSemaphore)
 {
     blockBufferHandle.Dispose();
     blockActionSemaphore?.Release();
 }
示例#3
0
 void IHashAlgorithmWithCleanup.Cleanup()
 {
     if (_buffer is not null)
     {
         _buffer = null;
         _bufferHandle.Dispose();
     }
 }
示例#4
0
        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();
                }
            }
        }
示例#5
0
        /// <inheritdoc />
        public void Dispose()
        {
            if (Hasher is IHashAlgorithmWithCleanup cleanUp)
            {
                cleanUp.Cleanup();
            }

            _poolHandle.Dispose();
        }
示例#6
0
            /// <inheritdoc/>
            public void Dispose()
            {
                if (_bytesInPushBuffer > 0)
                {
                    _regressionChunker.PushBuffer(new ArraySegment <byte>(_pushBuffer.Value, 0, _bytesInPushBuffer));
                }


                _regressionChunker.Complete();

                _lastPushBuffer?.Dispose();
                _pushBuffer.Dispose();
            }
示例#7
0
        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 !;
                }
            }
示例#9
0
 /// <inheritdoc />
 public void Dispose()
 {
     Hasher.Initialize();
     _poolHandle.Dispose();
 }