
# Dělení do oddílů

`DocStore` zapisuje jeden soubor pro každý záznam. Bez dělení by se všechny soubory velké kolekce hromadily v jediném adresáři a operace s adresářem by se s rostoucím počtem položek zpomalovaly. storh proto rozděluje soubory záznamů do skupin podle dvou znaků ID záznamu:

```text
pages/data/2d/018bcfe5-6800-7000-8000-2d5dba6274da.jsonc
```

Skupina se určuje podle začátku UUID poslední části (znaky 24 a 25), která obsahuje náhodnou entropii. Dva hexadecimální znaky dávají 256 skupin, takže kolekce se 100 tisíci záznamy má v průměru méně než 400 souborů v adresáři.

## Proč konec, a ne začátek

ID UUIDv7 začínají 48bitovým časovým razítkem v milisekundách, takže ID vytvořená krátce po sobě sdílejí počáteční znaky. Dělení podle předpony by každou dávku zápisů směrovalo do stejného vytíženého adresáře a skupiny by se měnily pouze s postupem času. Koncové bajty jsou pro každý záznam náhodné, takže zápisy se rovnoměrně rozloží hned od prvního záznamu.

Dělení do oddílů je při čtení i dotazování neviditelné: `get()` vypočítá skupinu z ID a `stream()` vrací záznamy seřazené podle ID napříč všemi skupinami, takže stránkování pomocí kurzoru funguje, jako by kolekce byla jediným seřazeným seznamem.

## Ve velkém měřítku

Počet skupin nikdy neroste: dva hexadecimální znaky znamenají 256 adresářů bez ohledu na velikost kolekce. Roste počet souborů v každé skupině:

| Záznamy | Souborů ve skupině |
| ------- | ----------------- |
| 10k     | ~40               |
| 100k    | ~390              |
| 1M      | ~3,900            |
| 10M     | ~39,000           |

Moderní souborové systémy indexují položky adresářů, takže několik tisíc souborů ve skupině umožňuje rychlé vyhledávání jednotlivých záznamů; milion záznamů zvládají `get()` a dotazy využívající indexy bez problémů. Otevření úložiště má konstantní čas bez ohledu na velikost kolekce: osiřelé dočasné soubory se prohledávají jen tehdy, když značka po mrtvém zapisovači ukazuje, že předchozí proces havaroval uprostřed zápisu. Lineárně se s rozsahem zvětšují operace nad celou kolekcí: neindexovaná prohledávání, `reindex()` a `verify()` procházejí každý soubor záznamu, proto je berte jako dávkové úlohy. Přibližně nad 10 miliony záznamů v kolekci začíná záležet na počtu záznamů ve skupině i na celkovém využití inodů: rozdělte kolekce nebo pro data určená k prohledávání použijte segmentovaný protokol, který už svou konstrukcí udržuje počet souborů nízký.

## Ostatní moduly

`SegmentedLog` a `Queue` nedělí data do oddílů, protože nevytvářejí jeden soubor pro každý záznam. Protokol přidává data do segmentových souborů v `segments/`, jejichž velikost je omezena hodnotou `max_segment_bytes` (výchozí hodnota je 1 MiB), a fronta přidává události do jediného `queue.log`. Počet souborů tak zůstává nízký už svou konstrukcí.
