Exemple #1
0
        public bool Compress(Stream inputUncompressed, Stream outputCompressed, int compressionBlockSize = DefaultBlockSize)
        {
            var workBlocksCount = (int)(inputUncompressed.Length / compressionBlockSize);

            workBlocksCount += (inputUncompressed.Length % compressionBlockSize > 0) ? 1 : 0;
            var compressionWorkThreads = new List <Thread>();

            for (int i = 0; i < Environment.ProcessorCount; i += 1)
            {
                _buffers.Push(new byte[compressionBlockSize]);
            }

            using (var outputWriter = new BinaryWriter(outputCompressed))
            {
                outputWriter.Write(ArchiveMagic);
                outputWriter.Write(compressionBlockSize);
                outputWriter.Write(workBlocksCount);

                _runningThreads = 0;
                var    currentWorkBlock = 0;
                byte[] buf = null;
                while (currentWorkBlock <= workBlocksCount)
                {
                    if (_runningThreads >= Environment.ProcessorCount)
                    {
                        MaxReasonableThreadsIdle();
                        continue;
                    }

                    lock (_threadLock)
                    {
                        buf = _buffers.Pop();
                    }
                    var actualRead      = inputUncompressed.Read(buf, 0, compressionBlockSize);
                    var compressionWork = new Thread(ThreadCompressWork);
                    compressionWorkThreads.Add(compressionWork);
                    var compressionWorkData = new ThreadCompressWorkData(currentWorkBlock, buf, actualRead, outputWriter);
                    _runningThreads += 1;
                    compressionWork.Start(compressionWorkData);
                    currentWorkBlock += 1;
                }
                AwaitRemainingRunningThreads(compressionWorkThreads);
            }

            _buffers.Clear();
            return(true);
        }
Exemple #2
0
 private void GetCompressedBlockData(ThreadCompressWorkData workData, MemoryStream compressedBlockOutput)
 {
     using (MemoryStream compressedOutput = new MemoryStream())
     {
         using (GZipStream compressionStream = new GZipStream(compressedOutput, CompressionLevel.Optimal, leaveOpen: true))
         {
             compressionStream.Write(workData.DataForCompression, 0, workData.DataSize);
         }
         int compressedDataLength = (int)compressedOutput.Length;
         using (var binaryWriter = new BinaryWriter(compressedBlockOutput, System.Text.Encoding.Default, leaveOpen: true))
         {
             binaryWriter.Write(workData.BlockIndex);
             binaryWriter.Write(compressedDataLength);
             compressedOutput.Seek(0, SeekOrigin.Begin);
             compressedOutput.CopyTo(binaryWriter.BaseStream);
         }
     }
 }