可以将所有文件放在一个目录中,尽管有时会变得有些大。 许多文件系统都有限制。您想将git存储库放在USB记忆棒上的FAT32格式的驱动器上吗?您只能在一个目录中存储65,535个文件。这意味着必须细分目录结构,以便不太可能填充单个目录。
对于其他文件系统和更大的git存储库,这甚至会成为问题。我已经闲逛了一个相对较小的git repo(大约360MiB),它有181,546个用于11k文件的对象。拉Linux仓库,您有4,374,054个对象。如果将所有这些文件放在一个目录中,则将无法检出文件,并且将导致文件系统崩溃(出于“ crash”的某种含义)。
所以?您将其按字节分割。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年常用于21世纪初),这也可以在的东西,如可以看出EXT3与文件系统是链表的实现,需要为O(n)查找。即使有了B树更改:
尽管HTree算法大大缩短了查找时间,但可能会导致使用readdir()对大型目录中的所有文件执行某些操作的工作负载导致性能下降。
...
Daniel Phillips和Andreas Dilger提出了一个可能的缓解此性能问题的解决方案,但尚未实施,该方案涉及内核选择自由inode,这些inode的inode编号符合按文件名哈希对inode进行分组的属性。Daniel和Andreas建议根据目录的大小从一定范围的索引节点中分配索引节点,然后根据文件名哈希从该范围中选择一个空闲索引节点。从理论上讲,这应该减少当以readdir顺序访问目录中引用的inode时导致的抖动。但是,尚不清楚该策略是否会加速。实际上,这可能会增加可能必须引用的inode块的总数,从而使readdir()+ stat()工作负载的性能变差。显然,
顺便说一句,这是关于如何提高性能的,是从git发布的2005年开始的。
从Firefox和许多其他具有大量哈希缓存文件的应用程序中可以看出,按字节划分缓存的设计。它的性能成本可以忽略不计,并且当跨平台使用可能有点陈旧的系统时,很可能是程序正常与否的区别。