Пример #1
0
        private bool WaitForFrameLoad(long currentAddress, long currentFrame)
        {
            if (loaded[currentFrame].IsSet)
            {
                return(false);
            }

            try
            {
                epoch?.Suspend();
                loaded[currentFrame].Wait(loadedCancel[currentFrame].Token); // Ensure we have completed ongoing load
            }
            catch (Exception e)
            {
                loadedPage[currentFrame]   = -1;
                loadedCancel[currentFrame] = new CancellationTokenSource();
                Utility.MonotonicUpdate(ref nextAddress, (1 + (currentAddress >> logPageSizeBits)) << logPageSizeBits, out _);
                throw new FasterException("Page read from storage failed, skipping page. Inner exception: " + e.ToString());
            }
            finally
            {
                epoch?.Resume();
            }
            return(true);
        }
Пример #2
0
        /// <summary>
        /// Try to enqueue entry to log (in memory). If it returns true, we are
        /// done. If it returns false, we need to retry.
        /// </summary>
        /// <param name="entry">Entry to be enqueued to log</param>
        /// <param name="logicalAddress">Logical address of added entry</param>
        /// <returns>Whether the append succeeded</returns>
        public unsafe bool TryEnqueue(byte[] entry, out long logicalAddress)
        {
            logicalAddress = 0;

            epoch.Resume();

            var length = entry.Length;

            logicalAddress = allocator.TryAllocate(headerSize + Align(length));
            if (logicalAddress == 0)
            {
                epoch.Suspend();
                return(false);
            }

            var physicalAddress = allocator.GetPhysicalAddress(logicalAddress);

            fixed(byte *bp = entry)
            Buffer.MemoryCopy(bp, (void *)(headerSize + physicalAddress), length, length);

            SetHeader(length, (byte *)physicalAddress);
            epoch.Suspend();
            return(true);
        }
Пример #3
0
        /// <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)
                {
                    epoch?.Suspend();
                    throw new FasterException("Iterator address is less than log BeginAddress " + hlog.BeginAddress);
                }

                if (frameSize == 0 && currentAddress < headAddress)
                {
                    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)
                {
                    BufferAndLoad(currentAddress, currentPage, currentPage % frameSize);
                }

                long physicalAddress;
                if (currentAddress >= headAddress)
                {
                    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.Invalid || info.IsNull())
                {
                    epoch?.Suspend();
                    continue;
                }

                recordInfo = info;
                if (currentPhysicalAddress == 0)
                {
                    currentKey   = hlog.GetKey(physicalAddress);
                    currentValue = hlog.GetValue(physicalAddress);
                }
                epoch?.Suspend();
                return(true);
            }
Пример #4
0
        /// <summary>
        /// Get next record in iterator
        /// </summary>
        /// <param name="recordInfo"></param>
        /// <returns></returns>
        public bool GetNext(out RecordInfo recordInfo)
        {
            recordInfo   = default;
            currentKey   = default;
            currentValue = default;

            while (true)
            {
                currentAddress = nextAddress;

                // Check for boundary conditions
                if (currentAddress >= endAddress)
                {
                    return(false);
                }

                epoch?.Resume();
                var headAddress = hlog.HeadAddress;

                if (currentAddress < hlog.BeginAddress)
                {
                    epoch?.Suspend();
                    throw new FasterException("Iterator address is less than log BeginAddress " + hlog.BeginAddress);
                }

                if (frameSize == 0 && currentAddress < headAddress)
                {
                    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) / recordSize;

                if (currentAddress < headAddress)
                {
                    BufferAndLoad(currentAddress, currentPage, currentPage % frameSize);
                }

                // Check if record fits on page, if not skip to next page
                if ((currentAddress & hlog.PageSizeMask) + recordSize > hlog.PageSize)
                {
                    nextAddress = (1 + (currentAddress >> hlog.LogPageSizeBits)) << hlog.LogPageSizeBits;
                    epoch?.Suspend();
                    continue;
                }

                nextAddress = currentAddress + recordSize;

                if (currentAddress >= headAddress)
                {
                    // Read record from cached page memory
                    var page = currentPage % hlog.BufferSize;

                    if (hlog.values[page][offset].info.Invalid)
                    {
                        epoch?.Suspend();
                        continue;
                    }

                    recordInfo   = hlog.values[page][offset].info;
                    currentKey   = hlog.values[page][offset].key;
                    currentValue = hlog.values[page][offset].value;
                    epoch?.Suspend();
                    return(true);
                }

                var currentFrame = currentPage % frameSize;

                if (frame.GetInfo(currentFrame, offset).Invalid)
                {
                    epoch?.Suspend();
                    continue;
                }

                recordInfo   = frame.GetInfo(currentFrame, offset);
                currentKey   = frame.GetKey(currentFrame, offset);
                currentValue = frame.GetValue(currentFrame, offset);
                epoch?.Suspend();
                return(true);
            }
        }