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