private unsafe void BufferAndLoad(long currentAddress, long currentPage, long currentFrame) { if (loadedPage[currentFrame] != currentPage) { if (loadedPage[currentFrame] != -1) { WaitForFrameLoad(currentFrame); } allocator.AsyncReadPagesFromDeviceToFrame(currentAddress >> allocator.LogPageSizeBits, 1, endAddress, AsyncReadPagesCallback, Empty.Default, frame, out loaded[currentFrame], 0, null, null, loadedCancel[currentFrame]); loadedPage[currentFrame] = currentAddress >> allocator.LogPageSizeBits; } if (frameSize == 2) { var nextPage = currentPage + 1; var nextFrame = (currentFrame + 1) % frameSize; if (loadedPage[nextFrame] != nextPage) { if (loadedPage[nextFrame] != -1) { WaitForFrameLoad(nextFrame); } allocator.AsyncReadPagesFromDeviceToFrame(1 + (currentAddress >> allocator.LogPageSizeBits), 1, endAddress, AsyncReadPagesCallback, Empty.Default, frame, out loaded[nextFrame], 0, null, null, loadedCancel[nextFrame]); loadedPage[nextFrame] = 1 + (currentAddress >> allocator.LogPageSizeBits); } } WaitForFrameLoad(currentFrame); }
private unsafe void BufferAndLoad(long currentAddress, long currentPage, long currentFrame) { if (first || (currentAddress & hlog.PageSizeMask) == 0) { // Prefetch pages based on buffering mode if (frameSize == 1) { if (!first) { hlog.AsyncReadPagesFromDeviceToFrame(currentAddress >> hlog.LogPageSizeBits, 1, endAddress, AsyncReadPagesCallback, Empty.Default, frame, out loaded[currentFrame]); } } else { var endPage = endAddress >> hlog.LogPageSizeBits; if ((endPage > currentPage) && ((endPage > currentPage + 1) || ((endAddress & hlog.PageSizeMask) != 0))) { hlog.AsyncReadPagesFromDeviceToFrame(1 + (currentAddress >> hlog.LogPageSizeBits), 1, endAddress, AsyncReadPagesCallback, Empty.Default, frame, out loaded[(currentPage + 1) % frameSize]); } } first = false; } loaded[currentFrame].Wait(); }
private unsafe bool BufferAndLoad(long currentAddress, long currentPage, long currentFrame, long headAddress) { for (int i = 0; i < frameSize; i++) { var nextPage = currentPage + i; // Cannot load page if its not fully written to storage if (headAddress < (nextPage + 1) << allocator.LogPageSizeBits) { continue; } var nextFrame = (currentFrame + i) % frameSize; long val; while ((val = nextLoadedPage[nextFrame]) < nextPage || loadedPage[nextFrame] < nextPage) { if (val < nextPage && Interlocked.CompareExchange(ref nextLoadedPage[nextFrame], nextPage, val) == val) { var tmp_i = i; epoch.BumpCurrentEpoch(() => { allocator.AsyncReadPagesFromDeviceToFrame(tmp_i + (currentAddress >> allocator.LogPageSizeBits), 1, endAddress, AsyncReadPagesCallback, Empty.Default, frame, out loaded[nextFrame], 0, null, null, loadedCancel[nextFrame]); loadedPage[nextFrame] = nextPage; }); } else { epoch.ProtectAndDrain(); } } } return(WaitForFrameLoad(currentAddress, currentFrame)); }
/// <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> /// <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 unsafe BlittableScanIterator(BlittableAllocator <Key, Value> hlog, long beginAddress, long endAddress, ScanBufferingMode scanBufferingMode, LightEpoch epoch, bool forceInMemory = false) { this.hlog = hlog; this.forceInMemory = forceInMemory; // 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 && !forceInMemory) { var frameNumber = (nextAddress >> hlog.LogPageSizeBits) % frameSize; hlog.AsyncReadPagesFromDeviceToFrame (nextAddress >> hlog.LogPageSizeBits, 1, endAddress, AsyncReadPagesCallback, Empty.Default, frame, out loaded[frameNumber]); } }
private unsafe bool BufferAndLoad(long currentAddress, long currentPage, long currentFrame, long headAddress) { for (int i = 0; i < frameSize; i++) { var nextPage = currentPage + i; var pageEndAddress = (nextPage + 1) << allocator.LogPageSizeBits; if (fasterLog.readOnlyMode) { // Support partial page reads of committed data var _flush = fasterLog.CommittedUntilAddress; if (_flush < pageEndAddress) { pageEndAddress = _flush; } } // Cannot load page if its not fully written to storage if (headAddress < pageEndAddress) { continue; } var nextFrame = (currentFrame + i) % frameSize; long val; while ((val = nextLoadedPage[nextFrame]) < pageEndAddress || loadedPage[nextFrame] < pageEndAddress) { if (val < pageEndAddress && Interlocked.CompareExchange(ref nextLoadedPage[nextFrame], pageEndAddress, val) == val) { var tmp_i = i; epoch.BumpCurrentEpoch(() => { allocator.AsyncReadPagesFromDeviceToFrame(tmp_i + (currentAddress >> allocator.LogPageSizeBits), 1, endAddress, AsyncReadPagesCallback, Empty.Default, frame, out loaded[nextFrame], 0, null, null, loadedCancel[nextFrame]); loadedPage[nextFrame] = pageEndAddress; }); } else { epoch.ProtectAndDrain(); } } } return(WaitForFrameLoad(currentAddress, currentFrame)); }
/// <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]); } }
internal override void AsyncReadPagesFromDeviceToFrame <TContext>(long readPageStart, int numPages, long untilAddress, TContext context, out CountdownEvent completed, long devicePageOffset = 0, IDevice device = null, IDevice objectLogDevice = null, CancellationTokenSource cts = null) => allocator.AsyncReadPagesFromDeviceToFrame(readPageStart, numPages, untilAddress, AsyncReadPagesCallback, context, frame, out completed, devicePageOffset, device, objectLogDevice, cts);