Skip to content

Repros 780 - #787

Open
jshook wants to merge 4 commits into
779-nvqparametersidstringfor-throws-missingformatargumentexceptionfrom
repros-780
Open

jshook wants to merge 4 commits into
779-nvqparametersidstringfor-throws-missingformatargumentexceptionfrom
repros-780

Conversation

@jshook

@jshook jshook commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Review: repros and fixes for the cache path this makes reachable

Reviewed at f8ca7e51. The format fix is right and the key test passes. Two things in the cache path it enables, each with a failing test and a fix on repros-780, one commit each:

# Issue Repro Fix
1 A cached NVQ compressor is reloaded with ProductQuantization.load and fails (the point in the approving comment; #776 is still open) fa932e21 63c32578
2 Grid.cachedCompressors is an IdentityHashMap keyed by freshly formatted strings, so the memo never hits: every resolution reloads from disk and keeps the previous instance (pre-existing, since #244) f90f1f56 cc5fd20d

1. GridCompressorCacheTest.cachedNvqCompressorLoadsBackAsNvq resolves an NVQParameters compressor through Grid.getCompressor twice, clearing the memo in between so the second call takes the on-disk path. On the head it dies in ProductQuantization.load reading NVQ's version int as a centroid length (IndexOutOfBoundsException from the mapped reader on a small dataset; a corrupt PQ on a large one). The fix adds CompressorParameters.loadCompressor(RandomAccessReader), overridden for PQ and NVQ, and has loadFromCache call it. Same name and shape as the loader in #776, so whichever merges second resolves trivially.

2. cachedCompressors.computeIfAbsent(cp.idStringFor(ds), ...) never finds an earlier key because idStringFor formats a new String each call and the map compares by identity. sameKeyReturnsTheMemoizedCompressor resolves one key twice and expects the same instance and one entry; on the head it gets two instances and two entries. Fix: HashMap. getCompressor is only called from the sequential configuration loop.

With both fixes the cache tests, the PR's key test, and the full reactor suite pass on JDK 24 with the native provider (531 tests).

Minor: CompressorParametersTest's anonymous DataSet omits @Override, so a method removed from the interface leaves a dead stub instead of a compile error.

Resolve an NVQParameters compressor through Grid.getCompressor twice,
clearing the in-memory memo in between so the second call takes the
on-disk path. loadFromCache reads every cache file with
ProductQuantization.load, which takes NVQ's leading version int as a
centroid length and runs off the end of the file:
IndexOutOfBoundsException from the mapped reader.
Each compressor type has its own on-disk format, so loadFromCache now
calls CompressorParameters.loadCompressor instead of
ProductQuantization.load; PQ and NVQ parameters read back their own
type. Same shape as the loader in #776 so the two merge cleanly.
Grid.cachedCompressors is an IdentityHashMap keyed by strings that
idStringFor formats afresh on every call, so a second resolution of the
same key misses, reloads the compressor from disk, and adds another
entry. Resolve one key twice and expect the same instance and one entry.
idStringFor formats a new String on every call, so the IdentityHashMap
never matched an earlier key: each resolution reloaded the compressor
from disk and kept the previous instance in the map. Use a HashMap.
@github-actions

github-actions Bot commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

Before you submit for review:

  • Does your PR follow guidelines from CONTRIBUTIONS.md?
  • Did you summarize what this PR does clearly and concisely?
  • Did you include performance data for changes which may be performance impacting?
  • Did you include useful docs for any user-facing changes or features?
  • Did you include useful javadocs for developer oriented changes, explaining new concepts or key changes?
  • Did you rebase your branch onto the latest main for regression testing and PR submission?
  • Did you trigger regression testing via Run Bench Main and review results?
  • Did you adhere to the code formatting guidelines (TBD)
  • Did you group your changes for easy review, providing meaningful descriptions for each commit?
  • Did you ensure that all files contain the correct copyright header?
  • Did you add documentation for this feature to the release notes directory?

If you did not complete any of these, then please explain below.

@MarkWolters MarkWolters added the Non Main - do not review A PR going from one branch to another branch other than main. Do not review. label Nov 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Non Main - do not review A PR going from one branch to another branch other than main. Do not review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants