Example #1
0
        /// <summary>
        /// Flush pages from startPage (inclusive) to endPage (exclusive)
        /// to specified log device and obj device
        /// </summary>
        /// <param name="startPage"></param>
        /// <param name="endPage"></param>
        /// <param name="device"></param>
        /// <param name="completed"></param>
        public void AsyncFlushPagesToDevice(long startPage, long endPage, IDevice device, out CountdownEvent completed)
        {
            ISegmentedDevice objlogDevice = null;

            if (Key.HasObjectsToSerialize() || Value.HasObjectsToSerialize())
            {
                objlogDevice = CreateObjectLogDevice(device);
            }

            int totalNumPages = (int)(endPage - startPage);

            completed = new CountdownEvent(totalNumPages);

            for (long flushPage = startPage; flushPage < endPage; flushPage++)
            {
                var asyncResult = new PageAsyncFlushResult <Empty>
                {
                    handle = completed,
                    count  = 1
                };

                long pageStartAddress = flushPage << LogPageSizeBits;
                long pageEndAddress   = (flushPage + 1) << LogPageSizeBits;

                WriteAsync(pointers[flushPage % BufferSize],
                           (ulong)(AlignedPageSizeBytes * (flushPage - startPage)),
                           PageSize,
                           AsyncFlushPageToDeviceCallback,
                           asyncResult, device, objlogDevice);
            }
        }
Example #2
0
        public void AsyncReadPagesFromDevice(int numPages, long destinationStartPage, IDevice device, out CountdownEvent completed)
        {
            var asyncResult = new PageAsyncFlushResult();

            ISegmentedDevice objlogDevice = null;

            if (Key.HasObjectsToSerialize() || Value.HasObjectsToSerialize())
            {
                objlogDevice = CreateObjectLogDevice(device);
                throw new Exception("Reading pages with object log not yet supported");
            }
            completed                = new CountdownEvent(numPages);
            asyncResult.handle       = completed;
            asyncResult.objlogDevice = objlogDevice;

            for (long flushPage = destinationStartPage; flushPage < destinationStartPage + numPages; flushPage++)
            {
                long pageStartAddress = flushPage << LogPageSizeBits;
                long pageEndAddress   = (flushPage + 1) << LogPageSizeBits;

                device.ReadAsync(
                    (ulong)(AlignedPageSizeBytes * (flushPage - destinationStartPage)),
                    pointers[flushPage % BufferSize],
                    PageSize,
                    AsyncReadPageFromDeviceCallback,
                    asyncResult);
            }
        }
Example #3
0
        /// <summary>
        /// Flush pages from startPage (inclusive) to endPage (exclusive)
        /// to specified log device and obj device
        /// </summary>
        /// <param name="startPage"></param>
        /// <param name="endPage"></param>
        /// <param name="device"></param>
        public void AsyncFlushPagesToDevice(long startPage, long endPage, IDevice device, out CountdownEvent completed)
        {
            var asyncResult = new PageAsyncFlushResult();

            int numPages = (int)(endPage - startPage);

            ISegmentedDevice objlogDevice = null;

            if (Key.HasObjectsToSerialize() || Value.HasObjectsToSerialize())
            {
                numPages     = numPages * 2;
                objlogDevice = CreateObjectLogDevice(device);
            }

            completed          = new CountdownEvent(numPages);
            asyncResult.handle = completed;
            for (long flushPage = startPage; flushPage < endPage; flushPage++)
            {
                long pageStartAddress = flushPage << LogPageSizeBits;
                long pageEndAddress   = (flushPage + 1) << LogPageSizeBits;

                WriteAsync(pointers[flushPage % BufferSize],
                           (ulong)(AlignedPageSizeBytes * (flushPage - startPage)),
                           (uint)(PageSize * PrivateRecordSize),
                           AsyncFlushPageToDeviceCallback,
                           asyncResult, device, objlogDevice);
            }
        }
Example #4
0
        public WrappedDevice(ISegmentedDevice device)
        {
            _device      = device;
            _segmentSize = device.GetSegmentSize();

            if (!Utility.IsPowerOfTwo(_segmentSize))
            {
                throw new Exception("Invalid segment size");
            }

            _segmentSizeBits = Utility.GetLogBase2((ulong)_segmentSize);
            _segmentSizeMask = _segmentSize - 1;
        }
