File system in user space (FUSE) with compression and deduplication. Written in a single C file (1K LOC). Uses OpenSSL for hashing, zlib for compression and SQLite for data storage.
Can be even used as a permanent storage, or as a ramdrive (with “:memory:” database). Should be well suited for storing rather small, well compressible and possibly duplicate files (like a number of source trees, fetched from different sources, containing same submodules, etc).
Purely research project. Not for any other type of use.
There are two tables created in the database. The “t_entry” table represents file/folder hierarchy, and the “t_block” table represents binary blobs. When the file is opened, its blob gets fetched and decompressed into cache. The following read/write operations are done to the cached byte array. When the file is closed, it is checksummed, compressed and stored into the database. If there is already a blob with the same checksum, the blob is not stored, and the file is linked to the already existing blob.
./plik -h
./plik test_folder -o db_name=:memory:
./plik test_folder -f -d -o db_name=test.db
There are other options, that are common, and processed by FUSE library.
EMail: plik@tycho.sytes.net
All the feedback, suggestions, ideas, contributions are welcome.
Though nothing is promised.
Собственно, все образованные люди - нет необходимости пересказывать всё выдавленное выше.
Уже довольно давно на свете существует ZFS. И всем хорош, и сжатие, и дедубликация, и снимки, и бэкапы, и неразрушительное управление томами и всякое. Но одновременно, почти нигде толком не используется. А почему. Во-первых, все боятся Ларри Эллисона. Он мужчина серьёзный и у него много адвокатов. И если он придёт к вам и начнёт применять пруденцию, останетесь без штанов. Не то чтобы окончательно правильная свободная лицензия - все это понимают. Во-вторых, и тут я согласен с Тео де Раадтом, смешивание уровней абстракции и нарушение общей логики и изоляции - объединение томов и файловых систем - это неправильно. Опять же, какие альтернативы. BTRFS, говорят, не готов (кроме этого, эти люди из этого вашего Линукса недавно ReiserFS отпилили. А ReiserFS был охренителен). Поэтому у нас будет свой ZFS, корявый и недоделанный, в юзерспейсе.
Первая версия, ясное дело, была написана на Qt. Но выяснилось, что Гоблинтеч мало того, что сделал QtSql не потокобезопасным (как оказалось, обвесить мьютексом недостаточно), но требующим, чтобы обращение к БД было только из главной нити. FUSE многопоточен. Можно конечно толкать в однопоточном режиме (c “-s”) и будет работать. Но это не спортивно.
Далее появилась мысль взять другую библиотеку. Слышал про Poco. Почитал документацию (ту, что нашел). Перебор. Много неизведанного.
Boost или стандартная библиотека C++? Пускай Бьёрн Страуструп на этом пишет. Я тут недавно видел последний стандарт C++. Кино и немцы. С каждой итерацией новый язык. Ничего похожего на то, что было 20 лет назад с этим же названием. Есть мнение, что выпускаемые стандарты C++ нужны главным образом “ребятам из Яндекса”, у которых нет других оснований покататься по миру и потом похвастаться на Юттэп. Могли бы просто кататься. Но нет, извратили язык дальше некуда. И хвастаются. Видел тут видео, где собрались целое помещение и угадывают, что делает программа из 4-х строк. И долго не могут угадать. Я бы вот не хвастался.
Назад к корням. Хотелось бы всяких структур данных и функций по их управлению. Посмотрел на Glib и на EFL. С другой стороны, с документацией тяжеловато. Такой документации, как в Qt нет нигде. Максималистическое субъективное заявление.
Поэтому пускай будет чистый Си с частными библиотеками для специфического (а не общего) назначения. Опять же valgrind и gprof будут бойчее работать.
Вся реализация в одном main.c (подход “амальгамирование” принятый в JUCE). Кто теряется в 1K LOC, у того низкий ICQ, и тот нам не товарищ. А про то, что такое бывает и у нас, мы не признаемся, чтобы нас не обвинили в низком ICQ.
Название взято из Гаду-Гаду, лучшего на сегодняшний день мессенджера с лучшим названием и лучшими смайликами из всех, что есть на свете.
В Си нет исключений. Или есть, но мы о них не знаем. И одновременно нет возможности вернуть из функции анонимный кортеж, как в Perl 5 (лучшем языке программирования на свете). Поэтому, функции почти везде сконструированы как в классическом MacOS (и много ещё где) - набор входных и выходных параметров, в качестве возвращаемого значения bool успешности. Проверка на возврат false и возврат false - как замена исключений. Там, где false “порождается” - вывод сообщения об ошибке в консоль.
Ещё измышления. Если переменная на стеке, она вылетит с выходом из области видимости. Объект класса будет грохнут деструктором, который будет вызван в эпилоге функции компилятором C++. Для Си так не получится. Переменную на стеке он выбросит, а вот “деструктор” вызван неявно не будет. С указателями вообще беда - всё что в куче, останется в куче. Нужно всегда явно удалять то, что сам создал. Принимая во внимания ветвления и возвраты из середины функции, отслеживание созданного становится хитрой задачей. В Objective-C есть такая штука как NSAutoreleasePool. В go есть конструкции типа defer file.Close(). То есть, можно создать объект и сразу его отметить, как требующий сноса по завершении обработки, вне зависимости от того, что будет происходить дальше. В Си такого нет. Сконструируем. Будет pool, куда мы будем скучивать все промежуточные структуры (с указателем на функцию сноса), который будет для нас удалять весь мусор в конце “обработки события”. Может быть человечество такое сделало и без меня. Я тоже сделал. Valgrind подтверждает корректность. Появляется необходимость расслоить непосредственно функцию, и наружную обёртку, создающую и сносящую пул. Ну что делать, пока так.
У пула нет retain’а, то есть нельзя удержать то, что уже предназначено у сносу, только перекопировать. Поэтому тут и там есть “лишнее” копирование, но не много.
Разбор аргументов в стиле FUSE тоже субъидеален на мой перфекционистский взгляд. Это кроме того, что как добавил поддержку “разбора аргументов”, то тут же появилась утечка памяти. Не солидно. Даже всё настроение продолжать пропало, пока не придумаю, как устранить утечку. Переделывать полностью парсинг опций командной строки и фальсификацию оных отдельно для FUSE пока делать лениво. Поэтому остановимся пока на том, что есть.
Эта штука в целом может вообще к стати не работать. Но я бы попробовал. Самокритика и оптимизм.
Почтовый адрес для сбора обратной связи написан чуть выше (тут квест, ага). Конструктивным замечаниям, предложениям по развитию проекта буду рад.
Д.С.