Skip to content

feat: context recycling (reset) + dictionaries on contexts (load/ref)#26

Merged
dfa1 merged 2 commits into
mainfrom
feat/context-reset
Jun 27, 2026
Merged

feat: context recycling (reset) + dictionaries on contexts (load/ref)#26
dfa1 merged 2 commits into
mainfrom
feat/context-reset

Conversation

@dfa1

@dfa1 dfa1 commented Jun 27, 2026

Copy link
Copy Markdown
Owner

Two related steps toward closing the dictionary story on the one-shot contexts.

1. Context reset — ZSTD_CCtx_reset / ZSTD_DCtx_reset

ZstdCompressCtx.reset(ZstdResetDirective) / ZstdDecompressCtx.reset(...) recycle a context's native state between frames without freeing and recreating it.

  • SESSION_ONLY — abort the current frame, drop unflushed data; keep level, parameters, dictionary.
  • PARAMETERS / SESSION_AND_PARAMETERS — also restore defaults and clear the dictionary; valid only between frames.

A parameter reset returns native state to defaults, so the compress context drops its cached level back to Zstd.defaultCompressionLevel() to stay in sync.

2. Dictionaries on contexts — load / ref

The per-call compress(src, dict) overloads take the legacy dictionary path, which ignores the advanced parameters (checksum, window log, long-distance matching). To combine the two you need a sticky dictionary on the context:

  • loadDictionary(ZstdDictionary) / loadDictionary(MemorySegment) on both contexts — binds ZSTD_CCtx/DCtx_loadDictionary (previously wired only to the streams). The native MemorySegment overload is the zero-copy path.
  • refDictionary(ZstdCompressDict) / refDictionary(ZstdDecompressDict) — new ZSTD_CCtx_refCDict / ZSTD_DCtx_refDDict. Attaches a pre-digested dictionary by reference: no copy, no per-call digest. Borrowed — the caller keeps the digest alive. The pooled-context hot path that pairs with reset.

A sticky dictionary now lets the normal compress path honour dictionary + advanced parameters together. A parameter reset, or passing null, clears it.

Tests

  • ZstdParameterTest$Reset (6): session-only keeps level, parameter reset restores default level (both PARAMETERS and SESSION_AND_PARAMETERS), dictionary round-trips after reset, decompress ctx decodes after reset, null directive → NPE.
  • ZstdDictionaryTest$StickyDictionary (6): dict+checksum combine, referenced digest survives session reset, parameter reset clears the loaded dict, null clears it, native-segment load round-trips, heap segment rejected.
  • ZstdJniInteropTest$Dictionary (+2): loaded-dict-with-checksum frame and referenced-digest frame both decode in zstd-jni.
  • Full verify green: 81 integration tests, 0 Checkstyle violations, javadoc clean.

Docs

  • docs/supported.mdC/DCtx_reset, CCtx_refCDict, DCtx_refDDict flipped to bound; advanced-parameter count 8 → 12, total 55 → 59; loadDictionary mapping now lists the contexts.
  • docs/how-to.md — "Reset a context to recycle it" and "Compress with a dictionary and advanced parameters" recipes.
  • CHANGELOG.md[0.5] Added entries.

🤖 Generated with Claude Code

Bind ZSTD_CCtx_reset and ZSTD_DCtx_reset behind a new ZstdResetDirective
enum (SESSION_ONLY, PARAMETERS, SESSION_AND_PARAMETERS), exposed as
ZstdCompressCtx.reset(...) / ZstdDecompressCtx.reset(...). Lets a pooled
or long-lived context recycle its native state between frames without
freeing and recreating it.

A parameter reset clears the context back to defaults, so the compress
context drops its cached level back to Zstd.defaultCompressionLevel() to
stay in sync with the native state.

Document the recipe in docs/how-to.md, flip both symbols to bound in
docs/supported.md (advanced-parameter count 8 -> 10, total 55 -> 57), and
add the 0.5 changelog entry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dfa1 dfa1 force-pushed the feat/context-reset branch from cc5b56c to 4a8976b Compare June 27, 2026 05:57
@dfa1 dfa1 changed the title feat: ZSTD_CCtx_reset / ZSTD_DCtx_reset context recycling feat: context recycling (reset) + dictionaries on contexts (load/ref) Jun 27, 2026
Bind ZSTD_CCtx/DCtx_loadDictionary on the one-shot contexts (previously
only on streams) and the new ZSTD_CCtx_refCDict / ZSTD_DCtx_refDDict.

A sticky dictionary on a context lets compression combine a dictionary
with the advanced parameters (checksum, window log, long-distance
matching) via the compress2 path — impossible through the per-call
compress(src, dict) overloads, which route the legacy dictionary path.
refDictionary attaches a pre-digested CDict/DDict by reference (no copy,
no per-call digest), the pooled-context hot path that pairs with reset.
A parameter reset clears either.

loadDictionary takes a ZstdDictionary or a native MemorySegment
(zero-copy); refDictionary borrows the digest, so the caller keeps it
alive. Tests cover dict+checksum combine, ref-across-session-reset,
reset/null clearing, segment load, and zstd-jni interop on both frames.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dfa1 dfa1 force-pushed the feat/context-reset branch from c213a63 to f06ba23 Compare June 27, 2026 06:20
@dfa1 dfa1 merged commit 3dfd5b8 into main Jun 27, 2026
1 check passed
@dfa1 dfa1 deleted the feat/context-reset branch June 27, 2026 06:23
dfa1 added a commit that referenced this pull request Jun 27, 2026
…elog

Relocate docs/adr -> adr/ (top-level), rewriting the relative links for the
new depth. Link the ADR index from the README Documentation section. Add the
missing commit hash (3dfd5b8, #26) to the 0.5 "Added" changelog entries so
every line cites its commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant