Es ist möglich, alle Dateien in einem Verzeichnis abzulegen, obwohl dies manchmal etwas umfangreich werden kann. Viele Dateisysteme haben ein Limit . Sie möchten ein Git-Repository auf einem FAT32-formatierten Laufwerk auf einem USB-Stick ablegen? Sie können nur 65.535 Dateien in einem einzigen Verzeichnis speichern. Dies bedeutet, dass die Verzeichnisstruktur unterteilt werden muss, damit das Füllen eines einzelnen Verzeichnisses weniger wahrscheinlich ist.
Dies würde sogar bei anderen Dateisystemen und größeren Git-Repositorys zu einem Problem werden. Ein relativ kleines Git-Repo, in dem ich rumhängen muss (ca. 360MiB) und das 181.546 Objekte für 11k-Dateien enthält. Ziehen Sie das Linux-Repo und Sie haben 4.374.054 Objekte. Wenn Sie diese alle in einem Verzeichnis ablegen würden, wäre es unmöglich, das Dateisystem auszuchecken und zum Absturz zu bringen (für eine Bedeutung von "Absturz").
So? Sie haben es byteweise aufgeteilt. Ähnliche Ansätze werden mit Anwendungen wie FireFox durchgeführt:
~/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_
Darüber hinaus geht es auch um eine Frage der Leistung. Berücksichtigen Sie die NTFS-Leistung mit zahlreichen langen Dateinamen :
Windows NT benötigt viel Zeit, um Verzeichnisvorgänge auf NTFS-formatierten Laufwerken (Windows NT File System) auszuführen, die eine große Anzahl von Dateien mit langen Dateinamen (Namen, die nicht der 8.3-Konvention entsprechen) in einem einzelnen Verzeichnis enthalten.
Wenn NTFS Dateien in einem Verzeichnis auflistet, muss es nach den 8.3-Namen suchen, die den langen Dateinamen zugeordnet sind. Da ein NTFS-Verzeichnis in einem sortierten Zustand verwaltet wird, werden entsprechende lange Dateinamen und 8.3-Namen in der Verzeichnisliste in der Regel nicht nebeneinander angezeigt. Daher verwendet NTFS für jede vorhandene Datei eine lineare Suche im Verzeichnis. Infolgedessen steigt der Zeitaufwand für die Durchführung einer Verzeichnisliste mit dem Quadrat der Anzahl der Dateien im Verzeichnis. Für eine kleine Anzahl von Dateien (weniger als einige hundert) ist die Zeitverzögerung vernachlässigbar. Wenn sich die Anzahl der Dateien in einem Verzeichnis jedoch auf mehrere Tausend erhöht, kann sich der Zeitaufwand für eine Auflistung auf Minuten, Stunden oder sogar Tage erhöhen. Das Problem verschlimmert sich, wenn die langen Dateinamen sehr ähnlich sind - nur in den letzten Zeichen unterschiedlich.
Bei Dateien, die nach SHA1-Prüfsummen benannt sind, kann dies ein Rezept für eine Katastrophe und eine miserable Leistung sein.
Das Obige stammt aus einem technischen Hinweis von Windows NT 3.5 (und NTFS 1.2 - häufig verwendet von 1995 bis Anfang 2000). Dies kann auch in Dingen wie EXT3 festgestellt werden, bei denen Implementierungen des Dateisystems verknüpfte Listen sind, die O (n) Lookup erfordern . Und selbst mit diesem B-Tree-Wechsel:
Während der HTree-Algorithmus die Nachschlagezeiten erheblich verbesserte, konnte er bei Workloads, die readdir () verwendeten, einige Leistungseinbußen verursachen, um einige Vorgänge für alle Dateien in einem großen Verzeichnis auszuführen.
...
Eine mögliche Lösung zur Minderung dieses Leistungsproblems, das von Daniel Phillips und Andreas Dilger vorgeschlagen, aber noch nicht implementiert wurde, besteht darin, dass der Kernel freie Inodes auswählt, deren Inode-Nummern einer Eigenschaft entsprechen, die die Inodes nach ihrem Dateinamen-Hash gruppiert. Daniel und Andreas schlagen vor, den Inode aus einer Reihe von Inodes basierend auf der Größe des Verzeichnisses zuzuweisen und dann einen freien Inode aus diesem Bereich basierend auf dem Dateinamen-Hash auszuwählen. Dies sollte theoretisch die Menge an Thrashing reduzieren, die beim Zugriff auf die Inodes entsteht, auf die im Verzeichnis in readdir-Reihenfolge verwiesen wird. Insofern ist nicht klar, dass diese Strategie zu einer Beschleunigung führen wird; Tatsächlich kann dies die Gesamtzahl der Inode-Blöcke erhöhen, auf die möglicherweise verwiesen werden muss, und damit die Leistung der Workloads readdir () + stat () verschlechtern. Deutlich,
Übrigens war dieses Stück, wie man die Leistung verbessert, von 2005 an das gleiche Jahr, in dem git veröffentlicht wurde.
Wie bei Firefox und vielen anderen Anwendungen, die viele zwischengespeicherte Hash-Dateien haben, ist das Design das Aufteilen des Caches nach Byte. Es hat vernachlässigbare Leistungskosten, und wenn es plattformübergreifend mit Systemen verwendet wird, die möglicherweise etwas altmodisch sind, kann dies durchaus den Unterschied zwischen dem funktionierenden Programm und dem nicht funktionierenden Programm ausmachen.