private void ClearPage(int page, bool pageZero) { if (Key.HasObjectsToSerialize() || Value.HasObjectsToSerialize()) { long ptr = (long)pointers[page]; int numBytes = PageSize; long endptr = ptr + numBytes; if (pageZero) { ptr += Constants.kFirstValidAddress; } List <long> addr = new List <long>(); while (ptr < endptr) { if (!Layout.GetInfo(ptr)->Invalid) { if (Key.HasObjectsToSerialize()) { Key *key = Layout.GetKey(ptr); Key.Free(key); } if (Value.HasObjectsToSerialize()) { Value *value = Layout.GetValue(ptr); Value.Free(value); } } ptr += Layout.GetPhysicalSize(ptr); } } Array.Clear(values[page], 0, values[page].Length); }
/// <summary> /// Clear page /// </summary> /// <param name="ptr">From pointer</param> /// <param name="endptr">Until pointer</param> public void ClearPage(long ptr, long endptr) { while (ptr < endptr) { if (!Layout.GetInfo(ptr)->Invalid) { if (Key.HasObjectsToSerialize()) { Key *key = Layout.GetKey(ptr); Key.Free(key); } if (Value.HasObjectsToSerialize()) { Value *value = Layout.GetValue(ptr); Value.Free(value); } } ptr += Layout.GetPhysicalSize(ptr); } }
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); }
internal void InternalContinuePendingRequestAndCallback( ExecutionContext ctx, AsyncIOContext request) { var handleLatches = false; if ((ctx.version < threadCtx.version) // Thread has already shifted to (v+1) || (threadCtx.phase == Phase.PREPARE)) // Thread still in version v, but acquired shared-latch { handleLatches = true; } if (ctx.ioPendingRequests.TryGetValue(request.id, out PendingContext pendingContext)) { var status = default(Status); var internalStatus = default(OperationStatus); // Remove from pending dictionary ctx.ioPendingRequests.Remove(request.id); // Issue the continue command if (pendingContext.type == OperationType.READ) { internalStatus = InternalContinuePendingRead(ctx, request, ref pendingContext); } else { internalStatus = InternalContinuePendingRMW(ctx, request, ref pendingContext);; } // Delete key, value, record if (Key.HasObjectsToSerialize()) { var physicalAddress = (long)request.record.GetValidPointer(); Key.Free(Layout.GetKey(physicalAddress)); } if (Value.HasObjectsToSerialize()) { var physicalAddress = (long)request.record.GetValidPointer(); Value.Free(Layout.GetValue(physicalAddress)); } request.record.Return(); // Handle operation status if (internalStatus == OperationStatus.SUCCESS || internalStatus == OperationStatus.NOTFOUND) { status = (Status)internalStatus; } else { status = HandleOperationStatus(ctx, pendingContext, internalStatus); } // If done, callback user code if (status == Status.OK || status == Status.NOTFOUND) { if (handleLatches) { ReleaseSharedLatch(pendingContext.key); } if (pendingContext.type == OperationType.READ) { Functions.ReadCompletionCallback(pendingContext.key, pendingContext.input, pendingContext.output, pendingContext.userContext, status); } else { Functions.RMWCompletionCallback(pendingContext.key, pendingContext.input, pendingContext.userContext, status); } } } }
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); } }