.nornir/assets/lzip_parallel_flow.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1180 640" font-family="'DejaVu Sans', 'Segoe UI', sans-serif">
<defs>
<linearGradient id="board" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#0b1c2e"/><stop offset="1" stop-color="#06111d"/></linearGradient>
<linearGradient id="chip" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#14384f"/><stop offset="1" stop-color="#0e2a3e"/></linearGradient>
<linearGradient id="rail" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#173d57"/><stop offset="1" stop-color="#0c2438"/></linearGradient>
<linearGradient id="slot" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#123448"/><stop offset="1" stop-color="#0a2032"/></linearGradient>
<marker id="ah" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0 L10 5 L0 10 z" fill="#6fd3f5"/></marker>
</defs>
<rect x="0" y="0" width="1180" height="640" fill="url(#board)"/>
<g stroke="#143a52" stroke-width="1"><line x1="0" y1="74" x2="1180" y2="74"/><line x1="0" y1="592" x2="1180" y2="592"/></g>
<g fill="#16415c"><circle cx="40" cy="38" r="2"/><circle cx="1140" cy="38" r="2"/></g>
<text x="40" y="42" fill="#eaf6ff" font-size="22" font-weight="700">lzip-parallel</text>
<text x="196" y="42" fill="#9fc9e0" font-size="15">ZIP (JAR's superset) — parse Central Directory at tail → sort by offset → batched sequential reads → LPT balanced fan-out → per-entry DEFLATE + CRC</text>
<g font-size="12">
<line x1="770" y1="60" x2="810" y2="60" stroke="#6fd3f5" stroke-width="3" marker-end="url(#ah)"/><text x="816" y="64" fill="#cfe6f5">parallel dataflow</text>
<line x1="960" y1="60" x2="1000" y2="60" stroke="#ffcf6f" stroke-width="2" stroke-dasharray="4 3"/><text x="1006" y="64" fill="#ffcf6f">LPT weight · recycle</text>
</g>
<!-- INPUT -->
<rect x="24" y="238" width="128" height="164" rx="10" fill="url(#chip)" stroke="#5aa6cf" stroke-width="2"/>
<text x="88" y="264" fill="#eaf6ff" font-size="14" font-weight="700" text-anchor="middle">.zip input</text>
<rect x="38" y="286" width="100" height="26" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="88" y="303" fill="#bfe6ff" font-size="8.5" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">EOCD at tail</text>
<rect x="38" y="318" width="100" height="38" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="88" y="333" fill="#bfe6ff" font-size="8.5" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">local headers +</text>
<text x="88" y="346" fill="#bfe6ff" font-size="8.5" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">DEFLATE / STORE</text>
<text x="88" y="378" fill="#7fa8c4" font-size="8.5" text-anchor="middle">bin/lzip.rs</text>
<text x="88" y="392" fill="#7fa8c4" font-size="8.5" text-anchor="middle">.whl / .zip / .jar</text>
<!-- CENTRAL DIRECTORY -->
<rect x="168" y="222" width="150" height="196" rx="11" fill="url(#chip)" stroke="#7fc8ea" stroke-width="2"/>
<text x="243" y="246" fill="#eaf6ff" font-size="13.5" font-weight="700" text-anchor="middle">Central Directory</text>
<text x="243" y="262" fill="#9fc9e0" font-size="9.5" text-anchor="middle">seek tail — no full read</text>
<rect x="182" y="276" width="122" height="34" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="243" y="290" fill="#bfe6ff" font-size="8.4" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">read_central_</text>
<text x="243" y="301" fill="#bfe6ff" font-size="8.4" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">directory[_from]</text>
<rect x="182" y="318" width="122" height="34" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="243" y="332" fill="#bfe6ff" font-size="8.4" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">Vec<EntryLocation></text>
<text x="243" y="344" fill="#9fc9e0" font-size="8" text-anchor="middle">name · offset · sizes · crc</text>
<text x="243" y="374" fill="#86b3cc" font-size="8.5" text-anchor="middle">one-time serial parse</text>
<text x="243" y="388" fill="#86b3cc" font-size="8.5" text-anchor="middle">(only serial cost)</text>
<text x="243" y="408" fill="#7fa8c4" font-size="8.5" text-anchor="middle">central_dir.rs</text>
<!-- FILTER + SORT -->
<rect x="334" y="222" width="150" height="196" rx="11" fill="url(#chip)" stroke="#7fc8ea" stroke-width="2"/>
<text x="409" y="246" fill="#eaf6ff" font-size="13.5" font-weight="700" text-anchor="middle">filter + sort</text>
<text x="409" y="262" fill="#9fc9e0" font-size="9.5" text-anchor="middle">before any inflate</text>
<rect x="348" y="276" width="122" height="34" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="409" y="290" fill="#bfe6ff" font-size="8.2" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">needle / set /</text>
<text x="409" y="301" fill="#bfe6ff" font-size="8.2" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">suffixes · drop dirs</text>
<rect x="348" y="318" width="122" height="34" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="409" y="332" fill="#bfe6ff" font-size="8.4" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">sort_by_key</text>
<text x="409" y="343" fill="#bfe6ff" font-size="8.4" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">local_header_offset</text>
<text x="409" y="374" fill="#86b3cc" font-size="8.5" text-anchor="middle">sorted ⇒ sequential disk</text>
<text x="409" y="388" fill="#7CFFB2" font-size="8.5" text-anchor="middle">in-memory path: keep CD order</text>
<text x="409" y="408" fill="#7fa8c4" font-size="8.5" text-anchor="middle">reader.rs:55</text>
<!-- BATCH READER (producer) -->
<rect x="500" y="196" width="176" height="248" rx="12" fill="url(#rail)" stroke="#7fc8ea" stroke-width="2.5"/>
<text x="588" y="220" fill="#eaf6ff" font-size="14" font-weight="700" text-anchor="middle">batch reader</text>
<text x="588" y="236" fill="#9fc9e0" font-size="10" text-anchor="middle">sequential producer</text>
<rect x="516" y="248" width="144" height="30" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="588" y="262" fill="#bfe6ff" font-size="8.8" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">BATCH_SIZE = 64</text>
<text x="588" y="273" fill="#9fc9e0" font-size="8" text-anchor="middle">fill_batch · reader.rs:122</text>
<rect x="516" y="284" width="144" height="44" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="588" y="298" fill="#bfe6ff" font-size="8.6" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">seek local header</text>
<text x="588" y="310" fill="#9fc9e0" font-size="8" text-anchor="middle">skip name + extra</text>
<text x="588" y="322" fill="#9fc9e0" font-size="8" text-anchor="middle">read compressed_size bytes</text>
<rect x="516" y="334" width="144" height="30" rx="5" fill="url(#slot)" stroke="#ffcf6f" stroke-width="1.6"/>
<text x="588" y="348" fill="#ffe3a6" font-size="8.2" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">with_capacity + set_len</text>
<text x="588" y="359" fill="#ffcf6f" font-size="8" text-anchor="middle">uninit buf, skip zero-fill</text>
<text x="588" y="386" fill="#7CFFB2" font-size="8.6" text-anchor="middle">one batch live at a time ⇒</text>
<text x="588" y="398" fill="#7CFFB2" font-size="8.6" text-anchor="middle">peak RAM bounded, file</text>
<text x="588" y="410" fill="#7CFFB2" font-size="8.6" text-anchor="middle">never fully loaded</text>
<text x="588" y="432" fill="#7fa8c4" font-size="8.5" text-anchor="middle">StreamingZipRead · reader.rs:38</text>
<!-- WORKERS -->
<rect x="692" y="188" width="214" height="264" rx="12" fill="url(#chip)" stroke="#7fc8ea" stroke-width="2.5"/>
<text x="799" y="212" fill="#eaf6ff" font-size="14.5" font-weight="700" text-anchor="middle">N workers — LPT fan-out</text>
<text x="799" y="229" fill="#9fc9e0" font-size="10" text-anchor="middle">self-dispatch, no barrier</text>
<rect x="712" y="242" width="174" height="34" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="799" y="256" fill="#bfe6ff" font-size="8.8" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">gatling_for_each_balanced</text>
<text x="799" y="268" fill="#9fc9e0" font-size="8" text-anchor="middle">reader.rs:175 · forkjoin.rs:209</text>
<rect x="712" y="282" width="174" height="34" rx="5" fill="url(#slot)" stroke="#ffcf6f" stroke-width="1.6"/>
<text x="799" y="296" fill="#ffe3a6" font-size="8.8" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">weight = uncompressed_size</text>
<text x="799" y="308" fill="#ffcf6f" font-size="8" text-anchor="middle">heaviest entry claimed first</text>
<rect x="712" y="322" width="174" height="30" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="799" y="339" fill="#bfe6ff" font-size="8.8" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">decompress_entry_raw</text>
<rect x="712" y="358" width="174" height="30" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="799" y="372" fill="#bfe6ff" font-size="8.8" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">linflate DEFLATE + CRC32</text>
<text x="799" y="383" fill="#9fc9e0" font-size="8" text-anchor="middle">method-0 STORE copied verbatim</text>
<text x="799" y="408" fill="#ff9c9c" font-size="8.6" text-anchor="middle">CRC mismatch ⇒ error, siblings run</text>
<text x="799" y="424" fill="#86b3cc" font-size="8.6" text-anchor="middle">each entry = independent DEFLATE unit</text>
<text x="799" y="440" fill="#7fa8c4" font-size="8.5" text-anchor="middle">entry.rs:93 · linflate</text>
<!-- COLLECT -->
<rect x="922" y="222" width="132" height="196" rx="11" fill="url(#rail)" stroke="#7fc8ea" stroke-width="2"/>
<text x="988" y="246" fill="#eaf6ff" font-size="13.5" font-weight="700" text-anchor="middle">collect</text>
<text x="988" y="262" fill="#9fc9e0" font-size="9.5" text-anchor="middle">original index order</text>
<rect x="936" y="276" width="104" height="34" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="988" y="290" fill="#bfe6ff" font-size="8.2" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">results in</text>
<text x="988" y="301" fill="#bfe6ff" font-size="8.2" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">CD / offset order</text>
<rect x="936" y="318" width="104" height="34" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="988" y="332" fill="#bfe6ff" font-size="8.2" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">VecDeque buf</text>
<text x="988" y="343" fill="#9fc9e0" font-size="8" text-anchor="middle">Iterator yields</text>
<text x="988" y="374" fill="#86b3cc" font-size="8.5" text-anchor="middle">rebalance changes claim</text>
<text x="988" y="387" fill="#86b3cc" font-size="8.5" text-anchor="middle">order, not output order</text>
<text x="988" y="408" fill="#7fa8c4" font-size="8.5" text-anchor="middle">reader.rs:188</text>
<!-- OUTPUT -->
<rect x="1064" y="252" width="96" height="140" rx="10" fill="url(#chip)" stroke="#7fc8ea" stroke-width="2"/>
<text x="1112" y="276" fill="#eaf6ff" font-size="12.5" font-weight="700" text-anchor="middle">output</text>
<rect x="1076" y="292" width="72" height="30" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="1112" y="306" fill="#bfe6ff" font-size="7.4" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">Vec<ZipEntry></text>
<text x="1112" y="316" fill="#9fc9e0" font-size="7.4" text-anchor="middle">lib.rs:58</text>
<rect x="1076" y="328" width="72" height="30" rx="5" fill="url(#slot)" stroke="#6fd3f5" stroke-width="1.4"/>
<text x="1112" y="341" fill="#bfe6ff" font-size="7.4" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">or extracted</text>
<text x="1112" y="351" fill="#bfe6ff" font-size="7.4" text-anchor="middle" font-family="'DejaVu Sans Mono',monospace">files (CLI)</text>
<text x="1112" y="378" fill="#7fa8c4" font-size="7.8" text-anchor="middle">parwrite.rs:85</text>
<!-- FLOW -->
<g stroke="#6fd3f5" stroke-width="3" fill="none">
<path d="M152 320 H166" marker-end="url(#ah)"/>
<path d="M318 320 H332" marker-end="url(#ah)"/>
<path d="M484 320 H498" marker-end="url(#ah)"/>
<path d="M676 320 H690" marker-end="url(#ah)"/>
<path d="M906 320 H920" marker-end="url(#ah)"/>
<path d="M1054 322 H1062" marker-end="url(#ah)"/>
</g>
<!-- next-batch recycle -->
<path d="M922 400 C 820 470, 660 470, 588 452" stroke="#ffcf6f" stroke-width="2" fill="none" stroke-dasharray="4 3" marker-end="url(#ah)"/>
<text x="740" y="486" fill="#ffcf6f" font-size="9" text-anchor="middle">batch drained → producer fills the next 64 (bounded memory)</text>
<!-- ground rail -->
<rect x="168" y="536" width="892" height="44" rx="9" fill="url(#rail)" stroke="#7fc8ea" stroke-width="2"/>
<text x="186" y="554" fill="#dff1ff" font-size="12" font-weight="700">honest</text>
<text x="186" y="571" fill="#bcd9ec" font-size="10.5">Near-verbatim twin of ljar (JAR ⊂ ZIP). Entries ARE independent by format (each its own DEFLATE/STORE stream + CRC-32) — the only serial cost is the one-time Central Directory parse; LPT weight = uncompressed_size stops a skewed archive tail-choking one core. Heavy bench numbers land in the README A/B/C mashup.</text>
</svg>