You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor(scan)!: replace ScanResult with closeable Chunk; ScanIterator implements Iterator<Chunk>
ScanIterator.hasNext() used to silently close the previous chunk's Arena,
invalidating any Array references the caller still held — a footgun the
compiler could not catch. Java has no borrow checker, so Rust-style lending-
iterator semantics cannot be enforced at compile time.
Move to idiomatic Java lifecycle:
- ScanResult → Chunk implements AutoCloseable. Each Chunk owns a confined
Arena holding its decoded buffers; close() releases the arena.
- ScanIterator now implements Iterator<Chunk>, AutoCloseable. hasNext() is
side-effect-free; next() returns a fresh Chunk and throws
IllegalStateException if a prior chunk is still open. Iterator close()
closes any still-open chunk as a safety net.
- forEachRemaining(Consumer<? super Chunk>) is overridden to wrap each
next() in try-with-resources, so the standard JDK method works safely
without inventing a custom forEachChunk.
After Chunk.close(), touching previously-returned Array views raises FFM's
scope check (IllegalStateException) instead of returning undefined data.
Idiomatic call site:
try (var reader = VortexReader.open(path);
var iter = reader.scan(opts)) {
while (iter.hasNext()) {
try (Chunk chunk = iter.next()) {
...
}
}
}
CLAUDE.md gains a "prefer idiomatic modern Java" rule documenting the
preference for overriding standard JDK methods (forEachRemaining) over
parallel custom names. README, docs/explanation.md, docs/reference.md and
CHANGELOG updated. All call sites (CLI, CSV exporter, benchmarks, all unit
and integration tests) migrated to try-with-resources or forEachRemaining.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|`hasNext()`| Side-effect-free. Returns whether another chunk is available after zone-map pruning. |
138
+
|`next()`| Returns a fresh `Chunk` whose arena the caller closes. Throws `IllegalStateException` if a prior `Chunk` is still open, or `NoSuchElementException` if exhausted. |
139
+
|`forEachRemaining(Consumer)`| Overridden to wrap each `next()` in try-with-resources so chunks auto-close. |
140
+
|`close()`| Releases iterator state and closes any chunk still open. |
0 commit comments