Exemple #1
0
        private Result <int, ErrorCodes?> MultyThreadedDecompression(Stream inputStream, Stream outputStream)
        {
            using (var writerFinished = new ManualResetEvent(false))
                using (var workersPool = new WorkersPool.WorkersPool(settings.ThreadsCount, log))
                    using (var tasksQueue = new BlockingTasksQueue(settings.CompressingQueueSize, workersPool, log))
                    {
                        var outputFile = new OutputFileWithoutOffsetStore(outputStream);
                        var blockId    = 0;

                        var writeDecompressedTask =
                            RunDequeueingOutputWriteDecompressedBlocks(writerFinished, outputFile, tasksQueue);
                        workersPool.PushTask(writeDecompressedTask);

                        var needWaitTasksFinished             = false;
                        var needEndTasks                      = true;
                        StreamingGzipBlock streamingGzipBlock = null;
                        try
                        {
                            foreach (var block in gzipBlockSplitter.SplitBlocks(inputStream))
                            {
                                if (block is StreamingGzipBlock gzipBlock)
                                {
                                    tasksQueue.EndTasks();
                                    needEndTasks = false;
                                    if (needWaitTasksFinished)
                                    {
                                        writerFinished.WaitOne();
                                        needWaitTasksFinished = false;
                                    }

                                    streamingGzipBlock = gzipBlock;
                                    break;
                                }

                                tasksQueue.EnqueueTask(
                                    new DelegateTask(
                                        blockId++.ToString(),
                                        () => ((IndependentGzipBlock)block).Decompress())
                                    );
                                needWaitTasksFinished = true;
                            }
                        }
                        finally
                        {
                            if (needEndTasks)
                            {
                                tasksQueue.EndTasks();
                            }
                        }

                        if (needWaitTasksFinished)
                        {
                            writerFinished.WaitOne();
                        }

                        streamingGzipBlock?.WriteDecompressedDataTo(outputStream);

                        return(outputFile.CompressionRatio(inputStream.Length));
                    }
        }
Exemple #2
0
        private static IWorkerTask RunDequeueingOutputWriteDecompressedBlocks(
            ManualResetEvent writerFinished,
            OutputFileWithoutOffsetStore outputFile,
            BlockingTasksQueue tasksQueue)
        {
            return(new DelegateWorkerTask(
                       "Writer",
                       () =>
            {
                var error = WriteCompressedBlocks();
                if (error != null)
                {
                    throw new CompressorException(error.Value);
                }
            }));

            ErrorCodes?WriteCompressedBlocks()
            {
                try
                {
                    foreach (var result in tasksQueue.ConsumeTaskResults())
                    {
                        if (result.IsFailed)
                        {
                            if (result.Exception is CompressorException fileSystemException)
                            {
                                return(fileSystemException.Error);
                            }
                            throw result.Exception;
                        }

                        var decompressedBlock = (byte[])result.Result;
                        var error             = outputFile.Append(decompressedBlock.ToSegment());
                        if (error != null)
                        {
                            return(error.Value);
                        }
                    }

                    return(null);
                }
                finally
                {
                    writerFinished.Set();
                }
            }
        }