É possível colocar todos os arquivos em um diretório, embora às vezes isso possa se tornar um pouco grande. Muitos sistemas de arquivos têm um limite . Deseja colocar um repositório git em uma unidade formatada em FAT32 em um pendrive? Você pode armazenar apenas 65.535 arquivos em um único diretório. Isso significa que é necessário subdividir a estrutura de diretório para que seja menos provável o preenchimento de um único diretório.
Isso até se tornaria um problema com outros sistemas de arquivos e repositórios git maiores. Um repositório Git relativamente pequeno que eu tenho (cerca de 360MiB) e tem 181.546 objetos para arquivos 11k. Puxe o repositório Linux e você terá 4.374.054 objetos. Se você colocasse tudo isso em um diretório, seria impossível verificar e travar (por algum significado de 'travar') o sistema de arquivos.
Tão? Você o divide por byte. Abordagens semelhantes são feitas com aplicativos como o 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_
Além disso, também vai para uma questão de desempenho. Considere o desempenho NTFS com vários nomes de arquivos longos :
O Windows NT leva muito tempo para executar operações de diretório em unidades formatadas pelo sistema de arquivos Windows NT (NTFS) que contêm um grande número de arquivos com nomes longos (nomes que não estão em conformidade com a convenção 8.3) em um único diretório.
Quando o NTFS enumera arquivos em um diretório, ele deve procurar os nomes 8.3 associados aos nomes longos dos arquivos. Como um diretório NTFS é mantido em um estado classificado, os nomes longos correspondentes do arquivo e os nomes 8.3 geralmente não estão próximos um do outro na lista de diretórios. Portanto, o NTFS usa uma pesquisa linear do diretório para todos os arquivos presentes. Como resultado, a quantidade de tempo necessária para executar uma listagem de diretório aumenta com o quadrado do número de arquivos no diretório. Para um pequeno número de arquivos (menos de algumas centenas), o atraso é insignificante. Porém, à medida que o número de arquivos em um diretório aumenta para vários milhares, o tempo necessário para executar uma listagem pode aumentar para minutos, horas ou até dias. O problema é agravado se os nomes de arquivos longos forem muito semelhantes - diferindo apenas nos últimos caracteres.
Com arquivos nomeados após as somas de verificação SHA1, essa pode ser uma receita para um desastre e um desempenho péssimo.
Embora o acima seja de uma nota técnica do Windows NT 3.5 (e NTFS 1.2 - comumente usada de 1995 ao início dos anos 2000), isso também pode ser visto em coisas como EXT3, com implementações do sistema de arquivos vinculadas a listas que exigem pesquisa de O (n) . E mesmo com essa mudança de árvore B:
Embora o algoritmo HTree melhore significativamente os tempos de pesquisa, ele pode causar algumas regressões de desempenho para cargas de trabalho que usaram readdir () para executar alguma operação de todos os arquivos em um diretório grande.
...
Uma solução potencial para mitigar esse problema de desempenho, sugerida por Daniel Phillips e Andreas Dilger, mas ainda não implementada, envolve o kernel escolhendo inodes livres cujos números de inode atendem a uma propriedade que agrupa os inodes pelo hash do nome do arquivo. Daniel e Andreas sugerem alocar o inode de um intervalo de inodes com base no tamanho do diretório e, em seguida, escolher um inode livre desse intervalo com base no hash do nome do arquivo. Em teoria, isso deve reduzir a quantidade de thrashing resultante ao acessar os inodes referenciados no diretório na ordem readdir. No entanto, não está claro que essa estratégia resulte em uma aceleração; na verdade, isso poderia aumentar o número total de blocos de inodes que talvez precisassem ser referenciados e, assim, piorar o desempenho das cargas de trabalho readdir () + stat (). Claramente,
Aliás, esse pouco sobre como melhorar o desempenho foi de 2005, no mesmo ano em que o git foi lançado.
Como visto no Firefox e em muitos outros aplicativos que possuem muitos arquivos em cache de hash, o design de dividir o cache por byte. Ele tem um custo insignificante de desempenho e, quando usado em várias plataformas com sistemas que podem ser um pouco antigos, pode muito bem ser a diferença entre o programa funcionando ou não.