Можно поместить все файлы в один каталог, хотя иногда это может стать немного большим. Многие файловые системы имеют ограничение . Вы хотите поместить репозиторий git на диск в формате FAT32 на флешку? Вы можете хранить только 65 535 файлов в одном каталоге. Это означает, что необходимо подразделить структуру каталогов так, чтобы заполнение одного каталога было менее вероятным.
Это может даже стать проблемой с другими файловыми системами и более крупными git-репозиториями. Относительно небольшой репозиторий Git, который я вывешивал (около 360 МБ), и он имеет 181 546 объектов для файлов размером 11 КБ. Потяните репозиторий Linux, и вы получите 4 374 054 объекта. Если бы вы поместили все это в один каталог, было бы невозможно проверить и вывести из строя (для некоторого значения «крах») файловую систему.
Так? Вы делите это на байт. Подобные подходы делаются с приложениями, такими как FireFox:
~/Li/Ca/Fi/Pr/7a/Cache $ ls
0/ 4/ 8/ C/ _CACHE_001_
1/ 5/ 9/ D/ _CACHE_002_
2/ 6/ A/ E/ _CACHE_003_
3/ 7/ B/ F/ _CACHE_MAP_
Помимо этого, это также касается вопроса производительности. Рассмотрим производительность NTFS с множеством длинных имен файлов :
Windows NT занимает много времени для выполнения операций с каталогами на дисках, отформатированных в файловой системе Windows NT (NTFS), которые содержат большое количество файлов с длинными именами файлов (имена, которые не соответствуют соглашению 8.3) в одном каталоге.
Когда NTFS перечисляет файлы в каталоге, она должна искать имена 8.3, связанные с длинными именами файлов. Поскольку каталог NTFS поддерживается в отсортированном состоянии, соответствующие длинные имена файлов и имена 8.3, как правило, не находятся рядом друг с другом в списке каталогов. Таким образом, NTFS использует линейный поиск в каталоге для каждого файла. В результате количество времени, необходимое для выполнения листинга каталога, увеличивается с квадратом количества файлов в каталоге. Для небольшого количества файлов (менее нескольких сотен) задержка незначительна. Но поскольку количество файлов в каталоге увеличивается до нескольких тысяч, время, необходимое для выполнения листинга, может увеличиться до минут, часов или даже дней. Проблема усугубляется, если длинные имена файлов очень похожи - отличаются только последними несколькими символами.
С файлами, названными в честь контрольных сумм SHA1, это может стать рецептом катастрофы и ужасной производительности.
Хотя приведенное выше взято из технической заметки Windows NT 3.5 (и NTFS 1.2 - обычно используемой с 1995 по начало 2000-х годов), это также можно увидеть в таких вещах, как EXT3, где реализации файловой системы представляют собой связанные списки, требующие поиска O (n) , И даже с этим изменением B-дерева:
Хотя алгоритм HTree значительно улучшил время поиска, он может привести к некоторым спадам производительности для рабочих нагрузок, использующих readdir () для выполнения некоторых операций со всеми файлами в большом каталоге.
...
Одно из возможных решений для смягчения этой проблемы производительности, которое было предложено Дэниелом Филлипсом и Андреасом Дилгером, но еще не реализовано, заключается в том, что ядро выбирает свободные иноды, номера инодов которых соответствуют свойству, которое группирует иноды по их хэшу имени файла. Дэниел и Андреас предлагают выделить инод из диапазона инодов на основе размера каталога, а затем выбрать свободный инод из этого диапазона на основе хэша имени файла. Теоретически это должно уменьшить количество изменений, возникающих при доступе к инодам, указанным в каталоге, в порядке чтения. Однако не ясно, что эта стратегия приведет к ускорению; фактически это может увеличить общее количество блоков inode, на которые, возможно, придется ссылаться, и, таким образом, ухудшить производительность рабочих нагрузок readdir () + stat (). Очевидно, что
Кстати, этот бит о том, как улучшить производительность, был с 2005 года, в том же году был выпущен git.
Как видно из Firefox и многих других приложений, которые имеют много файлов с хеш-кешированием, дизайн разбивает кэш по байтам. Он имеет незначительные затраты производительности, и при использовании кроссплатформенности с системами, которые могут быть немного устаревшими, вполне может быть разница между работающей программой или нет.
git
«pack» смягчает многие из этих проблем. Теоретически,git
можно использовать только один каталог и просто перепаковывать, когда количество файлов в этом каталоге превышает определенный (возможно, зависящий от FS) предел.Есть две причины, почему это желательно.
Каталоги не могут быть сколь угодно большими. Например, некоторые (достаточно современные!) Файловые системы ограничены 32000 записей в одном каталоге. Количество коммитов в ядре Linux находится в таком порядке. Подразделение коммитов их первыми двумя шестнадцатеричными цифрами ограничивает размер верхнего уровня до 256 записей. Подкаталоги будут намного меньше для типичных репозиториев git.
Каталоги сканируются линейно. В некоторых файловых системах (например, семейство Ext *) каталог представляет собой связанный список или таблицу записей. Чтобы найти файл, весь список сканируется, пока не будет найдено подходящее имя файла. Понятно, что это нежелательно для производительности. Многие современные файловые системы дополнительно используют хеш-таблицы или B-деревья для быстрого поиска, но не у всех они могут быть. Хранение каждого каталога маленьким означает быстрое время доступа.
источник
objects
каталог может содержать до 4096 подкаталогов вместо ограниченного 256, что отвечает вышеупомянутому требованию, но с дополнительным преимуществом, что эти подкаталоги будут в 16 раз менее вероятно содержать в себе> 32000 файлов.Эти 256 блоков позволяют git хранить большие репозитории в файловых системах, которые ограничивают количество файлов в каталоге и обеспечивают низкую производительность в файловых системах, которые снижаются при использовании каталогов, содержащих много файлов.
источник
Существуют некоторые реализации файловых систем и / или файловых систем и / или реализаций libc, в которых производительность снижается при большом количестве записей каталога.
источник