// We await input of format GZipTest.exe compress/decompress FromFile ToFile private static void Main(string[] args) { if (!ParseInput(args)) { Console.ReadLine(); return; } // Let's figure out technical parameters ComputerInfo CI = new ComputerInfo(); ulong mem = CI.AvailablePhysicalMemory; ulong vmem = CI.AvailableVirtualMemory; int cpuCount = Environment.ProcessorCount; _maxThreads = cpuCount; _maxInputChunks = Convert.ToInt32((mem * 0.45) / (_chunkSize)); _maxOutputChunks = _maxInputChunks; // Seems like all input was correct, let's continue with actual work DateTime start = DateTime.Now; Console.WriteLine($"{_mode.ToString()}ing using {_maxThreads} threads and {_maxInputChunks} chunks per dictionary"); var inputDictionary = new MySafeDictionary <int, byte[]>(); var outputDictionary = new MySafeDictionary <int, byte[]>(); var myCompressor = new Compressor(inputDictionary, outputDictionary, _maxThreads, _maxOutputChunks, _mode); var myReader = new FileReader(from, inputDictionary, _maxInputChunks, _chunkSize, _mode == CompressionMode.Compress ? false : true); var myWriter = new FileWriter(to, outputDictionary); Thread readThread = new Thread(myReader.ReadAsync); Thread writeThread = new Thread(myWriter.Write); readThread.Start(); writeThread.Start(); myCompressor.LaunchThreads(); // Ok the work is being done. The first thing we should do is wait for the readThread to be done. The write thread might come down any minute if it runs out of space too while (readThread.IsAlive && writeThread.IsAlive) { // Console.WriteLine($"read = {myReader.ChunksRead}, inputcount = {inputDictionary.Count}, outputcount = {outputDictionary.Count}, written = {myWriter.ChunksWritten}"); Thread.Sleep(100); } while (myWriter.ChunksWritten < myReader.ChunksRead && writeThread.IsAlive) { // Console.WriteLine($"Reading all done. read = {myReader.ChunksRead}, inputcount = {inputDictionary.Count}, outputcount = {outputDictionary.Count}, written = {myWriter.ChunksWritten}"); Thread.Sleep(100); } myCompressor.StopThreads(); if (!writeThread.IsAlive) { Console.ReadLine(); return; } writeThread.Abort(); long startSize = new FileInfo(from).Length; long endSize = new FileInfo(to).Length; Console.WriteLine($"{_mode.ToString()}ed {startSize} Bytes ({(startSize / (1024 * 1024)):N2} MB) into {endSize} Bytes ({(endSize / (1024 * 1024)):N2} MB) in {DateTime.Now.Subtract(start).TotalMilliseconds:N0} milliseconds ({(DateTime.Now.Subtract(start).TotalMilliseconds / (60 * 1000)):N2} minutes)"); Console.ReadLine(); }
/// <summary> /// <para>Конструктор. Возвращает экземпляр <see cref="T:GZipTest.GZipModifier"/></para> /// <para>Принимает:</para> <para><paramref name="gZipStreamCommand"></paramref> - /// режим работы <see cref="T:System.IO.Compression.GZipStream"/> /// (<paramref name="gZipStreamCommand"></paramref>)</para> /// <para>полное имя (<paramref name="fileToReadPath"></paramref>) читаемого файла</para> /// <para>полное имя (<paramref name="fileToWritePath"></paramref>) записываемого файла</para> /// </summary> #region constructor public GZipModifier(CompressionMode gZipStreamCommand, string fileToReadPath, string fileToWritePath) { threadsNumber = Environment.ProcessorCount; threadPool = new Thread[threadsNumber]; this.gZipStreamCommand = gZipStreamCommand; this.fileToReadPath = fileToReadPath; this.fileToWritePath = fileToWritePath; args = new string[] { gZipStreamCommand.ToString(), fileToReadPath, fileToWritePath }; fileModifier = ModifierFactory.Create(gZipStreamCommand); readQueue = new LimitedSizeBlocksQueue(threadsNumber); writeBuffer = new ConcurrentDictionary <int, Block>(); countdown = new CountdownEvent(threadsNumber + 1); canAddBlockToBuffer = true; allBlocksWriten = false; blocksReaded = 0; }