void TryWriteAsync(BlobEntry blobEntry, IntPtr sourceAddress, ulong destinationAddress, uint numBytesToWrite, DeviceIOCompletionCallback callback, object context) { // If pageBlob is null, it is being created. Attempt to queue the write for the creator to complete after it is done if (blobEntry.PageBlob == null && blobEntry.TryQueueAction(p => this.WriteToBlobAsync(p, sourceAddress, destinationAddress, numBytesToWrite, callback, context))) { return; } // Otherwise, invoke directly. this.WriteToBlobAsync(blobEntry.PageBlob, sourceAddress, destinationAddress, numBytesToWrite, callback, context); }
/// <summary> /// <see cref="IDevice.WriteAsync(IntPtr, int, ulong, uint, DeviceIOCompletionCallback, object)">Inherited</see> /// </summary> public override void WriteAsync(IntPtr sourceAddress, int segmentId, ulong destinationAddress, uint numBytesToWrite, DeviceIOCompletionCallback callback, object context) { this.BlobManager?.StorageTracer?.FasterStorageProgress($"AzureStorageDevice.WriteAsync Called segmentId={segmentId} destinationAddress={destinationAddress} numBytesToWrite={numBytesToWrite}"); if (!this.blobs.TryGetValue(segmentId, out BlobEntry blobEntry)) { BlobEntry entry = new BlobEntry(this); if (this.blobs.TryAdd(segmentId, entry)) { CloudPageBlob pageBlob = this.pageBlobDirectory.GetPageBlobReference(this.GetSegmentBlobName(segmentId)); // If segment size is -1 we use a default var size = this.segmentSize == -1 ? AzureStorageDevice.MAX_PAGEBLOB_SIZE : this.segmentSize; // If no blob exists for the segment, we must first create the segment asynchronouly. (Create call takes ~70 ms by measurement) // After creation is done, we can call write. _ = entry.CreateAsync(size, pageBlob); } // Otherwise, some other thread beat us to it. Okay to use their blobs. blobEntry = this.blobs[segmentId]; } this.TryWriteAsync(blobEntry, sourceAddress, destinationAddress, numBytesToWrite, callback, context); }