/// <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) { Debug.WriteLine($"AzureStorageDevice.WriteAsync Called segmentId={segmentId} destinationAddress={destinationAddress} numBytesToWrite={numBytesToWrite}"); if (!blobs.TryGetValue(segmentId, out BlobEntry blobEntry)) { BlobEntry entry = new BlobEntry(this.BlobManager); if (blobs.TryAdd(segmentId, entry)) { CloudPageBlob pageBlob = this.blobDirectory.GetPageBlobReference(GetSegmentBlobName(segmentId)); // If segment size is -1, which denotes absence, we request the largest possible blob. This is okay because // page blobs are not backed by real pages on creation, and the given size is only a the physical limit of // how large it can grow to. var size = segmentSize == -1 ? MAX_BLOB_SIZE : 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. var _ = entry.CreateAsync(size, pageBlob); } // Otherwise, some other thread beat us to it. Okay to use their blobs. blobEntry = blobs[segmentId]; } this.TryWriteAsync(blobEntry, sourceAddress, destinationAddress, numBytesToWrite, callback, context); }
private 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); }
private void TryWriteAsync(BlobEntry blobEntry, IntPtr sourceAddress, ulong destinationAddress, uint numBytesToWrite, IOCompletionCallback callback, IAsyncResult asyncResult) { CloudPageBlob pageBlob = blobEntry.GetPageBlob(); // If pageBlob is null, it is being created. Attempt to queue the write for the creator to complete after it is done if (pageBlob == null && blobEntry.TryQueueAction(p => WriteToBlobAsync(p, sourceAddress, destinationAddress, numBytesToWrite, callback, asyncResult))) { return; } // Otherwise, invoke directly. WriteToBlobAsync(pageBlob, sourceAddress, destinationAddress, numBytesToWrite, callback, asyncResult); }
/// <summary> /// <see cref="IDevice.WriteAsync(IntPtr, int, ulong, uint, IOCompletionCallback, IAsyncResult)">Inherited</see> /// </summary> public override void WriteAsync(IntPtr sourceAddress, int segmentId, ulong destinationAddress, uint numBytesToWrite, IOCompletionCallback callback, IAsyncResult asyncResult) { if (!blobs.TryGetValue(segmentId, out BlobEntry blobEntry)) { BlobEntry entry = new BlobEntry(); if (blobs.TryAdd(segmentId, entry)) { CloudPageBlob pageBlob = container.GetPageBlobReference(blobName + segmentId); // If segment size is -1, which denotes absence, we request the largest possible blob. This is okay because // page blobs are not backed by real pages on creation, and the given size is only a the physical limit of // how large it can grow to. var size = segmentSize == -1 ? MAX_BLOB_SIZE : 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 = blobs[segmentId]; } TryWriteAsync(blobEntry, sourceAddress, destinationAddress, numBytesToWrite, callback, asyncResult); }