
# Sadalīšana segmentos

`DocStore` katram ierakstam izveido atsevišķu failu. Bez sadalīšanas segmentos lielā kolekcijā visi faili uzkrātos vienā mapē, un mapes darbības palēninātos, pieaugot ierakstu skaitam. Tāpēc storh sadala ierakstu failus grupās pēc divām ID rakstzīmēm:

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

Grupas nosaukums tiek veidots no UUID pēdējās daļas sākuma (24. un 25. rakstzīmes), kas satur nejaušu entropiju. Divas heksadecimālās rakstzīmes dod 256 grupas, tāpēc 100k ierakstu kolekcijā katrā mapē vidēji ir mazāk nekā 400 failu.

## Kāpēc izmantot beigas, nevis sākumu

UUIDv7 ID sākas ar 48 bitu laika zīmogu milisekundēs, tāpēc gandrīz vienlaikus izveidotiem ID ir vienādas sākuma rakstzīmes. Sadalot segmentos pēc prefiksa, katrs rakstīšanas uzplūds nonāktu vienā un tajā pašā noslogotajā mapē, un grupas mainītos tikai laika gaitā. Ierakstu beigu baiti ir nejauši, tāpēc ieraksti tiek vienmērīgi sadalīti jau no paša sākuma.

Sadalīšana segmentos ir nemanāma nolasīšanai un vaicājumiem: `get()` aprēķina grupu pēc ID, bet `stream()` atgriež ierakstus, sakārtotus pēc ID visās grupās, tāpēc lapošana ar kursoru darbojas tā, it kā kolekcija būtu viens sakārtots saraksts.

## Lielā mērogā

Grupu skaits nekad nepieaug: divas heksadecimālās rakstzīmes nozīmē 256 mapes neatkarīgi no kolekcijas lieluma. Pieaug failu skaits katrā grupā:

| Ieraksti | Faili grupā |
| ------- | ---------------- |
| 10k     | ~40              |
| 100k    | ~390             |
| 1M      | ~3,900           |
| 10M     | ~39,000          |

Mūsdienu failu sistēmas indeksē mapju ierakstus, tāpēc daži tūkstoši failu katrā grupā nodrošina ātru tiešo meklēšanu; 1M ierakstu ir ērti apstrādāt, izmantojot `get()` un indeksētus vaicājumus. Krātuves atvēršana aizņem nemainīgu laiku neatkarīgi no kolekcijas lieluma: bāreņu pagaidu failu tīrīšana notiek tikai tad, ja bojāta rakstītāja pazīme liecina, ka iepriekšējais process avarējis rakstīšanas laikā. Darbības, kas mērogojas lineāri, ir darbi ar visu kolekciju: neindeksēta skenēšana, `reindex()` un `verify()`, kas katrs pārbauda visus ierakstu failus, tāpēc uzskatiet tos par pakešdarbiem. Ja kolekcijā ir vairāk nekā aptuveni 10M ierakstu, jārēķinās ar ierakstu skaitu grupās un kopējo i-node lietojumu: sadaliet kolekcijas vai izmantojiet segmentētu žurnālu datiem, kas tiek skenēti, jo tas pēc konstrukcijas uztur mazu failu skaitu.

## Pārējie dzinēji

`SegmentedLog` un `Queue` nav jāsadala segmentos, jo tie neveido atsevišķu failu katram ierakstam. Žurnāls pievieno ierakstus segmentu failiem mapē `segments/`, kuru izmēru ierobežo `max_segment_bytes` (pēc noklusējuma 1 MiB), bet rinda pievieno notikumus vienam `queue.log`. Failu skaits pēc konstrukcijas ir neliels.
