/// <summary> /// Get next record /// </summary> /// <param name="recordInfo"></param> /// <returns>True if record found, false if end of scan</returns> public bool GetNext(out RecordInfo recordInfo) { recordInfo = default; while (true) { currentAddress = nextAddress; // Check for boundary conditions if (currentAddress >= endAddress) { return(false); } if (currentAddress < hlog.BeginAddress) { throw new FasterException("Iterator address is less than log BeginAddress " + hlog.BeginAddress); } if (frameSize == 0 && currentAddress < hlog.HeadAddress) { throw new FasterException("Iterator address is less than log HeadAddress in memory-scan mode"); } var currentPage = currentAddress >> hlog.LogPageSizeBits; var offset = currentAddress & hlog.PageSizeMask; if (currentAddress < hlog.HeadAddress) { BufferAndLoad(currentAddress, currentPage, currentPage % frameSize); } long physicalAddress; if (currentAddress >= hlog.HeadAddress) { physicalAddress = hlog.GetPhysicalAddress(currentAddress); } else { physicalAddress = frame.GetPhysicalAddress(currentPage % frameSize, offset); } // Check if record fits on page, if not skip to next page var recordSize = hlog.GetRecordSize(physicalAddress); if ((currentAddress & hlog.PageSizeMask) + recordSize > hlog.PageSize) { nextAddress = (1 + (currentAddress >> hlog.LogPageSizeBits)) << hlog.LogPageSizeBits; continue; } nextAddress = currentAddress + recordSize; ref var info = ref hlog.GetInfo(physicalAddress); if (info.Invalid || info.IsNull()) { continue; } currentPhysicalAddress = physicalAddress; recordInfo = info; return(true); }
/// <summary> /// Get next record in iterator /// </summary> /// <param name="recordInfo"></param> /// <param name="key"></param> /// <param name="value"></param> /// <returns></returns> public bool GetNext(out RecordInfo recordInfo, out Key key, out Value value) { recordInfo = default(RecordInfo); key = default(Key); value = default(Value); currentAddress = nextAddress; while (true) { // Check for boundary conditions if (currentAddress >= endAddress) { return(false); } if (currentAddress < hlog.BeginAddress) { throw new Exception("Iterator address is less than log BeginAddress " + hlog.BeginAddress); } if (frameSize == 0 && currentAddress < hlog.HeadAddress) { throw new Exception("Iterator address is less than log HeadAddress in memory-scan mode"); } var currentPage = currentAddress >> hlog.LogPageSizeBits; var offset = currentAddress & hlog.PageSizeMask; if (currentAddress < hlog.HeadAddress) { BufferAndLoad(currentAddress, currentPage, currentPage % frameSize); } var recordSize = hlog.GetRecordSize(hlog.GetPhysicalAddress(currentAddress)); // Check if record fits on page, if not skip to next page if ((currentAddress & hlog.PageSizeMask) + recordSize > hlog.PageSize) { currentAddress = (1 + (currentAddress >> hlog.LogPageSizeBits)) << hlog.LogPageSizeBits; continue; } if (currentAddress >= hlog.HeadAddress) { // Read record from cached page memory var _physicalAddress = hlog.GetPhysicalAddress(currentAddress); if (hlog.GetInfo(_physicalAddress).Invalid) { currentAddress += hlog.GetRecordSize(_physicalAddress); continue; } recordInfo = hlog.GetInfo(_physicalAddress); key = hlog.GetKey(_physicalAddress); value = hlog.GetValue(_physicalAddress); nextAddress = currentAddress + hlog.GetRecordSize(_physicalAddress); return(true); } var physicalAddress = frame.GetPhysicalAddress(currentPage % frameSize, offset); if (hlog.GetInfo(physicalAddress).Invalid) { currentAddress += hlog.GetRecordSize(physicalAddress); continue; } recordInfo = hlog.GetInfo(physicalAddress); key = hlog.GetKey(physicalAddress); value = hlog.GetValue(physicalAddress); nextAddress = currentAddress + hlog.GetRecordSize(physicalAddress); return(true); } }
/// <summary> /// Get next record /// </summary> /// <param name="recordInfo"></param> /// <returns>True if record found, false if end of scan</returns> public bool GetNext(out RecordInfo recordInfo) { recordInfo = default; while (true) { currentAddress = nextAddress; // Check for boundary conditions if (currentAddress >= endAddress) { return(false); } epoch?.Resume(); var headAddress = hlog.HeadAddress; if (currentAddress < hlog.BeginAddress && !forceInMemory) { epoch?.Suspend(); throw new FasterException("Iterator address is less than log BeginAddress " + hlog.BeginAddress); } if (frameSize == 0 && currentAddress < headAddress && !forceInMemory) { epoch?.Suspend(); throw new FasterException("Iterator address is less than log HeadAddress in memory-scan mode"); } var currentPage = currentAddress >> hlog.LogPageSizeBits; var offset = currentAddress & hlog.PageSizeMask; if (currentAddress < headAddress && !forceInMemory) { BufferAndLoad(currentAddress, currentPage, currentPage % frameSize, headAddress, endAddress); } long physicalAddress; if (currentAddress >= headAddress || forceInMemory) { physicalAddress = hlog.GetPhysicalAddress(currentAddress); currentPhysicalAddress = 0; } else { currentPhysicalAddress = physicalAddress = frame.GetPhysicalAddress(currentPage % frameSize, offset); } // Check if record fits on page, if not skip to next page var recordSize = hlog.GetRecordSize(physicalAddress).Item2; if ((currentAddress & hlog.PageSizeMask) + recordSize > hlog.PageSize) { nextAddress = (1 + (currentAddress >> hlog.LogPageSizeBits)) << hlog.LogPageSizeBits; epoch?.Suspend(); continue; } nextAddress = currentAddress + recordSize; ref var info = ref hlog.GetInfo(physicalAddress); if (info.SkipOnScan || info.IsNull()) { epoch?.Suspend(); continue; } recordInfo = info; if (currentPhysicalAddress == 0) { currentKey = hlog.GetKey(physicalAddress); currentValue = hlog.GetValue(physicalAddress); } epoch?.Suspend(); return(true); }