/// <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> /// Wait for ongoing checkpoint to complete /// </summary> /// <returns></returns> public async ValueTask CompleteCheckpointAsync(CancellationToken token = default) { if (LightEpoch.AnyInstanceProtected()) { throw new FasterException("Cannot use CompleteCheckpointAsync when using legacy or non-async sessions"); } token.ThrowIfCancellationRequested(); while (true) { var systemState = _systemState; if (systemState.phase == Phase.REST || systemState.phase == Phase.PREPARE_GROW || systemState.phase == Phase.IN_PROGRESS_GROW) { return; } await HandleCheckpointingPhasesAsync(null, null); } }
/// <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> /// Initialize device /// </summary> /// <param name="segmentSize"></param> /// <param name="epoch"></param> public virtual void Initialize(long segmentSize, LightEpoch epoch = null) { // TODO(Tianyu): Alternatively, we can adjust capacity based on the segment size: given a phsyical upper limit of capacity, // we only make use of (Capacity / segmentSize * segmentSize) many bytes. Debug.Assert(Capacity == -1 || Capacity % segmentSize == 0, "capacity must be a multiple of segment sizes"); this.segmentSize = segmentSize; this.epoch = epoch; if (!Utility.IsPowerOfTwo(segmentSize)) { if (segmentSize != -1) { throw new Exception("Invalid segment size: " + segmentSize); } segmentSizeBits = 64; segmentSizeMask = ~0UL; } else { segmentSizeBits = Utility.GetLogBase2((ulong)segmentSize); segmentSizeMask = (ulong)segmentSize - 1; } }
/// <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> /// <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]); } }
/// <summary> /// Creates a new SimpleVersionScheme /// </summary> public SimpleVersionScheme() { epoch = new LightEpoch(); }