Example #5
0
        public void AsyncReadPagesFromDevice <TContext>(
            long readPageStart,
            int numPages,
            IOCompletionCallback callback,
            TContext context,
            out CountdownEvent completed,
            long devicePageOffset = 0,
            IDevice device        = null)
        {
            var usedDevice = (device != null) ? device : this.device;
            ISegmentedDevice usedObjlogDevice = null;

            if (Key.HasObjectsToSerialize() || Value.HasObjectsToSerialize())
            {
                usedObjlogDevice = (device != null) ? CreateObjectLogDevice(device) : objlogDevice;
            }

            completed = new CountdownEvent(numPages);
            for (long readPage = readPageStart; readPage < (readPageStart + numPages); readPage++)
            {
                int pageIndex = (int)(readPage % BufferSize);
                if (values[pageIndex] == null)
                {
                    // Allocate a new page
                    AllocatePage(pageIndex);
                }
                else
                {
                    ClearPage(pageIndex, readPage == 0);
                }
                var asyncResult = new PageAsyncReadResult <TContext>()
                {
                    page    = readPage,
                    context = context,
                    handle  = completed,
                    count   = 1
                };

                ulong offsetInFile = (ulong)(AlignedPageSizeBytes * readPage);

                if (device != null)
                {
                    offsetInFile = (ulong)(AlignedPageSizeBytes * (readPage - devicePageOffset));
                }

                ReadAsync(offsetInFile, pointers[pageIndex], PageSize, callback, asyncResult, usedDevice, usedObjlogDevice);
            }
        }
Example #6
0
        public PersistentMemoryMalloc(IDevice device, long startAddress)
        {
            // Console.WriteLine("Total memory (GB) = " + totalSize/1000000000);
            // Console.WriteLine("BufferSize = " + BufferSize);
            // Console.WriteLine("ReadOnlyLag = " + (ReadOnlyLagAddress >> PageSizeBits));

            if (BufferSize < 16)
            {
                throw new Exception("HLOG buffer must be at least 16 pages");
            }

            this.device = device;

            objlogDevice = CreateObjectLogDevice(device);

            sectorSize   = (int)device.GetSectorSize();
            epoch        = LightEpoch.Instance;
            ioBufferPool = new NativeSectorAlignedBufferPool(1, sectorSize);

            if (ForceUnpinnedAllocation)
            {
                IsPinned = false;
            }
            else
            {
                IsPinned = true;
                try
                {
                    var tmp = new T[1];
                    var h   = GCHandle.Alloc(tmp, GCHandleType.Pinned);
                    var p   = h.AddrOfPinnedObject();
                    //PrivateRecordSize = Marshal.SizeOf(tmp[0]);
                    AlignedPageSizeBytes = (((PrivateRecordSize * PageSize) + (sectorSize - 1)) & ~(sectorSize - 1));
                }
                catch (Exception)
                {
                    IsPinned = false;
                }
            }

            ptrHandle      = GCHandle.Alloc(pointers, GCHandleType.Pinned);
            nativePointers = (long *)ptrHandle.AddrOfPinnedObject();

            Initialize(startAddress);
        }
Example #7
0
        public PersistentMemoryMalloc(IDevice device, long startAddress)
        {
            if (BufferSize < 16)
            {
                throw new Exception("HLOG buffer must be at least 16 pages");
            }

            this.device = device;

            objlogDevice = CreateObjectLogDevice(device);

            sectorSize           = (int)device.GetSectorSize();
            epoch                = LightEpoch.Instance;
            ioBufferPool         = new NativeSectorAlignedBufferPool(1, sectorSize);
            AlignedPageSizeBytes = ((PageSize + (sectorSize - 1)) & ~(sectorSize - 1));

            ptrHandle      = GCHandle.Alloc(pointers, GCHandleType.Pinned);
            nativePointers = (long *)ptrHandle.AddrOfPinnedObject();

            Initialize(startAddress);
        }
