public void Execute(OperationParameters parameters) { var inputStream = File.OpenRead(parameters.InputFileName); var outputStream = File.Create(parameters.OutputFileName); blockStreamWriter.Initialize(outputStream); int inputBlockSize = parameters.InputBlockSize; int blocksCount = (int)(inputStream.Length / inputBlockSize) + (inputStream.Length % inputBlockSize == 0 ? 0 : 1); int lastInputBlockSize = (int)(inputStream.Length - inputBlockSize * (blocksCount - 1)); bufferPool.Initialize(Math.Min(threadPool.WorkersCount, blocksCount) * 3, inputBlockSize); logger.Debug($"{nameof(CompressOperationExecutor)}. Number of blocks {blocksCount}"); outputStream.Write(BitConverter.GetBytes(inputStream.Length)); outputStream.Write(BitConverter.GetBytes(inputBlockSize)); for (int blockNumber = 0; blockNumber < blocksCount; blockNumber++) { var inputBlock = bufferPool.Take(); int currentInputBlockSize = blockNumber == blocksCount - 1 ? lastInputBlockSize : inputBlockSize; inputBlock.FillFrom(inputStream, currentInputBlockSize); var outputBlock = bufferPool.Take(); int number = blockNumber; threadPool.Enqueue(() => CompressBlock(inputBlock, number, outputBlock)); } inputStream.Close(); threadPool.Wait(); blockStreamWriter.Wait(blocksCount); outputStream.Close(); }
public void Execute(OperationParameters parameters) { var inputStream = File.OpenRead(parameters.InputFileName); var inputStreamReader = new BinaryReader(inputStream); long dataSize = inputStreamReader.ReadInt64(); int outputBlockSize = inputStreamReader.ReadInt32(); int blocksCount = (int)(dataSize / outputBlockSize) + (dataSize % outputBlockSize == 0 ? 0 : 1); int lastOutputBlockSize = (int)(dataSize - outputBlockSize * (blocksCount - 1)); logger.Debug($"{nameof(DecompressOperationExecutor)}. Number of blocks {blocksCount}"); var outputStream = File.Create(parameters.OutputFileName); blockStreamWriter.Initialize(outputStream); bufferPool.Initialize(Math.Min(threadPool.WorkersCount, blocksCount) * 3, outputBlockSize); for (int blockNumber = 0; blockNumber < blocksCount; blockNumber++) { var inputBlock = bufferPool.Take(); int inputBlockSize = inputStreamReader.ReadInt32(); inputBlock.FillFrom(inputStream, inputBlockSize); var outputBlock = bufferPool.Take(); int currentOutputBlockSize = blockNumber == blocksCount - 1 ? lastOutputBlockSize : outputBlockSize; int number = blockNumber; threadPool.Enqueue(() => DecompressBlock(inputBlock, number, outputBlock, currentOutputBlockSize)); logger.Debug($"{nameof(DecompressOperationExecutor)}. Block {number}: input size {inputBlockSize}, output size {outputBlockSize}"); } inputStream.Close(); threadPool.Wait(); blockStreamWriter.Wait(blocksCount); var resultDataSize = outputStream.Length; outputStream.Close(); if (dataSize != resultDataSize) { throw new InvalidDataException($"Decompressed data size is {resultDataSize}, but expected {dataSize}"); } }