nx_cdc_lib.nx
buildroot/runtime/nx_cdc_lib.nx
about
nx_cdc_lib.nx -- CONTENT-DEFINED CHUNKING (FastCDC gear, normalized) as a LIBRARY (/compare/dataio DI5, 2026-09-05).
WHY: fixed-size chunking re-keys every chunk after an insertion, so a one-byte edit near the head of a 400 KB
artifact makes every following chunk "new" to a receiver that already holds the previous version -- the whole file
ships again. Content-defined boundaries (a rolling gear hash, cut where its low bits are zero) re-align within one
chunk of the edit, so only the touched region is new. This is the FastCDC shape (Xia et al., USENIX ATC 2016, the
dataio board's pinned reference): a 256-entry gear table, a one-shift-one-add rolling fingerprint, a minimum length
skipped outright, NORMALIZED chunking (a stricter mask before the average, a looser one after, so lengths cluster
around the average) and a hard maximum.
EVERYTHING IS DERIVED, NOTHING TUNED. The gear table is SHA-256 of a NAMED seed and the byte value -- reproducible on
any host, so no table ships that could drift. The mask bit counts come from log2(avg). min, avg and max belong to the
CALLER: nx_content_put derives them from the ONE wire chunk constant it already owns (max = the wire chunk, so every
content-defined chunk still fits one call).
HONESTY LIMITS, stated: the masks take the LOW bits of the fingerprint (the paper spreads the bits; the low-bit
variant is simpler and its statistics are PROVEN by nx_cdc_gate on a pseudo-random corpus rather than assumed). The
final chunk may be shorter than min. This lib never reads a file or the clock; it computes over a buffer.
license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 2 imports · 5 importers
imports: nx_syscalls.nxnx_sha256.nx
imported by: _cdc_fixture_gen.nxnx_cdc_gate.nxnx_content_put.nxnx_content_put_client.nxnx_content_put_gate.nx
structs
| none |
consts
| 23 | const CDC_GEAR_N: i64 = 256 |
| 24 | const CDC_GEAR_W: i64 = 8 // one i64 per gear entry |
| 25 | const CDC_GEAR_BYTES: i64 = 2048 // CDC_GEAR_N x CDC_GEAR_W |
| 26 | const CDC_SEED: *u8 = "nx-cdc-gear-v1" as *u8 |
| 27 | const CDC_DIGEST_B: i64 = 32 |
| 28 | const CDC_MIN_BITS: i64 = 4 // an average below 16 bytes has no meaningful mask: refused, never guessed |
| 29 | const CDC_ERR: i64 = 0 - 1 |
functions
| 31 | func cdc_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } called by 1: cdc_gear_table |
| 34 | func cdc_gear_table(out: *u8) -> i64 |
| 51 | func cdc_gear_at(tbl: *u8, b: i64) -> i64 |
| 58 | func cdc_mask_bits(avg: i64) -> i64 { var b: i64 = 0; var v: i64 = avg; while v > 1 { v = v / 2; b = b + 1 } return b } |
| 60 | func cdc_mask(bits: i64) -> i64 |
| 70 | func cdc_next_boundary(tbl: *u8, buf: *u8, n: i64, start: i64, min: i64, avg: i64, max: i64) -> i64 |
| 103 | func cdc_plan(tbl: *u8, buf: *u8, n: i64, min: i64, avg: i64, max: i64, offs: *i64, cap: i64) -> i64 |
| 127 | func cdc_plan_fixed(n: i64, size: i64, offs: *i64, cap: i64) -> i64 called by 1: main |
| 148 | func cdc_chunk_digest(buf: *u8, offs: *i64, k: i64, out: *u8) -> i64 |
| 156 | func cdc_shared_digests(da: *u8, na: i64, db: *u8, nb: i64) -> i64 called by 1: main |