static void ScanThread() { byte[] result; while (true) { while (!iter.GetNext(out result, out _, out _)) { // For finite end address, check if iteration ended // if (currentAddress >= endAddress) return; iter.WaitAsync().GetAwaiter().GetResult(); } // Memory pool variant: // iter.GetNext(pool, out IMemoryOwner<byte> resultMem, out int length, out long currentAddress) if (Different(result, staticEntry)) { throw new Exception("Invalid entry found"); } // Example of random read from given address // (result, _) = log.ReadAsync(iter.CurrentAddress).GetAwaiter().GetResult(); // Truncate until start of most recently read page log.TruncateUntilPageStart(iter.NextAddress); // Truncate log until after most recently read entry // log.TruncateUntil(iter.NextAddress); } // Example of recoverable (named) iterator: // using (iter = log.Scan(log.BeginAddress, long.MaxValue, "foo")) }
public async Task <List <(string, long, long)> > GetList() { var result = new List <(string, long, long)>(); using (FasterLogScanIterator iter = logger.Scan(nextAddress, 100_000_000)) { int i = 0; byte[] entry; int length; while (iter.GetNext(out entry, out length)) { UTF8Encoding encoding = new UTF8Encoding(); if (iter.CurrentAddress >= 1568) { Debugger.Break(); } await iter.WaitAsync(); result.Add((encoding.GetString(entry), iter.CurrentAddress, iter.NextAddress)); i++; if (i > 50) { nextAddress = iter.NextAddress; break; } } } return(result); }
async IAsyncEnumerable <PartitionUpdateEvent> EventsToReplay(long from) { long to = this.log.TailAddress; using (FasterLogScanIterator iter = this.log.Scan(from, to)) { byte[] result; int entryLength; long currentAddress; MemoryStream reassembly = null; while (!this.cancellationToken.IsCancellationRequested) { PartitionUpdateEvent partitionEvent = null; while (!iter.GetNext(out result, out entryLength, out currentAddress)) { if (currentAddress >= to) { yield break; } await iter.WaitAsync(this.cancellationToken).ConfigureAwait(false); } if ((result[0] & first) != none) { if ((result[0] & last) != none) { partitionEvent = (PartitionUpdateEvent)Serializer.DeserializeEvent(new ArraySegment <byte>(result, 1, entryLength - 1)); } else { reassembly = new MemoryStream(); reassembly.Write(result, 1, entryLength - 1); } } else { reassembly.Write(result, 1, entryLength - 1); if ((result[0] & last) != none) { reassembly.Position = 0; partitionEvent = (PartitionUpdateEvent)Serializer.DeserializeEvent(reassembly); reassembly = null; } } if (partitionEvent != null) { partitionEvent.NextCommitLogPosition = iter.NextAddress; yield return(partitionEvent); } } } }
public async Task <Option <(string, long, long)> > GetNext() { using FasterLogScanIterator iter = logger.Scan(nextAddress, 100_000_000); while (true) { byte[] entry; int length; while (!iter.GetNext(out entry, out length)) { if (iter.CurrentAddress >= 100_000_000) { return(Option.None <(string, long, long)>()); } } UTF8Encoding encoding = new UTF8Encoding(); await iter.WaitAsync(); nextAddress = iter.NextAddress; return(Option.Some((encoding.GetString(entry), iter.CurrentAddress, iter.NextAddress))); // Possible to pipe } }