Пример #1
0
 private void WriteBlock(CompressionBlock block)
 {
     lock (_blocksToWrite)
     {
         _blocksToWrite.Enqueue(block);
         _onWriteQueryAddedEvent.Set();
     }
 }
Пример #2
0
        private void Decompress(CompressionBlock currentBlock)
        {
            if (_parallelDecompression)
            {
                using (var memoryStream = new MemoryStream(_bufferSize))
                {
                    using (var gzipStream = new GZipStream(
                               new MemoryStream(currentBlock.Data),
                               _compressionMode))
                    {
                        byte[] decompressedData = new byte[_bufferSize];

                        int nRead;
                        while ((nRead = gzipStream.Read(decompressedData, 0, decompressedData.Length)) > 0)
                        {
                            memoryStream.Write(decompressedData, 0, nRead);
                        }
                    }

                    _processedIndex = currentBlock.BlockIndex;
                    WriteBlock(new CompressionBlock(_processedIndex, memoryStream.ToArray()));
                }
            }
            else
            {
                if (_decompressionStream == null)
                {
                    _memoryToDecompress = new MemoryStream(new byte[currentBlock.Data.Length]);

                    _decompressionStream = new GZipStream(_memoryToDecompress, _compressionMode);
                }

                _memoryToDecompress.Write(currentBlock.Data, 0, currentBlock.Data.Length);
                _memoryToDecompress.Seek(0, SeekOrigin.Begin);


                while (true)
                {
                    if (_blocksToWrite.Count > _blockCacheSize)
                    {
                        _onWrittenEvent.WaitOne(SyncWaitMs);
                        continue;
                    }

                    byte[] decompressedData = new byte[_bufferSize];
                    int    nRead            = _decompressionStream.Read(decompressedData, 0, decompressedData.Length);
                    if (nRead == 0)
                    {
                        break;
                    }

                    WriteBlock(new CompressionBlock(_processedIndex, decompressedData, nRead));
                    _processedIndex++;
                }

                _memoryToDecompress.Position = 0;
            }
        }
Пример #3
0
        private void WriteWorker(Object streamObject)
        {
            Stream stream = streamObject as Stream;

            while (_blocksToWrite.Count > 0 || _compressionThreads.Any(t => t.IsAlive))
            {
                CompressionBlock block = null;
                lock (_blocksToWrite)
                {
                    if (_blocksToWrite.Any())
                    {
                        block = _blocksToWrite.Dequeue();
                    }
                }

                if (block != null)
                {
                    if (block.BlockIndex - _currentProcessedBlock == 1)
                    {
                        stream.Write(block.Data, 0, block.EffectiveSize);
                        _onWrittenEvent.Set();
                        _currentProcessedBlock++;
                    }
                    else
                    {
                        _blocks.Add(block.BlockIndex, block);
                    }
                }

                while (_blocks.ContainsKey(_currentProcessedBlock + 1))
                {
                    CompressionBlock currentBlock = _blocks[_currentProcessedBlock + 1];
                    _blocks.Remove(_currentProcessedBlock + 1);
                    stream.Write(currentBlock.Data, 0, currentBlock.EffectiveSize);
                    _onWrittenEvent.Set();
                    _currentProcessedBlock++;
                }

                if (block == null)
                {
                    _onWriteQueryAddedEvent.WaitOne(SyncWaitMs);
                }
            }
        }
Пример #4
0
        private void Compress(CompressionBlock block)
        {
            using (var memoryStream = new MemoryStream(_bufferSize))
            {
                using (var gzipStream = new GZipStream(memoryStream, _compressionMode))
                {
                    gzipStream.Write(block.Data, 0, block.EffectiveSize);
                }

                byte[]     data       = memoryStream.ToArray();
                GZipHeader gZipHeader = new GZipHeader(data);

                int initialHeaderSize = gZipHeader.Header.Length;

                int size = 0;
                // Добавляем поле с размером.
                gZipHeader.SetExtra(
                    CompressedBlocksProvider.VeeamArchiverSI1,
                    CompressedBlocksProvider.VeeamArchiverSI2,
                    BitConverter.GetBytes(size));

                // Устанавливаем конечный размер блока.
                size = (int)(gZipHeader.Header.Length + data.Length - initialHeaderSize);

                gZipHeader.SetExtra(
                    CompressedBlocksProvider.VeeamArchiverSI1,
                    CompressedBlocksProvider.VeeamArchiverSI2,
                    BitConverter.GetBytes(size));

                byte[] resultBlock = new byte[size];
                Array.Copy(gZipHeader.Header, resultBlock, gZipHeader.Header.Length);
                Array.Copy(data, initialHeaderSize, resultBlock, gZipHeader.Header.Length, data.Length - initialHeaderSize);

                _processedIndex = block.BlockIndex;
                WriteBlock(new CompressionBlock(_processedIndex, resultBlock));
            }
        }
Пример #5
0
        private void CompressionWorker(Object stream)
        {
            while (_readerThread.IsAlive || _readBlocks.Count > 0)
            {
                if (_blocksToWrite.Count > _blockCacheSize)
                {
                    _onWrittenEvent.WaitOne(SyncWaitMs);
                    continue;
                }

                CompressionBlock currentBlock = ReadBlock();

                if (currentBlock == null)
                {
                    if (_readerThread.IsAlive)
                    {
                        _onReadEvent.WaitOne(SyncWaitMs);
                    }

                    continue;
                }

                if (currentBlock.BlockIndex == 0)
                {
                    int desiredThreadsCount = 1;

                    _parallelDecompression = false;
                    if (_compressionMode == CompressionMode.Compress)
                    {
                        desiredThreadsCount    = Environment.ProcessorCount;
                        _parallelDecompression = true;
                    }
                    else
                    {
                        try
                        {
                            GZipHeader header   = new GZipHeader(currentBlock.Data);
                            byte[]     sizeData = header.GetExtra(
                                CompressedBlocksProvider.VeeamArchiverSI1,
                                CompressedBlocksProvider.VeeamArchiverSI2);
                            if (sizeData != null && BitConverter.ToInt32(sizeData, 0) > 0)
                            {
                                desiredThreadsCount    = Environment.ProcessorCount;
                                _parallelDecompression = true;
                            }
                        }
                        catch (Exception ex)
                        {
                            RaiseErrorOccured(ex);
                        }
                    }

                    for (int i = 0; i < desiredThreadsCount - 1; i++)
                    {
                        var thread = new Thread(new ParameterizedThreadStart(CompressionWorker));
                        _compressionThreads.Add(thread);
                        thread.Start();
                    }
                }

                try
                {
                    if (_compressionMode == CompressionMode.Compress)
                    {
                        Compress(currentBlock);
                    }
                    else
                    {
                        Decompress(currentBlock);
                    }
                }
                catch (Exception ex)
                {
                    RaiseErrorOccured(ex);
                }
            }

            if (_decompressionStream != null)
            {
                _decompressionStream.Dispose();
            }

            if (_memoryToDecompress != null)
            {
                _memoryToDecompress.Dispose();
            }
        }