Skip to content

nardin/gzip

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Gzip

Update 1

Добавлена распарельная распаковка.

Стандартный формат gzip трудно паралелится. Поэтому изменен для себя:

  1. В заголовке 6 бит 4 байта установлен в 1. Это зарезервированный бит и должен приводить к тому что другие архиваторы не испрользуют и при устновке определяют архив как невалидный.
  2. 5-8 байт содержат длину заархивированого блока с заголовком.

Для совместимости добавлена опция "compatibility". При установки создается gzip архив соответствующий стандарту. Для распаковки, определяется тип архива. Для архивов соответсвующих стандарту используется потоковый однопоточный режим как наиболее эффективный, но требуется .NET Core 3.0 или позднее.

Решение.

Входной поток разбивается на куски каждый из которых сжимается отдельно (имеет заголовок, тело и CRC) и записывается в итоговый файл друг за другом. Итоговый формат полностью совместим со стандартом gzip и может быть распакован напрмер 7Zip.

Организовывается pipeline:

workFlow
    .Step(new FileReadWorker(inFileStream, chunkSizeBytes))
        .Pipe<BlockingPipe<FileChunk>>(size)
    .Step<CompressWorker>(size)
        .Pipe<OrderingPipe>(size)
    .Step(new GzipWriteFileWorker(outFileStream))

Каждый Worker запускается в отдельном потоке. Потоки для сжатия запускается по количеству ядер процессора.

Для сихронизации потоков используются конкурентные коллекции (аля BlockingCollection) которые используются как Pip. Pip-ы ограничены по размеру, чтобы избежать излишнего потребления памяти при их забивании.

Для управления написана обертка WorkFlow (для красивого синтаксиса содержит внутрений класс). Для отмены используется стандартный механизм CancellationTokenSource.

Worker

Worker получились простые: pip на вход и pip на выход, что сильно упрощает их тестирование и поддержки.

Обработка ошибок

При выбрасывание Exception из Worker (дочернего потока). Exception упаковывается в стандартный AggregateException. Worker-ы получают сигнал об отмене через CancellationTokenSource и могут завершить свою работу. Для ожидающий потоков вызывается Interrupt. (Так дочерние потоки не имеют дополнительной логики на отмену и просто должны прекратить работу, можно было бы использовать Thread.Abort(), но он был удален из .Net Core)

Ошибки работы с файлома читаемы и нетребует обертки или пояснения, выбрасываются как есть.

Decompress

Однопоточный потому как GZipStream поддерживает multiple parts. Потребление CPU, памяти минимальное.

Время разархивации в разы меньше. Можно было бы искать в потоке заголовки (изветсная последовательность) и разбивать на куски но

  1. Могут быть ложные срабатывания и их нужно обрабатывать
  2. Из-за малой времени и потребляемых ресурсов. Накладные расходы на распареливание могут ухудшить резельтат.

Что можно улучшить

  1. Внутрению колекция для OrderingPipe заменить на циклический буфер. Сейчас это по факту бутылочное горлышко.
  2. Тесты для Worker
  3. Обработка закрытия программы (Ctrl-C обрабатывается)
  4. Обработка нехватки памяти. Мы можем посчить сколько сумарно памяти нужно для запуска N потоков и если это больше доступной памяти запускаться в однопоточном режиме. При нехватки памяти Windows задействует swap что может быть хуже чем в однопоточном но в RAM.

P.S.

Как альтернативное решение не использовать выделенные потоки а использовать самописный пул-потоков. При появление сообщения в Pip менеджер берет свободный поток и запускате на нем обработку только этого сообщения. Как это былобы реальзовано на Task.

Но нужны планировшики для кажго шага или один общий. И была идея переиспользовать стримы но GzipStream не поддерживает сброс. Поэтому большую часть аллокаций памяти сейчас от стримов. Для буферов используется шареная память.

Код вынесен в отдельную сборку. Минус в том что еще одна dll. Но сам проект .net standart 2.0 и может быть использована как в .Net таки и в .Net Core. Да, в рамках текущей задачи избыточно.

Скриншоты потребления памяти в /doc/img

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages