Пример #1
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));
        }
Пример #2
0
        /// <summary>
        /// Buffer and load
        /// </summary>
        /// <param name="currentAddress"></param>
        /// <param name="currentPage"></param>
        /// <param name="currentFrame"></param>
        /// <param name="headAddress"></param>
        /// <param name="endAddress"></param>
        /// <returns></returns>
        protected unsafe bool BufferAndLoad(long currentAddress, long currentPage, long currentFrame, long headAddress, long endAddress)
        {
            for (int i = 0; i < frameSize; i++)
            {
                var nextPage = currentPage + i;

                var pageStartAddress = nextPage << logPageSizeBits;
                // Cannot load page if it is entirely in memory or beyond the end address
                if (pageStartAddress >= headAddress || pageStartAddress >= endAddress)
                {
                    continue;
                }

                var pageEndAddress = (nextPage + 1) << logPageSizeBits;
                if (endAddress < pageEndAddress)
                {
                    pageEndAddress = endAddress;
                }
                if (headAddress < pageEndAddress)
                {
                    pageEndAddress = headAddress;
                }

                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;
                        if (epoch != null)
                        {
                            epoch.BumpCurrentEpoch(() =>
                            {
                                AsyncReadPagesFromDeviceToFrame(tmp_i + (currentAddress >> logPageSizeBits), 1, endAddress, Empty.Default, out loaded[nextFrame], 0, null, null, loadedCancel[nextFrame]);
                                loadedPage[nextFrame] = pageEndAddress;
                            });
                        }
                        else
                        {
                            AsyncReadPagesFromDeviceToFrame(tmp_i + (currentAddress >> logPageSizeBits), 1, endAddress, Empty.Default, out loaded[nextFrame], 0, null, null, loadedCancel[nextFrame]);
                            loadedPage[nextFrame] = pageEndAddress;
                        }
                    }
                    else
                    {
                        epoch?.ProtectAndDrain();
                    }
                }
            }
            return(WaitForFrameLoad(currentAddress, currentFrame));
        }
Пример #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;

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