Beispiel #1
0
        /// <summary>
        /// Get next record in iterator
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool GetNext(out Key key, out Value value)
        {
            key   = default(Key);
            value = default(Value);

            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);
                }

                var currentPage  = currentAddress >> hlog.LogPageSizeBits;
                var currentFrame = currentPage % frameSize;
                var offset       = currentAddress & hlog.PageSizeMask;

                if (currentAddress < hlog.HeadAddress)
                {
                    BufferAndLoad(currentAddress, currentPage, currentFrame);
                }

                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);

                    key             = hlog.GetKey(_physicalAddress);
                    value           = hlog.GetValue(_physicalAddress);
                    currentAddress += hlog.GetRecordSize(_physicalAddress);
                    return(true);
                }

                var physicalAddress = frame.GetPhysicalAddress(currentFrame, offset);
                key             = hlog.GetKey(physicalAddress);
                value           = hlog.GetValue(physicalAddress);
                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);
            }