Example #8
0
        private void ReadAsync <TContext>(
            ulong alignedSourceAddress, IntPtr alignedDestinationAddress, uint aligned_read_length,
            IOCompletionCallback callback, PageAsyncReadResult <TContext> asyncResult, IDevice device, ISegmentedDevice objlogDevice)
        {
            if (!Key.HasObjectsToSerialize() && !Value.HasObjectsToSerialize())
            {
                device.ReadAsync(alignedSourceAddress, alignedDestinationAddress,
                                 aligned_read_length, callback, asyncResult);
                return;
            }

            asyncResult.callback = callback;
            asyncResult.count++;
            asyncResult.objlogDevice = objlogDevice;

            device.ReadAsync(alignedSourceAddress, alignedDestinationAddress,
                             aligned_read_length, AsyncReadPageCallback <TContext>, asyncResult);
        }
Example #9
0
        private void WriteAsync <TContext>(IntPtr alignedSourceAddress, ulong alignedDestinationAddress, uint numBytesToWrite,
                                           IOCompletionCallback callback, PageAsyncFlushResult <TContext> asyncResult,
                                           IDevice device, ISegmentedDevice objlogDevice)
        {
            if (!Key.HasObjectsToSerialize() && !Value.HasObjectsToSerialize())
            {
                device.WriteAsync(alignedSourceAddress, alignedDestinationAddress,
                                  numBytesToWrite, callback, asyncResult);
                return;
            }

            // need to write both page and object cache
            asyncResult.count++;
            MemoryStream ms     = new MemoryStream();
            var          buffer = ioBufferPool.Get(PageSize);

            Buffer.MemoryCopy((void *)alignedSourceAddress, buffer.aligned_pointer, numBytesToWrite, numBytesToWrite);

            long        ptr  = (long)buffer.aligned_pointer;
            List <long> addr = new List <long>();

            asyncResult.freeBuffer1 = buffer;

            // Correct for page 0 of HLOG
            if (alignedDestinationAddress >> LogPageSizeBits == 0)
            {
                ptr += Constants.kFirstValidAddress;
            }

            while (ptr < (long)buffer.aligned_pointer + numBytesToWrite)
            {
                if (!Layout.GetInfo(ptr)->Invalid)
                {
                    long pos = ms.Position;

                    Key *key = Layout.GetKey(ptr);
                    Key.Serialize(key, ms);
                    ((AddressInfo *)key)->IsDiskAddress = true;
                    ((AddressInfo *)key)->Address       = pos;
                    ((AddressInfo *)key)->Size          = (int)(ms.Position - pos);
                    addr.Add((long)key);

                    pos = ms.Position;
                    Value *value = Layout.GetValue(ptr);
                    Value.Serialize(value, ms);
                    ((AddressInfo *)value)->IsDiskAddress = true;
                    ((AddressInfo *)value)->Address       = pos;
                    ((AddressInfo *)value)->Size          = (int)(ms.Position - pos);
                    addr.Add((long)value);
                }
                ptr += Layout.GetPhysicalSize(ptr);
            }


            var s         = ms.ToArray();
            var objBuffer = ioBufferPool.Get(s.Length);

            asyncResult.freeBuffer2 = objBuffer;

            var alignedLength = (s.Length + (sectorSize - 1)) & ~(sectorSize - 1);

            var objAddr = Interlocked.Add(ref segmentOffsets[(alignedDestinationAddress >> LogSegmentSizeBits) % SegmentBufferSize], alignedLength) - alignedLength;

            fixed(void *src = s)
            Buffer.MemoryCopy(src, objBuffer.aligned_pointer, s.Length, s.Length);

            foreach (var address in addr)
            {
                *((long *)address) += objAddr;
            }

            objlogDevice.WriteAsync(
                (IntPtr)objBuffer.aligned_pointer,
                (int)(alignedDestinationAddress >> LogSegmentSizeBits),
                (ulong)objAddr, (uint)alignedLength, callback, asyncResult);

            device.WriteAsync((IntPtr)buffer.aligned_pointer, alignedDestinationAddress,
                              numBytesToWrite, callback, asyncResult);
        }