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);
        }
Ejemplo n.º 2
0
 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();
 }
Ejemplo n.º 3
0
        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));
        }
Ejemplo n.º 4
0
        /// <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]);
        }
Ejemplo n.º 5
0
        /// <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]);
            }
        }
Ejemplo n.º 6
0
        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));
        }
Ejemplo n.º 7
0
        /// <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]);
            }
        }
Ejemplo n.º 8
0
 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);