예제 #1
0
        public async Task DownloadFile(string virtualPath, string systemPath, bool lowPriority = false)
        {
            var size = await GetFileSize(virtualPath).ConfigureAwait(false);

            long position = 0;

            if (size < 0)
            {
                throw new FileNotFoundException($"There is no {virtualPath} on the server");
            }

            using (lowPriority ? ThreadUtility.EnterBackgroundProcessingMode() : null)
                using (var fs = File.OpenWrite(systemPath))
                {
                    while (position < size)
                    {
                        var chunkLength = (int)Math.Min(1024 * 1024, size - position);
                        using (var bytes = await DownloadSegment(virtualPath, position, chunkLength).ConfigureAwait(false))
                        {
                            if (bytes.Object == null)
                            {
                                throw new IOException();
                            }

                            await fs.WriteAsync(bytes.Object, 0, chunkLength).ConfigureAwait(false);
                        }

                        position += chunkLength;
                    }
                }
        }
예제 #2
0
        private static byte[][] ReadLeafs(HashAlgorithm tg, string filePath, long start, long end)
        {
            using (ThreadUtility.EnterBackgroundProcessingMode())
                using (var threadFilePtr = FileStreamFactory.CreateFileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 128 * 1024))
                {
                    var threadFileBlock = new FileBlock(start, end);
                    var LeafSize        = 1024;
                    var DataBlockSize   = LeafSize * 1024;
                    var data            = new byte[LeafSize + 1];

                    var totalLeafs = threadFileBlock.Length / LeafSize + threadFileBlock.Length % LeafSize > 0 ? 1 : 0;

                    var result = new byte[totalLeafs][];

                    threadFilePtr.Position = threadFileBlock.Start;

                    while (threadFilePtr.Position < threadFileBlock.End)
                    {
                        var leafIndex = (int)((threadFilePtr.Position - start) / 1024);

                        var dataBlock = new byte[Math.Min(threadFileBlock.End - threadFilePtr.Position, DataBlockSize)];

                        threadFilePtr.Read(dataBlock, 0, dataBlock.Length); //read block

                        var blockLeafs = dataBlock.Length / LeafSize;

                        int i;
                        for (i = 0; i < blockLeafs; i++)
                        {
                            Buffer.BlockCopy(dataBlock, i * LeafSize, data, 1, LeafSize);

                            tg.Initialize();
                            result[leafIndex++] = tg.ComputeHash(data);
                        }

                        if (i * LeafSize < dataBlock.Length)
                        {
                            data    = new byte[dataBlock.Length - blockLeafs * LeafSize + 1];
                            data[0] = LeafHash;

                            Buffer.BlockCopy(dataBlock, blockLeafs * LeafSize, data, 1, (data.Length - 1));

                            tg.Initialize();
                            result[leafIndex] = tg.ComputeHash(data);

                            data    = new byte[LeafSize + 1];
                            data[0] = LeafHash;
                        }
                    }
                    return(result);
                }
        }
예제 #3
0
        void ProcessLeafs(object threadId)
        {
            using (LowPriority ? ThreadUtility.EnterBackgroundProcessingMode() : null)
                using (var threadFilePtr = FileStreamFactory.CreateFileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.Read, FileStreamBufferLength))
                {
                    var threadFileBlock = _fileParts[(int)threadId];
                    var tg   = new T();
                    var data = new byte[LeafSize + 1];

                    threadFilePtr.Position = threadFileBlock.Start;

                    var dataBlock = new byte[DataBlockSize];

                    while (threadFilePtr.Position < threadFileBlock.End)
                    {
                        var leafIndex = (int)(threadFilePtr.Position / 1024);

                        var dataBlockSize = (int)Math.Min(threadFileBlock.End - threadFilePtr.Position, DataBlockSize);

                        threadFilePtr.Read(dataBlock, 0, dataBlockSize); //read block

                        Interlocked.Add(ref _processedBytes, dataBlockSize);

                        var blockLeafs = dataBlockSize / 1024;

                        int i;
                        for (i = 0; i < blockLeafs; i++)
                        {
                            Buffer.BlockCopy(dataBlock, i * LeafSize, data, 1, LeafSize);

                            tg.Initialize();
                            TTH[0][leafIndex++] = tg.ComputeHash(data);
                        }

                        if (i * LeafSize < dataBlockSize)
                        {
                            data    = new byte[dataBlockSize - blockLeafs * LeafSize + 1];
                            data[0] = LeafHash;

                            Buffer.BlockCopy(dataBlock, blockLeafs * LeafSize, data, 1, (data.Length - 1));

                            tg.Initialize();
                            TTH[0][leafIndex] = tg.ComputeHash(data);

                            data    = new byte[LeafSize + 1];
                            data[0] = LeafHash;
                        }
                    }
                }
        }
예제 #4
0
        void CompressTree()
        {
            int level = 0;

            using (LowPriority ? ThreadUtility.EnterBackgroundProcessingMode() : null)
            {
                while (level + 1 < LevelCount)
                {
                    int leafIndex         = 0;
                    var internalLeafCount = (_leafCount / 2) + (_leafCount % 2);
                    TTH[level + 1] = new byte[internalLeafCount][];

                    if (!LowPriority && _leafCount > 128)
                    {
                        Parallel.For(0, _leafCount / 2,
                                     ind => ProcessInternalLeaf(level + 1, ind, TTH[level][ind * 2], TTH[level][ind * 2 + 1]));
                        leafIndex = _leafCount / 2;
                    }
                    else
                    {
                        for (var i = 1; i < _leafCount; i += 2)
                        {
                            ProcessInternalLeaf(level + 1, leafIndex++, TTH[level][i - 1], TTH[level][i]);
                        }
                    }

                    if (leafIndex < internalLeafCount)
                    {
                        TTH[level + 1][leafIndex] = TTH[level][_leafCount - 1];
                    }

                    level++;
                    _leafCount = internalLeafCount;
                }
            }
        }