Dimungkinkan untuk meletakkan semua file dalam satu direktori, meskipun terkadang itu bisa menjadi agak besar. Banyak sistem file memiliki batas . Anda ingin meletakkan repositori git pada drive yang diformat FAT32 pada stik USB? Anda hanya dapat menyimpan 65.535 file dalam satu direktori. Ini berarti bahwa perlu untuk membagi struktur direktori sehingga mengisi satu direktori lebih kecil kemungkinannya.
Ini bahkan akan menjadi masalah dengan sistem file lain dan repositori git yang lebih besar. Repo git yang relatif kecil yang saya dapatkan (sekitar 360MiB) dan memiliki 181.546 objek untuk file 11k. Tarik repo Linux dan Anda punya 4.374.054 objek. Jika Anda meletakkan semua ini dalam satu direktori, tidak mungkin untuk memeriksa dan akan crash (untuk beberapa arti 'crash') sistem file.
Begitu? Anda membaginya dengan byte. Pendekatan serupa dilakukan dengan aplikasi seperti 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_
Selain itu, ini juga menyangkut masalah kinerja. Pertimbangkan Kinerja NTFS dengan Banyak Nama File Panjang :
Windows NT membutuhkan waktu lama untuk melakukan operasi direktori pada drive yang diformat sistem file Windows NT (NTFS) yang berisi sejumlah besar file dengan nama file yang panjang (nama yang tidak sesuai dengan konvensi 8.3) dalam satu direktori.
Ketika NTFS menghitung file dalam direktori, itu harus mencari 8,3 nama yang terkait dengan nama file panjang. Karena direktori NTFS dikelola dalam keadaan diurutkan, nama file panjang dan 8.3 nama yang sesuai umumnya tidak bersebelahan dalam daftar direktori. Jadi, NTFS menggunakan pencarian linear dari direktori untuk setiap file yang ada. Akibatnya, jumlah waktu yang diperlukan untuk melakukan daftar direktori meningkat dengan kuadrat jumlah file dalam direktori. Untuk sejumlah kecil file (kurang dari beberapa ratus) waktu tunda dapat diabaikan. Tetapi karena jumlah file dalam direktori meningkat hingga beberapa ribu, waktu yang diperlukan untuk melakukan listing dapat meningkat menjadi beberapa menit, jam, atau bahkan berhari-hari. Masalahnya diperburuk jika nama file yang panjang sangat mirip - hanya berbeda dalam beberapa karakter terakhir.
Dengan file yang dinamai dengan checksum SHA1, ini bisa menjadi resep untuk kinerja bencana dan buruk.
Sementara di atas adalah dari catatan teknologi dari Windows NT 3.5 (dan NTFS 1.2 - biasa digunakan dari 1995 hingga awal 2000-an) ini juga dapat dilihat dalam hal-hal seperti EXT3 dengan implementasi dari filesystem yang dihubungkan daftar yang memerlukan O (n) lookup . Dan bahkan dengan perubahan B-tree:
Sementara algoritma HTree secara signifikan meningkatkan waktu pencarian, hal itu dapat menyebabkan beberapa regresi kinerja untuk beban kerja yang menggunakan readdir () untuk melakukan beberapa operasi semua file dalam direktori besar.
...
Salah satu solusi potensial untuk mengurangi masalah kinerja ini, yang telah disarankan oleh Daniel Phillips dan Andreas Dilger, tetapi belum diimplementasikan, melibatkan kernel memilih inode bebas yang nomor inodenya memenuhi properti yang mengelompokkan inode dengan hash nama file mereka. Daniel dan Andreas menyarankan untuk mengalokasikan inode dari berbagai inode berdasarkan ukuran direktori, dan kemudian memilih inode gratis dari rentang itu berdasarkan hash nama file. Ini seharusnya secara teori mengurangi jumlah labrakan yang dihasilkan saat mengakses inode yang dirujuk dalam direktori dalam urutan readdir. Namun tidak jelas bahwa strategi ini akan menghasilkan percepatan; sebenarnya itu dapat meningkatkan jumlah total blok inode yang mungkin harus direferensikan, dan dengan demikian membuat kinerja readdir () + stat () beban kerja lebih buruk. Jelas,
Kebetulan, ini sedikit tentang cara meningkatkan kinerja dari tahun 2005, tahun yang sama git dirilis.
Seperti yang terlihat dengan Firefox dan banyak aplikasi lain yang memiliki banyak file cache hash, desain memecah cache dengan byte. Ini memiliki biaya kinerja yang dapat diabaikan, dan ketika digunakan lintas platform dengan sistem yang mungkin sedikit di sisi lama, bisa sangat baik perbedaan antara program yang bekerja atau tidak.
git
sistem "paket" mengurangi banyak masalah ini. Secara teoritis,git
bisa menggunakan hanya satu direktori, dan hanya mengemas ulang ketika jumlah file dalam direktori itu melebihi batas tertentu (mungkin tergantung pada FS).Ada dua alasan mengapa ini diinginkan.
Direktori tidak boleh besar secara sewenang-wenang. Misalnya beberapa sistem file (yang cukup modern!) Terbatas pada 32000 entri dalam satu direktori. Jumlah komit di kernel Linux dalam urutan besarnya. Membagi komit dengan dua digit hex pertama membatasi ukuran tingkat atas hingga 256 entri. Sub-direktori akan jauh lebih kecil untuk repositori git tipikal.
Direktori dipindai secara linear. Dalam beberapa sistem file (misalnya keluarga Ext *), direktori adalah daftar atau tabel entri yang ditautkan. Untuk mencari file, seluruh daftar dipindai sampai nama file yang cocok ditemukan. Jelas, ini tidak diinginkan untuk kinerja. Banyak sistem file modern juga menggunakan tabel hash atau B-tree untuk pencarian cepat, tetapi tidak semua orang memilikinya. Menjaga setiap direktori tetap kecil berarti waktu akses yang cepat.
sumber
objects
direktori tersebut dapat menampung hingga 4096 subdirektori alih-alih terbatas pada 256, memenuhi persyaratan di atas, tetapi dengan keuntungan tambahan bahwa subdirektori tersebut 16x lebih kecil kemungkinannya untuk berisi> 32000 file.256 bucket ini memungkinkan git untuk menyimpan repositori yang lebih besar pada sistem file yang membatasi jumlah file dalam direktori dan memberikan kinerja turunan pada sistem file yang menjadi lebih lambat dengan direktori yang berisi banyak file.
sumber
Ada beberapa filesystem dan / atau implementasi filesystem dan / atau implementasi libc di mana kinerja menurun dengan sejumlah besar entri direktori.
sumber