public async Task <CopyResult> CopyNextBatch(CancellationToken token) { var maxPos = await SourcePos .ReadAsync(token) .ConfigureAwait(false); var localPos = TargetPos.ReadPositionVolatile(); var availableAmount = maxPos - localPos; if (availableAmount <= 0) { // we don't have anything to write return(new CopyResult(0, maxPos, localPos, localPos)); } var amountToLoad = Math.Min(availableAmount, AmountToLoadMax); using (var mem = _streamManager.GetStream("fetcher")) { await _sourceReader.DownloadRangeToStreamAsync(mem, localPos, (int)amountToLoad) .ConfigureAwait(false); mem.Seek(0, SeekOrigin.Begin); _targetWriter.Save(mem, localPos); var position = localPos + mem.Length; TargetPos.Update(position); return(new CopyResult(mem.Length, maxPos, localPos, position)); } }
void FlushBuffer() { var bytesToWrite = _stream.Position; //Log.Verbose("Flush Buffer {3}-[{0} ({2}) {1}]-{4}", // DataStarts(), // DataEnds(), // DataEnds() - DataStarts(), // BufferStarts(), // BufferEnds()); var newPosition = VirtualPosition(); _pages.EnsureSize(Ceiling(newPosition)); var fullBytesToWrite = (int)Ceiling(_stream.Position); using (var copy = new MemoryStream(_buffer, 0, fullBytesToWrite)) { _pages.Save(copy, Floor(_position)); } _position = newPosition; if (bytesToWrite < _pageSize) { return; } var tail = Tail(bytesToWrite); if (tail == 0) { Array.Clear(_buffer, 0, _buffer.Length); _stream.Seek(0, SeekOrigin.Begin); } else { Array.Copy(_buffer, Floor(bytesToWrite), _buffer, 0, _pageSize); Array.Clear(_buffer, _pageSize, _buffer.Length - _pageSize); _stream.Seek(tail, SeekOrigin.Begin); } }