Example #1
0
        private bool RetrievedObjects(byte *record, AsyncIOContext ctx)
        {
            if (!Key.HasObjectsToSerialize() && !Value.HasObjectsToSerialize())
            {
                return(true);
            }

            if (ctx.objBuffer.buffer == null)
            {
                // Issue IO for objects
                long startAddress = -1;
                long numBytes     = 0;
                if (Key.HasObjectsToSerialize())
                {
                    var x = (AddressInfo *)Layout.GetKey((long)record);
                    numBytes    += x->Size;
                    startAddress = x->Address;
                }

                if (Value.HasObjectsToSerialize())
                {
                    var x = (AddressInfo *)Layout.GetValue((long)record);
                    numBytes += x->Size;
                    if (startAddress == -1)
                    {
                        startAddress = x->Address;
                    }
                }

                // We are limited to a 2GB size per key-value
                if (numBytes > int.MaxValue)
                {
                    throw new Exception("Size of key-value exceeds max of 2GB: " + numBytes);
                }

                AsyncGetFromDisk(startAddress, (int)numBytes,
                                 AsyncGetFromDiskCallback, ctx, ctx.record);
                return(false);
            }

            // Parse the key and value objects
            MemoryStream ms = new MemoryStream(ctx.objBuffer.buffer);

            ms.Seek(ctx.objBuffer.offset + ctx.objBuffer.valid_offset, SeekOrigin.Begin);
            Key.Deserialize(Layout.GetKey((long)record), ms);
            Value.Deserialize(Layout.GetValue((long)record), ms);
            ctx.objBuffer.Return();
            return(true);
        }
Example #2
0
        private bool RetrievedObjects(byte *record, AsyncIOContext ctx)
        {
            if (!Key.HasObjectsToSerialize() && !Value.HasObjectsToSerialize())
            {
                return(true);
            }

            if (ctx.objBuffer.buffer == null)
            {
                // Issue IO for objects
                long startAddress = -1;
                int  numBytes     = 0;
                if (Key.HasObjectsToSerialize())
                {
                    var x = (AddressInfo *)Layout.GetKey((long)record);
                    if (x->IsDiskAddress)
                    {
                        numBytes    += x->Size;
                        startAddress = x->Address;
                    }
                }

                if (Value.HasObjectsToSerialize())
                {
                    var x = (AddressInfo *)Layout.GetValue((long)record);
                    if (x->IsDiskAddress)
                    {
                        numBytes += x->Size;
                        if (startAddress == -1)
                        {
                            startAddress = x->Address;
                        }
                    }
                }

                AsyncGetFromDisk(startAddress, numBytes,
                                 AsyncGetFromDiskCallback, ctx, ctx.record);
                return(false);
            }

            // Parse the key and value objects
            MemoryStream ms = new MemoryStream(ctx.objBuffer.buffer);

            ms.Seek(ctx.objBuffer.offset + ctx.objBuffer.valid_offset, SeekOrigin.Begin);
            Key.Deserialize(Layout.GetKey((long)record), ms);
            Value.Deserialize(Layout.GetValue((long)record), ms);
            ctx.objBuffer.Return();
            return(true);
        }
Example #3
0
        /// <summary>
        /// Deseialize part of page from stream
        /// </summary>
        /// <param name="ptr">From pointer</param>
        /// <param name="untilptr">Until pointer</param>
        /// <param name="stream">Stream</param>
        public void Deserialize(long ptr, long untilptr, Stream stream)
        {
            while (ptr < untilptr)
            {
                if (!Layout.GetInfo(ptr)->Invalid)
                {
                    if (Key.HasObjectsToSerialize())
                    {
                        Key.Deserialize(Layout.GetKey(ptr), stream);
                    }

                    if (Value.HasObjectsToSerialize())
                    {
                        Value.Deserialize(Layout.GetValue(ptr), stream);
                    }
                }
                ptr += Layout.GetPhysicalSize(ptr);
            }
        }
