示例#1
0
 static VsoHash()
 {
     using (var emptyStream = new MemoryStream())
     {
         OfNothing = CalculateBlobIdentifierWithBlocks(emptyStream);
     }
 }
示例#2
0
文件: VsoHash.cs 项目: socat/BuildXL
        public static async Task <BlobIdentifierWithBlocks> CalculateBlobIdentifierWithBlocksAsync(Stream stream)
        {
            BlobIdentifierWithBlocks result = null;

            await WalkBlocksAsync(
                stream,
                blockActionSemaphore : null,
                multipleBlocksInParallel : false,
                singleBlockCallback : (block, blockLength, blobIdWithBlocks) =>
            {
                result = blobIdWithBlocks;
                return(Task.FromResult(0));
            },
                multipleBlockCallback : (block, blockLength, blockHash, isFinalBlock) => Task.FromResult(0),
                multipleBlockSealCallback : blobIdWithBlocks =>
            {
                result = blobIdWithBlocks;
                return(Task.FromResult(0));
            }).ConfigureAwait(false);

            if (result == null)
            {
                throw new InvalidOperationException($"Program error: {nameof(CalculateBlobIdentifierWithBlocksAsync)} did not calculate a value.");
            }

            return(result);
        }
示例#3
0
文件: VsoHash.cs 项目: socat/BuildXL
        public static BlobIdentifierWithBlocks CalculateBlobIdentifierWithBlocks(Stream stream)
        {
            BlobIdentifierWithBlocks result = null;

            WalkBlocks(
                stream,
                blockActionSemaphore: null,
                multipleBlocksInParallel: false,
                singleBlockCallback: (block, blockLength, blobIdWithBlocks) =>
            {
                result = blobIdWithBlocks;
            },
                multipleBlockCallback: (block, blockLength, blockHash, isFinalBlock) =>
            {
            },
                multipleBlockSealCallback: blobIdWithBlocks =>
            {
                result = blobIdWithBlocks;
            });

            if (result == null)
            {
                throw new InvalidOperationException("Program error: did not calculate a value.");
            }

            return(result);
        }
示例#4
0
文件: VsoHash.cs 项目: socat/BuildXL
        public static async Task <BlobIdentifierWithBlocks> WalkAllBlobBlocksAsync(
            Stream stream,
            SemaphoreSlim blockActionSemaphore,
            bool multipleBlocksInParallel,
            MultipleBlockBlobCallbackAsync multipleBlockCallback,
            long?bytesToReadFromStream = null)
        {
            bytesToReadFromStream = bytesToReadFromStream ?? (stream.Length - stream.Position);
            BlobIdentifierWithBlocks blobIdWithBlocks = default(BlobIdentifierWithBlocks);

            await WalkMultiBlockBlobAsync(
                stream,
                blockActionSemaphore,
                multipleBlocksInParallel,
                multipleBlockCallback,
                computedBlobIdWithBlocks =>
            {
                blobIdWithBlocks = computedBlobIdWithBlocks;
                return(Task.FromResult(0));
            },
                bytesToReadFromStream.GetValueOrDefault()).ConfigureAwait(false);

            return(blobIdWithBlocks);
        }
示例#5
0
文件: VsoHash.cs 项目: socat/BuildXL
        private static async Task WalkMultiBlockBlobAsync(
            Stream stream,
            SemaphoreSlim blockActionSemaphore,
            bool multiBlocksInParallel,
            MultipleBlockBlobCallbackAsync multipleBlockCallback,
            MultipleBlockBlobSealCallbackAsync multipleBlockSealCallback,
            long bytesLeftInBlob)
        {
            var rollingId = new RollingBlobIdentifierWithBlocks();
            BlobIdentifierWithBlocks blobIdentifierWithBlocks = null;

            var tasks = new List <Task>();

            do
            {
                await ReadBlockAsync(
                    stream,
                    blockActionSemaphore,
                    bytesLeftInBlob,
                    async (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;
                    }

                    Task multiBlockTask = Task.Run(async() =>
                    {
                        try
                        {
                            await multipleBlockCallback(blockBufferHandle.Value, blockLength, blockHash, isFinalBlock).ConfigureAwait(false);
                        }
                        finally
                        {
                            CleanupBufferAndSemaphore(blockBufferHandle, blockActionSemaphore);
                        }
                    });
                    tasks.Add(multiBlockTask);

                    if (!multiBlocksInParallel)
                    {
                        await multiBlockTask.ConfigureAwait(false);
                    }
                }).ConfigureAwait(false);
            }while (bytesLeftInBlob > 0);

            await Task.WhenAll(tasks).ConfigureAwait(false);

            await multipleBlockSealCallback(blobIdentifierWithBlocks).ConfigureAwait(false);
        }
示例#6
0
文件: VsoHash.cs 项目: socat/BuildXL
        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);
        }