Beispiel #1
0
        protected async Task <InternalPageBlobSizeInfo> PreparePageBlobAsync(CloudPageBlob pageBlob,
                                                                             int sourceBufferByteCountToWrite, CancellationToken cancellationToken)
        {
            EnsureBlobExistsResult result = await this.EnsureBlobExistsAsync(pageBlob, byteCountToWrite : sourceBufferByteCountToWrite);

            InternalPageBlobSizeInfo sizeInfo;

            switch (result)
            {
            case EnsureBlobExistsResult.Created:
                sizeInfo = new InternalPageBlobSizeInfo();
                break;

            case EnsureBlobExistsResult.AlreadyExisted:
                sizeInfo = await this.ResizePageBlobIfNeededAsync(pageBlob, sourceBufferByteCountToWrite,
                                                                  cancellationToken);

                break;

            default:
                throw new NotSupportedException($"Unrecognized enum value ({result}) returned from the method {nameof(this.EnsureBlobExistsAsync)}.");
            }

            return(sizeInfo);
        }
Beispiel #2
0
        protected async Task <InternalPageBlobSizeInfo> ResizePageBlobIfNeededAsync(CloudPageBlob pageBlob,
                                                                                    int sourceBufferByteCountToWrite, CancellationToken cancellationToken)
        {
            BlobProperties blobProperties = await this.GetPropertiesAsync(pageBlob, cancellationToken);

            int offsetOfLastPage = CalculateOffsetOfLastPage((int)blobProperties.Length);

            byte[] usedBytesFromLastPage =
                await this.GetUsedBytesWrittenToLastPageAsync(pageBlob, offsetOfLastPage, cancellationToken);

            var sizeInfo = new InternalPageBlobSizeInfo(offsetOfLastPage, usedBytesFromLastPage);

            int currentTotalBytesUsed =
                CalculateTotalBytesUsed((int)blobProperties.Length, usedBytesFromLastPage.Length);

            await this.ResizePageBlobIfNeededAsync(pageBlob, (int)blobProperties.Length, currentTotalBytesUsed,
                                                   sourceBufferByteCountToWrite, cancellationToken);

            return(sizeInfo);
        }
Beispiel #3
0
        internal async Task <BlobSegmentInfo> AppendImplAsync(Stream sourceStreamToWrite, CancellationToken?cancellationToken = null, Func <Task> concurrencyTestFunc = null)
        {
            if (cancellationToken == null)
            {
                cancellationToken = CancellationToken.None;
            }

            this.EnsureInitialized();

            CloudPageBlob pageBlob = this.BlobContainer.GetPageBlobReference(this.BlobPath);

            // Note: We only force the use of a buffer here if the stream that is passed cannot seek. We need the
            //       length to fill out the page with null characters, so it must support seeking unless we find a
            //       different algorithm.
            if (!sourceStreamToWrite.CanSeek)
            {
                sourceStreamToWrite =
                    await BuildMemoryStreamThatCanSeekAsync(sourceStreamToWrite, cancellationToken.Value);
            }

            InternalPageBlobSizeInfo pageBlobSizeInfo = await this.PreparePageBlobAsync(pageBlob,
                                                                                        (int)sourceStreamToWrite.Length, cancellationToken.Value);

            Stream streamToWrite = BuildStreamOfPagesToWrite(sourceStreamToWrite, pageBlobSizeInfo);

            int byteOffset   = pageBlobSizeInfo.OffsetOfLastPage + pageBlobSizeInfo.UsedBytesFromLastPage.Length;
            int streamLength = (int)sourceStreamToWrite.Length;

            if (concurrencyTestFunc != null)
            {
                await concurrencyTestFunc();
            }

            await pageBlob.WritePagesAsync(streamToWrite, pageBlobSizeInfo.OffsetOfLastPage, null,
                                           CreateAccessCondition(pageBlob), this.RequestOptions, this.OperationContext, cancellationToken.Value);

            return(new BlobSegmentInfo(byteOffset, streamLength));
        }
Beispiel #4
0
        protected static Stream BuildStreamOfPagesToWrite(Stream sourceStreamToWrite, InternalPageBlobSizeInfo sizeInfo)
        {
            int updatedUsedByteCount           = sizeInfo.UsedBytesFromLastPage.Length + (int)sourceStreamToWrite.Length;
            int updatedUsedToFullPageByteCount = CalculateBlobLengthThroughEndOfPage(updatedUsedByteCount);

            var streamForPreviouslyUsedBytes = new MemoryStream(sizeInfo.UsedBytesFromLastPage, false);

            if (updatedUsedByteCount == updatedUsedToFullPageByteCount)
            {
                return(new ConcatenatedStream(new[] { streamForPreviouslyUsedBytes, sourceStreamToWrite }));
            }

            var streamToFillOutLastPage = new MemoryStream(FullPageOfNullChars, 0,
                                                           (int)(updatedUsedToFullPageByteCount - updatedUsedByteCount));

            return(new ConcatenatedStream(new[] { streamForPreviouslyUsedBytes, sourceStreamToWrite, streamToFillOutLastPage }));
        }