/// <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]); }
/// <inheritdoc /> public override void InitializeForReads() { base.InitializeForReads(); if (frameSize > 0 && (endAddress > 0 || tailAddress > 0)) { frame = new BlittableFrame(frameSize, 1 << LogPageSizeBits, sectorSize); } }
/// <summary> /// Read pages from specified device /// </summary> /// <typeparam name="TContext"></typeparam> /// <param name="readPageStart"></param> /// <param name="numPages"></param> /// <param name="untilAddress"></param> /// <param name="callback"></param> /// <param name="context"></param> /// <param name="frame"></param> /// <param name="completed"></param> /// <param name="devicePageOffset"></param> /// <param name="device"></param> /// <param name="objectLogDevice"></param> internal void AsyncReadPagesFromDeviceToFrame <TContext>( long readPageStart, int numPages, long untilAddress, IOCompletionCallback callback, TContext context, BlittableFrame frame, out CountdownEvent completed, long devicePageOffset = 0, IDevice device = null, IDevice objectLogDevice = null) { var usedDevice = device; IDevice usedObjlogDevice = objectLogDevice; if (device == null) { usedDevice = this.device; } completed = new CountdownEvent(numPages); for (long readPage = readPageStart; readPage < (readPageStart + numPages); readPage++) { int pageIndex = (int)(readPage % frame.frameSize); if (frame.frame[pageIndex] == null) { frame.Allocate(pageIndex); } else { frame.Clear(pageIndex); } var asyncResult = new PageAsyncReadResult <TContext>() { page = readPage, context = context, handle = completed, frame = frame }; ulong offsetInFile = (ulong)(AlignedPageSizeBytes * readPage); uint readLength = (uint)AlignedPageSizeBytes; long adjustedUntilAddress = (AlignedPageSizeBytes * (untilAddress >> LogPageSizeBits) + (untilAddress & PageSizeMask)); if (adjustedUntilAddress > 0 && ((adjustedUntilAddress - (long)offsetInFile) < PageSize)) { readLength = (uint)(adjustedUntilAddress - (long)offsetInFile); readLength = (uint)((readLength + (sectorSize - 1)) & ~(sectorSize - 1)); } if (device != null) { offsetInFile = (ulong)(AlignedPageSizeBytes * (readPage - devicePageOffset)); } usedDevice.ReadAsync(offsetInFile, (IntPtr)frame.pointers[pageIndex], readLength, callback, asyncResult); } }
/// <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> /// Read pages from specified device /// </summary> /// <typeparam name="TContext"></typeparam> /// <param name="readPageStart"></param> /// <param name="numPages"></param> /// <param name="callback"></param> /// <param name="context"></param> /// <param name="frame"></param> /// <param name="completed"></param> /// <param name="devicePageOffset"></param> /// <param name="device"></param> /// <param name="objectLogDevice"></param> internal void AsyncReadPagesFromDeviceToFrame <TContext>( long readPageStart, int numPages, IOCompletionCallback callback, TContext context, BlittableFrame frame, out CountdownEvent completed, long devicePageOffset = 0, IDevice device = null, IDevice objectLogDevice = null) { var usedDevice = device; IDevice usedObjlogDevice = objectLogDevice; if (device == null) { usedDevice = this.device; } completed = new CountdownEvent(numPages); for (long readPage = readPageStart; readPage < (readPageStart + numPages); readPage++) { int pageIndex = (int)(readPage % frame.frameSize); if (frame.frame[pageIndex] == null) { frame.Allocate(pageIndex); } else { frame.Clear(pageIndex); } var asyncResult = new PageAsyncReadResult <TContext>() { page = readPage, context = context, handle = completed, count = 1, frame = frame }; ulong offsetInFile = (ulong)(AlignedPageSizeBytes * readPage); if (device != null) { offsetInFile = (ulong)(AlignedPageSizeBytes * (readPage - devicePageOffset)); } usedDevice.ReadAsync(offsetInFile, (IntPtr)frame.pointers[pageIndex], (uint)AlignedPageSizeBytes, callback, asyncResult); } }
/// <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]); } }
/// <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="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) { this.fasterLog = fasterLog; this.allocator = hlog; this.getMemory = getMemory; this.epoch = epoch; this.headerSize = headerSize; this.scanUncommitted = scanUncommitted; 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]); } }