public Task<DriverReadResult> ReadAsync(long position, long maxBytes, CancellationToken cancel = new CancellationToken()) { var events = new List<RawEvent>(); if (position >= _file.Length) return Task.FromResult(new DriverReadResult(_file.Length, events)); _file.Seek(position, SeekOrigin.Begin); var readBytes = 0L; using (var r = new BinaryReader(_file, Encoding.UTF8, true)) { var availableBytes = _file.Length - position; while (readBytes < availableBytes) { var evt = EventFormat.Read(r); var newReadBytes = _file.Position - position; if (events.Count == 0 || newReadBytes < maxBytes) { events.Add(evt); readBytes = newReadBytes; } if (newReadBytes >= maxBytes) break; } } return Task.FromResult(new DriverReadResult(position + readBytes, events)); }
internal DriverReadResult Read(long position, long maxBytes) { var events = new List <RawEvent>(); if (position >= _file.Length) { return(new DriverReadResult(_file.Length, events)); } _file.Seek(position, SeekOrigin.Begin); var readBytes = 0L; using (var r = new BinaryReader(_file, Encoding.UTF8, true)) { var availableBytes = _file.Length - position; while (readBytes < availableBytes) { var evt = EventFormat.Read(r); var newReadBytes = _file.Position - position; if (events.Count == 0 || newReadBytes < maxBytes) { events.Add(evt); readBytes = newReadBytes; } if (newReadBytes >= maxBytes) { break; } } } return(new DriverReadResult(position + readBytes, events)); }
public async Task <DriverReadResult> ReadAsync(long position, long maxBytes, CancellationToken cancel = new CancellationToken()) { // STEP 1: PRELIMINARY CHECKS // ========================== // The local cache tells us there is no data available at the provided position, // so start by refreshing the cache. if (_blobs.Count == 0 || position >= _lastKnownPosition) { await RefreshCache(cancel); } // Even with a fresh cache, our position is beyond any available data: // return that there is no more data available. if (_blobs.Count == 0 || position >= _lastKnownPosition) { return(new DriverReadResult(_lastKnownPosition, new RawEvent[0])); } // STEP 2: IDENTIFY BLOB // ===================== CloudAppendBlob blob = null; long firstPosition = 0; long blobSize = 0; for (var i = _blobs.Count - 1; i >= 0; --i) { if (_firstPosition[i] <= position) { blob = _blobs[i]; firstPosition = _firstPosition[i]; blobSize = (i == _blobs.Count - 1 ? _lastKnownPosition : _firstPosition[i + 1]) - firstPosition; break; } } if (blob == null) { // Since _firstPosition[0] == 0, this means the position is negative throw new ArgumentOutOfRangeException("Invalid position:" + position, "position"); } // STEP 3: READ RAW DATA // ===================== var startPos = position - firstPosition; maxBytes = Math.Min(maxBytes, Math.Min(_buffer.Length, blobSize - startPos)); if (maxBytes == 0) { return(new DriverReadResult(_lastKnownPosition, new RawEvent[0])); } var length = await ReadRangeAsync(blob, startPos, maxBytes, cancel); // STEP 4: PARSE DATA // ================== var events = new List <RawEvent>(); var readBytes = 0L; using (var ms = new MemoryStream(_buffer, 0, length)) using (var reader = new BinaryReader(ms)) { while (true) { try { events.Add(EventFormat.Read(reader)); // Only update after finishing a full read ! readBytes = ms.Position; } catch (EndOfStreamException) { break; } catch (InvalidDataException e) { throw new InvalidDataException($"{e.Message} at {position + readBytes}"); } } } return(new DriverReadResult(position + readBytes, events)); }