È possibile mettere tutti i file in una directory, anche se a volte può diventare un po 'grande. Molti file system hanno un limite . Vuoi mettere un repository git su un disco formattato FAT32 su una chiavetta USB? È possibile memorizzare solo 65.535 file in una singola directory. Ciò significa che è necessario suddividere la struttura della directory in modo che sia meno probabile riempire una singola directory.
Questo potrebbe persino diventare un problema con altri file system e repository git più grandi. Un repository git relativamente piccolo che ho in giro (circa 360 MiB) e ha 181.546 oggetti per file 11k. Estrai il repository Linux e avrai 4.374.054 oggetti. Se dovessi metterli tutti in una directory, sarebbe impossibile verificare e si bloccherebbe (per un certo significato di "crash") il file system.
Così? Lo dividi per byte. Approcci simili vengono fatti con applicazioni come 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_
Oltre a ciò, si passa anche a una questione di prestazioni. Prendi in considerazione le prestazioni NTFS con numerosi nomi di file lunghi :
Windows NT impiega molto tempo per eseguire operazioni di directory su unità formattate con file system (NTFS) di Windows NT che contengono un numero elevato di file con nomi di file lunghi (nomi non conformi alla convenzione 8.3) in una singola directory.
Quando NTFS enumera i file in una directory, deve cercare i nomi 8.3 associati ai nomi di file lunghi. Poiché una directory NTFS viene mantenuta in uno stato ordinato, i nomi di file lunghi corrispondenti e i nomi 8.3 non sono generalmente uno accanto all'altro nell'elenco di directory. Pertanto, NTFS utilizza una ricerca lineare della directory per ogni file presente. Di conseguenza, il tempo necessario per eseguire un elenco di directory aumenta con il quadrato del numero di file nella directory. Per un numero limitato di file (meno di alcune centinaia) il ritardo è trascurabile. Ma poiché il numero di file in una directory aumenta a diverse migliaia, il tempo necessario per eseguire un elenco può aumentare a minuti, ore o persino giorni. Il problema si aggrava se i nomi di file lunghi sono molto simili, differendo solo negli ultimi caratteri.
Con i file che prendono il nome dai checksum SHA1, questa potrebbe essere una ricetta per disastri e prestazioni spaventose.
Mentre quanto sopra deriva da una nota tecnica di Windows NT 3.5 (e NTFS 1.2 - comunemente usati dal 1995 ai primi anni 2000), questo può essere visto anche in cose come EXT3 con implementazioni del filesystem che sono liste collegate che richiedono una ricerca O (n) . E anche con quel cambio B-tree:
Mentre l'algoritmo HTree ha migliorato significativamente i tempi di ricerca, potrebbe causare alcune regressioni delle prestazioni per i carichi di lavoro che utilizzavano readdir () per eseguire alcune operazioni di tutti i file in una directory di grandi dimensioni.
...
Una potenziale soluzione per mitigare questo problema di prestazioni, che è stata suggerita da Daniel Phillips e Andreas Dilger, ma non ancora implementata, prevede che il kernel scelga inode liberi i cui numeri di inode soddisfino una proprietà che raggruppa gli inode in base al loro hash di nome file. Daniel e Andreas suggeriscono di allocare l'inode da un intervallo di inode in base alla dimensione della directory, e quindi di scegliere un inode gratuito da quell'intervallo in base all'hash del nome file. Ciò dovrebbe in teoria ridurre la quantità di thrashing che risulta quando si accede agli inode a cui si fa riferimento nella directory in ordine readdir. Non è chiaro, tuttavia, che questa strategia si tradurrà in un aumento di velocità; in effetti potrebbe aumentare il numero totale di blocchi di inode a cui potrebbe essere necessario fare riferimento, e quindi peggiorare le prestazioni dei carichi di lavoro readdir () + stat (). Chiaramente,
Per inciso, questo pezzo su come migliorare le prestazioni è del 2005, lo stesso anno in cui è stato rilasciato git.
Come si è visto con Firefox e molte altre applicazioni che hanno molti file con cache hash, la progettazione di suddividere la cache per byte. Ha costi di prestazione trascurabili e, se usati su piattaforme diverse con sistemi che potrebbero essere un po 'vecchi, potrebbe benissimo essere la differenza tra il funzionamento del programma o meno.