Example #4
0
        private void AsyncReadPageCallback <TContext>(uint errorCode, uint numBytes, NativeOverlapped *overlap)
        {
            if (errorCode != 0)
            {
                Trace.TraceError("OverlappedStream GetQueuedCompletionStatus error: {0}", errorCode);
            }

            PageAsyncReadResult <TContext> result = (PageAsyncReadResult <TContext>)Overlapped.Unpack(overlap).AsyncResult;

            if (Interlocked.Decrement(ref result.count) == 1)
            {
                // We will be issuing another I/O, so free this overlap
                Overlapped.Free(overlap);

                long ptr = (long)pointers[result.page % BufferSize];
                // Correct for page 0 of HLOG
                if (result.page == 0)
                {
                    ptr += Constants.kFirstValidAddress;
                }

                long minObjAddress = long.MaxValue;
                long maxObjAddress = long.MinValue;

                while (ptr < (long)pointers[result.page % BufferSize] + PageSize)
                {
                    if (!Layout.GetInfo(ptr)->Invalid)
                    {
                        if (Key.HasObjectsToSerialize())
                        {
                            Key *key  = Layout.GetKey(ptr);
                            var  addr = ((AddressInfo *)key)->Address;
                            if (addr < minObjAddress)
                            {
                                minObjAddress = addr;
                            }
                            addr += ((AddressInfo *)key)->Size;
                            if (addr > maxObjAddress)
                            {
                                maxObjAddress = addr;
                            }
                        }

                        if (Value.HasObjectsToSerialize())
                        {
                            Value *value = Layout.GetValue(ptr);
                            var    addr  = ((AddressInfo *)value)->Address;
                            if (addr < minObjAddress)
                            {
                                minObjAddress = addr;
                            }
                            addr += ((AddressInfo *)value)->Size;
                            if (addr > maxObjAddress)
                            {
                                maxObjAddress = addr;
                            }
                        }
                    }
                    ptr += Layout.GetPhysicalSize(ptr);
                }

                // Object log fragment should be aligned by construction
                Debug.Assert(minObjAddress % sectorSize == 0);

                var to_read   = (int)(maxObjAddress - minObjAddress);
                var objBuffer = ioBufferPool.Get(to_read);
                result.freeBuffer1 = objBuffer;
                var alignedLength = (to_read + (sectorSize - 1)) & ~(sectorSize - 1);

                // Request objects from objlog
                result.objlogDevice.ReadAsync(
                    (int)(result.page >> (LogSegmentSizeBits - LogPageSizeBits)),
                    (ulong)minObjAddress,
                    (IntPtr)objBuffer.aligned_pointer, (uint)alignedLength, AsyncReadPageCallback <TContext>, result);
            }
            else
            {
                // Load objects from buffer into memory
                long ptr = (long)pointers[result.page % BufferSize];
                // Correct for page 0 of HLOG
                if (result.page == 0)
                {
                    ptr += Constants.kFirstValidAddress;
                }

                MemoryStream ms = new MemoryStream(result.freeBuffer1.buffer);
                ms.Seek(result.freeBuffer1.offset + result.freeBuffer1.valid_offset, SeekOrigin.Begin);

                while (ptr < (long)pointers[result.page % BufferSize] + PageSize)
                {
                    if (!Layout.GetInfo(ptr)->Invalid)
                    {
                        if (Key.HasObjectsToSerialize())
                        {
                            Key.Deserialize(Layout.GetKey(ptr), ms);
                        }

                        if (Value.HasObjectsToSerialize())
                        {
                            Value.Deserialize(Layout.GetValue(ptr), ms);
                        }
                    }
                    ptr += Layout.GetPhysicalSize(ptr);
                }
                ms.Dispose();

                result.Free();

                // Call the "real" page read callback
                result.callback(errorCode, numBytes, overlap);
            }
        }