Esempio n. 1
0
        private static void WalkBlocks(
            Stream stream,
            SemaphoreSlim?blockActionSemaphore,
            bool multipleBlocksInParallel,
            SingleBlockBlobCallback singleBlockCallback,
            MultipleBlockBlobCallback multipleBlockCallback,
            MultipleBlockBlobSealCallback multipleBlockSealCallback,
            long bytesToReadFromStream = -1)
        {
            bytesToReadFromStream = (bytesToReadFromStream >= 0) ? bytesToReadFromStream : (stream.Length - stream.Position);
            bool isSingleBlockBlob = bytesToReadFromStream <= BlockSize;

            if (isSingleBlockBlob)
            {
                WalkSingleBlockBlob(stream, blockActionSemaphore, singleBlockCallback, bytesToReadFromStream);
            }
            else
            {
                WalkMultiBlockBlob(stream, blockActionSemaphore, multipleBlocksInParallel, multipleBlockCallback, multipleBlockSealCallback, bytesToReadFromStream);
            }
        }
Esempio n. 2
0
        private static void WalkMultiBlockBlob(
            Stream stream,
            SemaphoreSlim?blockActionSemaphore,
            bool multiBlocksInParallel,
            MultipleBlockBlobCallback multipleBlockCallback,
            MultipleBlockBlobSealCallback multipleBlockSealCallback,
            long bytesLeftInBlob)
        {
            var rollingId = new RollingBlobIdentifierWithBlocks();
            BlobIdentifierWithBlocks?blobIdentifierWithBlocks = null;

            Lazy <List <Task> > tasks = new Lazy <List <Task> >(() => new List <Task>());

            do
            {
                ReadBlock(
                    stream,
                    blockActionSemaphore,
                    bytesLeftInBlob,
                    (blockBufferHandle, blockLength, blockHash) =>
                {
                    bytesLeftInBlob  -= blockLength;
                    bool isFinalBlock = bytesLeftInBlob == 0;

                    try
                    {
                        if (isFinalBlock)
                        {
                            blobIdentifierWithBlocks = rollingId.Finalize(blockHash);
                        }
                        else
                        {
                            rollingId.Update(blockHash);
                        }
                    }
                    catch
                    {
                        CleanupBufferAndSemaphore(blockBufferHandle, blockActionSemaphore);
                        throw;
                    }

                    if (multiBlocksInParallel)
                    {
                        tasks.Value.Add(Task.Run(() =>
                        {
                            try
                            {
                                multipleBlockCallback(blockBufferHandle.Value, blockLength, blockHash, isFinalBlock);
                            }
                            finally
                            {
                                CleanupBufferAndSemaphore(blockBufferHandle, blockActionSemaphore);
                            }
                        }));
                    }
                    else
                    {
                        try
                        {
                            multipleBlockCallback(blockBufferHandle.Value, blockLength, blockHash, isFinalBlock);
                        }
                        finally
                        {
                            CleanupBufferAndSemaphore(blockBufferHandle, blockActionSemaphore);
                        }
                    }
                });
            }while (bytesLeftInBlob > 0);

            if (tasks.IsValueCreated)
            {
                Task.WaitAll(tasks.Value.ToArray());
            }

            multipleBlockSealCallback(blobIdentifierWithBlocks);
        }