/// <summary> /// Constructor /// </summary> /// <param name="beginAddress"></param> /// <param name="endAddress"></param> /// <param name="scanBufferingMode"></param> /// <param name="epoch"></param> /// <param name="logPageSizeBits"></param> /// <param name="initForReads"></param> public unsafe ScanIteratorBase(long beginAddress, long endAddress, ScanBufferingMode scanBufferingMode, LightEpoch epoch, int logPageSizeBits, bool initForReads = true) { // If we are protected when creating the iterator, we do not need per-GetNext protection if (epoch != null && !epoch.ThisInstanceProtected()) { this.epoch = epoch; } this.beginAddress = beginAddress; this.endAddress = endAddress; this.logPageSizeBits = logPageSizeBits; currentAddress = -1; nextAddress = beginAddress; if (scanBufferingMode == ScanBufferingMode.SinglePageBuffering) { frameSize = 1; } else if (scanBufferingMode == ScanBufferingMode.DoublePageBuffering) { frameSize = 2; } else if (scanBufferingMode == ScanBufferingMode.NoBuffering) { frameSize = 0; return; } if (initForReads) { InitializeForReads(); } }
/// <summary> /// Constructor /// </summary> /// <param name="beginAddress"></param> /// <param name="endAddress"></param> /// <param name="scanBufferingMode"></param> /// <param name="epoch"></param> /// <param name="logPageSizeBits"></param> public unsafe ScanIteratorBase(long beginAddress, long endAddress, ScanBufferingMode scanBufferingMode, LightEpoch epoch, int logPageSizeBits) { // If we are protected when creating the iterator, we do not need per-GetNext protection if (!epoch.ThisInstanceProtected()) { this.epoch = epoch; } this.beginAddress = beginAddress; this.endAddress = endAddress; this.logPageSizeBits = logPageSizeBits; currentAddress = -1; nextAddress = beginAddress; if (scanBufferingMode == ScanBufferingMode.SinglePageBuffering) { frameSize = 1; } else if (scanBufferingMode == ScanBufferingMode.DoublePageBuffering) { frameSize = 2; } else if (scanBufferingMode == ScanBufferingMode.NoBuffering) { frameSize = 0; return; } loaded = new CountdownEvent[frameSize]; loadedCancel = new CancellationTokenSource[frameSize]; loadedPage = new long[frameSize]; nextLoadedPage = new long[frameSize]; for (int i = 0; i < frameSize; i++) { loadedPage[i] = -1; nextLoadedPage[i] = -1; loadedCancel[i] = new CancellationTokenSource(); } }
/// <summary> /// Constructor /// </summary> /// <param name="fasterLog"></param> /// <param name="hlog"></param> /// <param name="beginAddress"></param> /// <param name="endAddress"></param> /// <param name="scanBufferingMode"></param> /// <param name="epoch"></param> /// <param name="headerSize"></param> /// <param name="name"></param> /// <param name="getMemory"></param> internal unsafe FasterLogScanIterator(FasterLog fasterLog, BlittableAllocator <Empty, byte> hlog, long beginAddress, long endAddress, GetMemory getMemory, ScanBufferingMode scanBufferingMode, LightEpoch epoch, int headerSize, string name) { this.fasterLog = fasterLog; this.allocator = hlog; this.getMemory = getMemory; this.epoch = epoch; this.headerSize = headerSize; if (beginAddress == 0) { beginAddress = hlog.GetFirstValidLogicalAddress(0); } this.name = name; this.endAddress = endAddress; NextAddress = CompletedUntilAddress = beginAddress; if (scanBufferingMode == ScanBufferingMode.SinglePageBuffering) { frameSize = 1; } else if (scanBufferingMode == ScanBufferingMode.DoublePageBuffering) { frameSize = 2; } else if (scanBufferingMode == ScanBufferingMode.NoBuffering) { frameSize = 0; return; } frame = new BlittableFrame(frameSize, hlog.PageSize, hlog.GetDeviceSectorSize()); loaded = new CountdownEvent[frameSize]; loadedCancel = new CancellationTokenSource[frameSize]; loadedPage = new long[frameSize]; nextLoadedPage = new long[frameSize]; for (int i = 0; i < frameSize; i++) { loadedPage[i] = -1; nextLoadedPage[i] = -1; loadedCancel[i] = new CancellationTokenSource(); } }
/// <summary> /// Constructor /// </summary> /// <param name="hlog"></param> /// <param name="beginAddress"></param> /// <param name="endAddress"></param> /// <param name="scanBufferingMode"></param> public unsafe BlittableScanIterator(BlittableAllocator <Key, Value> hlog, long beginAddress, long endAddress, ScanBufferingMode scanBufferingMode) { this.hlog = hlog; if (beginAddress == 0) { beginAddress = hlog.GetFirstValidLogicalAddress(0); } this.beginAddress = beginAddress; this.endAddress = endAddress; currentAddress = -1; nextAddress = beginAddress; if (scanBufferingMode == ScanBufferingMode.SinglePageBuffering) { frameSize = 1; } else if (scanBufferingMode == ScanBufferingMode.DoublePageBuffering) { frameSize = 2; } else if (scanBufferingMode == ScanBufferingMode.NoBuffering) { frameSize = 0; return; } frame = new BlittableFrame(frameSize, hlog.PageSize, hlog.GetDeviceSectorSize()); loaded = new CountdownEvent[frameSize]; // Only load addresses flushed to disk if (nextAddress < hlog.HeadAddress) { var frameNumber = (nextAddress >> hlog.LogPageSizeBits) % frameSize; hlog.AsyncReadPagesFromDeviceToFrame (nextAddress >> hlog.LogPageSizeBits, 1, endAddress, AsyncReadPagesCallback, Empty.Default, frame, out loaded[frameNumber]); } }
/// <summary> /// Constructor /// </summary> /// <param name="hlog"></param> /// <param name="beginAddress"></param> /// <param name="endAddress"></param> /// <param name="scanBufferingMode"></param> /// <param name="epoch"></param> /// <param name="forceInMemory">Provided address range is known by caller to be in memory, even if less than HeadAddress</param> public VariableLengthBlittableScanIterator(VariableLengthBlittableAllocator <Key, Value> hlog, long beginAddress, long endAddress, ScanBufferingMode scanBufferingMode, LightEpoch epoch, bool forceInMemory = false) : base(beginAddress == 0 ? hlog.GetFirstValidLogicalAddress(0) : beginAddress, endAddress, scanBufferingMode, epoch, hlog.LogPageSizeBits) { this.hlog = hlog; this.forceInMemory = forceInMemory; if (frameSize > 0) { frame = new BlittableFrame(frameSize, hlog.PageSize, hlog.GetDeviceSectorSize()); } }
/// <summary> /// Scan the log underlying FASTER, for address range /// </summary> /// <param name="beginAddress"></param> /// <param name="endAddress"></param> /// <param name="scanBufferingMode"></param> /// <returns></returns> public IFasterScanIterator <Key, Value> LogScan(long beginAddress, long endAddress, ScanBufferingMode scanBufferingMode = ScanBufferingMode.DoublePageBuffering) { return(hlog.Scan(beginAddress, endAddress, scanBufferingMode)); }
/// <summary> /// Pull-based iterator interface for scanning FASTER log /// </summary> /// <param name="beginAddress">Begin address for scan.</param> /// <param name="endAddress">End address for scan (or long.MaxValue for tailing).</param> /// <param name="name">Name of iterator, if we need to persist/recover it (default null - do not persist).</param> /// <param name="recover">Whether to recover named iterator from latest commit (if exists). If false, iterator starts from beginAddress.</param> /// <param name="scanBufferingMode">Use single or double buffering</param> /// <param name="scanUncommitted">Whether we scan uncommitted data</param> /// <returns></returns> public FasterLogScanIterator Scan(long beginAddress, long endAddress, string name = null, bool recover = true, ScanBufferingMode scanBufferingMode = ScanBufferingMode.DoublePageBuffering, bool scanUncommitted = false) { FasterLogScanIterator iter; if (recover && name != null && RecoveredIterators != null && RecoveredIterators.ContainsKey(name)) { iter = new FasterLogScanIterator(this, allocator, RecoveredIterators[name], endAddress, getMemory, scanBufferingMode, epoch, headerSize, name, scanUncommitted); } else { iter = new FasterLogScanIterator(this, allocator, beginAddress, endAddress, getMemory, scanBufferingMode, epoch, headerSize, name, scanUncommitted); } if (name != null) { if (name.Length > 20) { throw new FasterException("Max length of iterator name is 20 characters"); } if (PersistedIterators.ContainsKey(name)) { Debug.WriteLine("Iterator name exists, overwriting"); } PersistedIterators[name] = iter; } if (Interlocked.Increment(ref logRefCount) == 1) { throw new FasterException("Cannot scan disposed log instance"); } return(iter); }
/// <summary> /// Pull-based iterator interface for scanning FASTER log /// </summary> /// <param name="beginAddress">Begin address for scan.</param> /// <param name="endAddress">End address for scan (or long.MaxValue for tailing).</param> /// <param name="name">Name of iterator, if we need to persist/recover it (default null - do not persist).</param> /// <param name="recover">Whether to recover named iterator from latest commit (if exists). If false, iterator starts from beginAddress.</param> /// <param name="scanBufferingMode">Use single or double buffering</param> /// <returns></returns> public FasterLogScanIterator Scan(long beginAddress, long endAddress, string name = null, bool recover = true, ScanBufferingMode scanBufferingMode = ScanBufferingMode.DoublePageBuffering) { FasterLogScanIterator iter; if (recover && name != null && RecoveredIterators != null && RecoveredIterators.ContainsKey(name)) { iter = new FasterLogScanIterator(this, allocator, RecoveredIterators[name], endAddress, getMemory, scanBufferingMode, epoch, headerSize, name); } else { iter = new FasterLogScanIterator(this, allocator, beginAddress, endAddress, getMemory, scanBufferingMode, epoch, headerSize, name); } if (name != null) { if (name.Length > 20) { throw new Exception("Max length of iterator name is 20 characters"); } if (FasterLogScanIterator.PersistedIterators.ContainsKey(name)) { Debug.WriteLine("Iterator name exists, overwriting"); } FasterLogScanIterator.PersistedIterators[name] = iter; } return(iter); }
/// <summary> /// Iterator interface for scanning FASTER log /// </summary> /// <param name="beginAddress"></param> /// <param name="endAddress"></param> /// <param name="scanBufferingMode"></param> /// <returns></returns> public override IFasterScanIterator <Key, Value> Scan(long beginAddress, long endAddress, ScanBufferingMode scanBufferingMode) { return(new BlittableScanIterator <Key, Value>(this, beginAddress, endAddress, scanBufferingMode)); }
/// <summary> /// Iterator interface for scanning FASTER log /// </summary> /// <param name="beginAddress"></param> /// <param name="endAddress"></param> /// <param name="scanBufferingMode"></param> /// <returns></returns> public override IFasterScanIterator <Key, Value> Scan(long beginAddress, long endAddress, ScanBufferingMode scanBufferingMode) { throw new NotImplementedException(); }
/// <summary> /// Constructor /// </summary> /// <param name="fasterLog"></param> /// <param name="hlog"></param> /// <param name="beginAddress"></param> /// <param name="endAddress"></param> /// <param name="scanBufferingMode"></param> /// <param name="epoch"></param> /// <param name="headerSize"></param> /// <param name="name"></param> /// <param name="getMemory"></param> /// <param name="scanUncommitted"></param> internal unsafe FasterLogScanIterator(FasterLog fasterLog, BlittableAllocator <Empty, byte> hlog, long beginAddress, long endAddress, GetMemory getMemory, ScanBufferingMode scanBufferingMode, LightEpoch epoch, int headerSize, string name, bool scanUncommitted = false) : base(beginAddress == 0 ? hlog.GetFirstValidLogicalAddress(0) : beginAddress, endAddress, scanBufferingMode, epoch, hlog.LogPageSizeBits) { this.fasterLog = fasterLog; this.allocator = hlog; this.getMemory = getMemory; this.headerSize = headerSize; this.scanUncommitted = scanUncommitted; this.name = name; CompletedUntilAddress = beginAddress; if (frameSize > 0) { frame = new BlittableFrame(frameSize, hlog.PageSize, hlog.GetDeviceSectorSize()); } }
/// <summary> /// Constructor /// </summary> /// <param name="hlog"></param> /// <param name="beginAddress"></param> /// <param name="endAddress"></param> /// <param name="scanBufferingMode"></param> /// <param name="epoch"></param> public GenericScanIterator(GenericAllocator <Key, Value> hlog, long beginAddress, long endAddress, ScanBufferingMode scanBufferingMode, LightEpoch epoch) : base(beginAddress == 0 ? hlog.GetFirstValidLogicalAddress(0) : beginAddress, endAddress, scanBufferingMode, epoch, hlog.LogPageSizeBits) { this.hlog = hlog; recordSize = hlog.GetRecordSize(0).Item2; if (frameSize > 0) { frame = new GenericFrame <Key, Value>(frameSize, hlog.PageSize); } }
/// <summary> /// Constructor /// </summary> /// <param name="hlog"></param> /// <param name="beginAddress"></param> /// <param name="endAddress"></param> /// <param name="scanBufferingMode"></param> public unsafe BlittableScanIterator(BlittableAllocator <Key, Value> hlog, long beginAddress, long endAddress, ScanBufferingMode scanBufferingMode) { this.hlog = hlog; this.beginAddress = beginAddress; this.endAddress = endAddress; currentAddress = beginAddress; if (scanBufferingMode == ScanBufferingMode.SinglePageBuffering) { frameSize = 1; } else { frameSize = 2; } frame = new BlittableFrame(frameSize, hlog.PageSize, hlog.GetDeviceSectorSize()); loaded = new CountdownEvent[frameSize]; var frameNumber = (currentAddress >> hlog.LogPageSizeBits) % frameSize; hlog.AsyncReadPagesFromDeviceToFrame (currentAddress >> hlog.LogPageSizeBits, 1, AsyncReadPagesCallback, Empty.Default, frame, out loaded[frameNumber]); }
/// <summary> /// Constructor /// </summary> /// <param name="hlog"></param> /// <param name="beginAddress"></param> /// <param name="endAddress"></param> /// <param name="scanBufferingMode"></param> public GenericScanIterator(GenericAllocator <Key, Value> hlog, long beginAddress, long endAddress, ScanBufferingMode scanBufferingMode) { this.hlog = hlog; this.beginAddress = beginAddress; this.endAddress = endAddress; currentAddress = beginAddress; if (scanBufferingMode == ScanBufferingMode.SinglePageBuffering) { frameSize = 1; } else { frameSize = 2; } frame = new Record <Key, Value> [frameSize][]; loaded = new CountdownEvent[frameSize]; var frameNumber = (currentAddress >> hlog.LogPageSizeBits) % frameSize; hlog.AsyncReadPagesFromDeviceToFrame (currentAddress >> hlog.LogPageSizeBits, 1, AsyncReadPagesCallback, Empty.Default, frame, frameSize, out loaded[frameNumber]); }
/// <summary> /// Constructor /// </summary> /// <param name="hlog"></param> /// <param name="beginAddress"></param> /// <param name="endAddress"></param> /// <param name="scanBufferingMode"></param> /// <param name="epoch"></param> public unsafe BlittableScanIterator(BlittableAllocator <Key, Value> hlog, long beginAddress, long endAddress, ScanBufferingMode scanBufferingMode, LightEpoch epoch) { this.hlog = hlog; // If we are protected when creating the iterator, we do not need per-GetNext protection if (!epoch.ThisInstanceProtected()) { this.epoch = epoch; } if (beginAddress == 0) { beginAddress = hlog.GetFirstValidLogicalAddress(0); } this.endAddress = endAddress; currentAddress = -1; nextAddress = beginAddress; if (scanBufferingMode == ScanBufferingMode.SinglePageBuffering) { frameSize = 1; } else if (scanBufferingMode == ScanBufferingMode.DoublePageBuffering) { frameSize = 2; } else if (scanBufferingMode == ScanBufferingMode.NoBuffering) { frameSize = 0; return; } frame = new BlittableFrame(frameSize, hlog.PageSize, hlog.GetDeviceSectorSize()); loaded = new CountdownEvent[frameSize]; // Only load addresses flushed to disk if (nextAddress < hlog.HeadAddress) { var frameNumber = (nextAddress >> hlog.LogPageSizeBits) % frameSize; hlog.AsyncReadPagesFromDeviceToFrame (nextAddress >> hlog.LogPageSizeBits, 1, endAddress, AsyncReadPagesCallback, Empty.Default, frame, out loaded[frameNumber]); } }