Beispiel #1
0
        internal bool GetLogicalAddress(Key *key, out long logicalAddress)
        {
            var bucket = default(HashBucket *);
            var slot   = default(int);

            logicalAddress = Constants.kInvalidAddress;
            var physicalAddress = default(long);
            var info            = default(RecordInfo *);

            var hash = Key.GetHashCode(key);
            var tag  = (ushort)((ulong)hash >> Constants.kHashTagShift);

            var entry     = default(HashBucketEntry);
            var tagExists = FindTag(hash, tag, ref bucket, ref slot, ref entry);

            if (tagExists)
            {
                logicalAddress = entry.word & Constants.kAddressMask;
                Debug.Assert(logicalAddress != 0);
                if (logicalAddress >= hlog.HeadAddress)
                {
                    physicalAddress = hlog.GetPhysicalAddress(logicalAddress);
                    if (!Key.Equals(key, Layout.GetKey(physicalAddress)))
                    {
                        logicalAddress = Layout.GetInfo(physicalAddress)->PreviousAddress;
                        TraceBackForKeyMatch(key, logicalAddress, hlog.HeadAddress, out logicalAddress, out physicalAddress);
                    }
                }
            }

            if (logicalAddress < hlog.HeadAddress && logicalAddress != Constants.kInvalidAddress)
            {
                return(false);
            }
            return(true);
        }
Beispiel #2
0
        private void AsyncGetFromDiskCallback(
            uint errorCode,
            uint numBytes,
            NativeOverlapped *overlap)
        {
            if (errorCode != 0)
            {
                Trace.TraceError("OverlappedStream GetQueuedCompletionStatus error: {0}", errorCode);
            }

            var result = (AsyncGetFromDiskResult <AsyncIOContext>)Overlapped.Unpack(overlap).AsyncResult;

            Interlocked.Decrement(ref numPendingReads);

            var ctx    = result.context;
            var record = ctx.record.GetValidPointer();

            if (Layout.HasTotalRecord(record, ctx.record.available_bytes, out int requiredBytes))
            {
                //We have the complete record.
                if (RetrievedObjects(record, ctx))
                {
                    if (Key.Equals((Key *)ctx.key, Layout.GetKey((long)record)))
                    {
                        //The keys are same, so I/O is complete
                        // ctx.record = result.record;
                        ctx.callbackQueue.Add(ctx);
                    }
                    else
                    {
                        var oldAddress = ctx.logicalAddress;

                        //keys are not same. I/O is not complete
                        ctx.logicalAddress = ((RecordInfo *)record)->PreviousAddress;
                        if (ctx.logicalAddress != Constants.kInvalidAddress)
                        {
                            // Delete key, value, record
                            if (Key.HasObjectsToSerialize())
                            {
                                var physicalAddress = (long)ctx.record.GetValidPointer();
                                Key.Free(Layout.GetKey(physicalAddress));
                            }
                            if (Value.HasObjectsToSerialize())
                            {
                                var physicalAddress = (long)ctx.record.GetValidPointer();
                                Value.Free(Layout.GetValue(physicalAddress));
                            }
                            ctx.record.Return();
                            ctx.record = ctx.objBuffer = default(SectorAlignedMemory);
                            AsyncGetFromDisk(ctx.logicalAddress, requiredBytes, AsyncGetFromDiskCallback, ctx);
                        }
                        else
                        {
                            ctx.callbackQueue.Add(ctx);
                        }
                    }
                }
            }
            else
            {
                ctx.record.Return();
                AsyncGetFromDisk(ctx.logicalAddress, requiredBytes, AsyncGetFromDiskCallback, ctx);
            }

            Overlapped.Free(overlap);
        }
Beispiel #3
0
        protected void AsyncGetFromDiskCallback(
            uint errorCode,
            uint numBytes,
            NativeOverlapped *overlap)
        {
            //Debugger.Break();
            var result = (AsyncGetFromDiskResult <AsyncIOContext>)Overlapped.Unpack(overlap).AsyncResult;

            try
            {
                if (errorCode != 0)
                {
                    Trace.TraceError("OverlappedStream GetQueuedCompletionStatus error: {0}", errorCode);
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError("Completion Callback error, {0}", ex.Message);
            }
            finally
            {
                Interlocked.Decrement(ref numPendingReads);

                var ctx    = result.context;
                var record = ctx.record.GetValidPointer();
                if (Layout.HasTotalRecord(record, ctx.record.available_bytes, out int requiredBytes))
                {
                    //We have the complete record.
                    if (RetrievedObjects(record, ctx))
                    {
                        if (Key.Equals(ctx.key, Layout.GetKey((long)record)))
                        {
                            //The keys are same, so I/O is complete
                            // ctx.record = result.record;
                            ctx.callbackQueue.Add(ctx);
                        }
                        else
                        {
                            var oldAddress = ctx.logicalAddress;

                            //keys are not same. I/O is not complete
                            ctx.logicalAddress = ((RecordInfo *)record)->PreviousAddress;
                            if (ctx.logicalAddress != Constants.kInvalidAddress)
                            {
                                // Delete key, value, record
                                if (Key.HasObjectsToSerialize())
                                {
                                    var physicalAddress = (long)ctx.record.GetValidPointer();
                                    Key.Free(Layout.GetKey(physicalAddress));
                                }
                                if (Value.HasObjectsToSerialize())
                                {
                                    var physicalAddress = (long)ctx.record.GetValidPointer();
                                    Value.Free(Layout.GetValue(physicalAddress));
                                }
                                ctx.record.Return();
                                AsyncGetFromDisk(ctx.logicalAddress, requiredBytes, AsyncGetFromDiskCallback, ctx);
                            }
                            else
                            {
                                //Console.WriteLine("Lookup Address = " + oldAddress);
                                //Console.WriteLine("RecordInfo: " + RecordInfo.ToString((RecordInfo*)record));
                                // Console.WriteLine("Record not found. Looking for: " + ctx.key->value + " found: " + Layout.GetKey((long)record)->value + " req bytes: " + requiredBytes);
                                ctx.callbackQueue.Add(ctx);
                            }
                        }
                    }
                }
                else
                {
                    ctx.record.Return();
                    AsyncGetFromDisk(ctx.logicalAddress, requiredBytes, AsyncGetFromDiskCallback, ctx);
                }

                Overlapped.Free(overlap);
            }
        }