Commit Graph
7446 Commits
Author SHA1 Message Date
Jonathan Shook 085e545787 feat(engine): measure recall against the neighbors that exist
A filtered ground truth pads a query whose predicate matches fewer than k rows with sentinels no search can return, and the strict recall divides by k regardless, so a small slice reads low by construction. attainable_recall leaves the sentinels out of the denominator: the share of the neighbors that exist which were found. A row with nothing attainable scores 1.0; how many such rows there are is a fact about the ground truth, not the search.
2026-09-16 07:04:49 +00:00
Jonathan Shook d557669a80 docs(vectordata): record the 2.1.2 baseline, selectors, and version 3
The compatibility contract moves to the reference's 33fedae commit and states the absent-version rule, stated parents, the derived axis, the tag schema, the selector grammar and cardinality, the group prebuffer, and the remaining representation differences. The README documents selecting profiles and the version-3 layout.
2026-09-16 01:40:42 +00:00
Jonathan Shook 28ac06286c feat(vectordata): prebuffer the profiles a selector names
A group prebuffers the named profiles in the order a set selector resolved to, each facet against its declared window through the same planner, after tallying the announced total and reporting it as a large download at 250 MiB. One view per profile serves both the tally and the fetch, so the offset index a plan loads is the one the prebuffer uses.
2026-09-16 01:40:42 +00:00
Jonathan Shook b6ddfcc575 feat(vectordata): select profiles by selector on the group and catalog surfaces
A group answers what a selector reads of every profile, structure as loaded after inheritance and attributes its own, in size order: default first, then by base_count or the name read as a count, then naturally by name. A catalog open takes a selector and refuses a set, openProfiles returns the set, openProfile splits a spec by its head's shape, and a catalog entry resolves the same selection from its listed layout before anything is fetched, exposing the listed format version.
2026-09-16 01:40:28 +00:00
Jonathan Shook 9f3efebe85 feat(vectordata): read format version 3 and hold an absent version to 1
Version 3 is stated parents and a profile tag schema: every profile but default names a real parent or the load is refused naming the profiles involved, and the schema loads in naming order. An unversioned manifest is read as the least it could be and refused, naming the version to declare, when its content needs more. The axis of an inheritance step is derived from base_count rather than the parent's name: base facets are re-cut to the child's count, the per-size outputs, metadata_results now among them, do not cross a size step, and base_count and maxk inherit as the reference's do. A parent YAML reads as a number is the name it spells. Test fixtures that declare a series now state version 2.
2026-09-16 01:39:58 +00:00
Jonathan Shook 4a1f6a4d06 feat(vectordata): parse profile selectors and split a spec by its head's shape
The reference's one selector parser: the grammar, the value readings by spelling, the structural keys, list and map matching, case folding, and the set and single-profile resolution rules with their messages. A spec's head is found by shape, so a URL's port and a selector's colon are told apart. A regular expression outside the RE2 subset is refused rather than accepted here and rejected there.
2026-09-16 01:39:58 +00:00
Jonathan Shook 97de9ab974 feat(vectordata): report a uniform series' shard count on its descriptor
A series has no single source path, and a caller reporting what opening the facet will cost needs the number without realizing the series first.
2026-09-16 01:39:58 +00:00
Jonathan Shook a3753e205d feat(vectordata): read manifests under the YAML 1.2 core schema
The engine's default JSON schema reads a tilde as the string it spells; the reference writes a naming tag in a profile_tags schema as a tilde, and reads under the core schema, where it is null.
2026-09-16 01:39:58 +00:00
Jonathan Shook 0b7ebc12a9 docs(cqld4): state the predicate forms and load guidance in the predicated workload
Derive the form survey into the description, note that the rampup
must be throttled against a single small node since an overloaded node
drops mutations that errors=count only counts, and say which of the
nine indexed columns carry the predicates so a lighter variant is an
informed choice.
2026-09-05 04:28:25 +00:00
Jonathan Shook 6d6906545b feat(virtdata): survey a predicate facet's forms before the first cycle
PredicateClause reads every predicate once when it is built,
initializes each distinct shape then, and reports the forms on the
console with the number of predicates of each, so how many prepared
statements a run will hold is known before it starts. A shape that
cannot be prepared is reported with the others and refused after the
survey rather than on the cycle that would have met it. The
predicateForms expression takes the same survey quietly for a
workload's description.
2026-09-05 04:28:25 +00:00
Jonathan Shook c36c6933f1 feat(cqld4): drive the predicated search through prepared forms
The predicate's structure is reified through the template: the
predicate bind point takes a fragment, the adapter prepares one
statement per predicate shape keyed by its fingerprint, and the
comparands bind as parameters typed from the metadata fields. The
rendered form stays available through RecordText for a driver that
cannot prepare.
2026-09-05 00:15:52 +00:00
Jonathan Shook dc9626d4b8 feat(cqld4): prepare a statement once per form when a bind value is a fragment
When a bind point of a prepared op yields a fragment, its text takes
the bind point's place in the statement and its values take the place
of that bind value. The space holds one prepared statement per op and
form key, prepared the first time the form is seen; a cycle without a
fragment takes the single-statement path unchanged. A template with one
fragment is keyed by the fragment's own key, so a cycle allocates no
key.
2026-09-05 00:15:52 +00:00
Jonathan Shook e28599af18 feat(virtdata): prepare each predicate shape once as a fragment
PredicateClause turns each predicate into a prepared fragment: the
shape's WHERE clause with a marker per comparand, the comparands typed
from the metadata fields they constrain, and the fingerprint as the
form key. A form is initialized once, its clause composed and its
binder compiled on the first predicate of that shape, and every later
cycle of the shape costs the record read, the fingerprint lookup, and
the value projection.
2026-09-05 00:15:52 +00:00
Jonathan Shook 19bee2506d feat(vectordata): bind an already-decoded predicate through its binder
A caller that decodes a record itself, to read its fingerprint and pick
one binder per shape, binds the node directly with the same shape check
rather than decoding twice; the binder also names the shape it was
compiled against.
2026-09-05 00:15:52 +00:00
Jonathan Shook 7a7928b4e9 feat(virtdata): reify a per-cycle statement form as a prepared fragment
A bind value that is part statement and part parameters: text with
positional markers, the values for them, and the key of the form the
text has. Equal keys mean equal text, so an adapter prepares each form
once and binds every later fragment of that form through it.
2026-09-05 00:15:52 +00:00
Jonathan Shook cdbd9409e4 docs(vectordata): show the rendering mapper in the remote-access guide 2026-09-05 00:02:51 +00:00
Jonathan Shook 9e4ab0490b feat(cqld4): add a predicated vector search workload over a vectordata profile
Every dataset-shaped parameter is derived from the profile: the table's
metadata columns from the record layout, dimensions and k from the
facets, the similarity from the attributes. Rampup binds each base
vector with its metadata record field by field through a prepared
insert; search runs each query under the predicate published for it,
rendered as a WHERE clause since the predicates differ in shape, with
SAI indexes on every column they reference, and verifies against the
pre-filtered ground truth, padding a short result set the way the
ground truth pads a short match set.
2026-09-05 00:02:51 +00:00
Jonathan Shook 166d297bde feat(virtdata): render records and derive CQL columns from a layout
RecordText renders each record of a facet in a named vernacular — the
rendering contract beside the binding one, for a statement whose shape
changes per cycle. CqlColumns derives CQL column definitions from a
record layout, typed from the bind types so the columns accept what the
binders produce, and the recordLayout, recordFields, and recordColumns
expression functions expose the layout to a workload at load time.
2026-09-05 00:02:51 +00:00
Jonathan Shook d461f5831b fix(vectordata): render a CQL conjunction without grouping parentheses
A CQL WHERE clause is a bare list of relations and Cassandra rejects a
conjunction wrapped in parentheses, which is what the reference's CQL
vernacular emits. Render the bare form for CQL, keep the grouping for
SQL and for the != and OR rewrites, and record the deviation in the
contract for upstream reconciliation.
2026-09-05 00:02:51 +00:00
Jonathan Shook 0a6c01031c docs(vectordata): show the record-binding functions in the remote-access guide
Add the four record mappers to the inline op examples and say why they
take no prefetch mode: a slab is paged, so a record fetches its page.
2026-09-04 23:34:00 +00:00
Jonathan Shook 62b49e8a52 feat(virtdata): bind vectordata records as projective functions
Four mappers over a facet of opaque records, each learning the layout
once and resolving no field name per cycle: RecordField projects one
field to the Java value its wire type says, RecordFields binds a record
to named values in bind order, RecordForm binds under a form the facet
declares, and PredicateParams binds a predicate's comparands as
parameters typed from the metadata fields they constrain. The shared
projection maps bind types to driver-ready Java values, reading varint
and decimal payloads as big-endian two's complement.
2026-09-04 23:34:00 +00:00
Jonathan Shook e0331a9e46 build(vectordata): compile at the reactor's Java 25 standard
Drop the module's own release override, the only Java-level pin in the
reactor, so it inherits the 25 standard every other module builds at.
2026-09-04 23:34:00 +00:00
Jonathan Shook 9bb45d0777 docs(vectordata): describe record binding in the contract
State the binding contract and the bind-type asymmetry, replace the
note that binding forms are out of scope with the three deviations that
remain — field views as objects, form extras as node values, and the
raw predicate scanner not ported — and show the cycle loop.
2026-09-04 22:50:06 +00:00
Jonathan Shook 28b70170bc feat(vectordata): bind records to operation parameters
The scaffolding projective functions build on: a Layout learned once
from a facet's first record, a Binder compiled against it that binds
by position with parameter renames applied at compile time, forms read
from the facet's forms namespace with one implicit form when it has
none, and a PredicateBinder that types each condition from the field's
tag rather than the comparand's variant and refuses a record whose
leader byte or shape disagrees with the template. BindType is its own
exhaustive mapping from the tag, distinct from the rendering one.
2026-09-04 22:50:06 +00:00
Jonathan Shook 0f1b0e8a30 feat(vectordata): walk MNode records in place
Port the reference's raw scan: a record's fields reached as views over
its own bytes, names skipped rather than copied, every tag advanced at
its true width. A Field reads its payload through accessors typed by
the wire form — a Half as a float, the temporal trio as text, Nanos as
two numbers — or materializes the AST view on request. Schema discovery
and predicate flattening ride on the same walk.
2026-09-04 22:50:06 +00:00
Jonathan Shook 97fd3e2495 docs(vectordata): describe the records layer in the contract
State the record, wire-format, vernacular, and facet-shape parts of the
contract, and replace the note that slab records are not decoded with
the three deviations that remain: a tree codec in place of serde,
document-order JSON parsing, and binding forms out of scope.
2026-09-04 22:37:28 +00:00
Jonathan Shook e315c4bca5 feat(vectordata): open a slab facet's records by ordinal
A slab facet opens through openFacetRecords as a RecordFacet, one
container per file with each shard of a series based at zero, and a
codec applied to it yields a typed reader. Every extension the spec
names carries a facet shape, facetShape answers it, and each reader
refuses the other shape by naming the one that opens it. Reading one
remote record costs its page, not the file.
2026-09-04 22:37:28 +00:00
Jonathan Shook c0afc9b030 feat(vectordata): render and parse records in every vernacular
Stage 2 of the codec: the thirteen vernaculars the reference names,
each rendering both node kinds in its own syntax. JSON, YAML, SQL, CQL,
CDDL, and readout parse back with the reference's type inference; the
schema, value, and display forms refuse to, naming themselves. The tree
form stands in for a serde target.
2026-09-04 22:37:28 +00:00
Jonathan Shook f58ffbc2d8 feat(vectordata): decode ANode records in both dialects
Port the reference's stage-1 codec: an MNode as a leader byte, a field
count, and tagged values over the 29 type tags; a PNode as a pre-order
predicate tree in the indexed, named legacy, and named typed wire forms.
Fingerprints and congruence compare shape without values, the Display
grammar reads back through PNodeDisplay, and PredicateEvaluator applies
a tree to a record with the reference's coercions.
2026-09-04 22:37:28 +00:00
Jonathan Shook 8f6df22a7c test(vectordata): make the hosted canary walk a workload's paths
- the canary asserted only that the base had records; it now reads
  base records at both ends of the profile's window, across a shard
  seam when the base is a series, a query, and a neighbor row whose
  entries name base records
- every facet is planned against the window it declares, a slab's
  included, and none may degrade to a whole-facet fetch — the case a
  sized profile over a slab-backed dataset presents
- a small base window is prefetched and read back resident, and the
  run prints what it found so a release log carries the numbers
2026-09-04 21:36:15 +00:00
Jonathan Shook 3c300fe927 test(virtdata): read a sharded dataset through the vector bindings
- a binding window over a series warms the shards it spans and still
  addresses records by absolute ordinal across the seam
- a background prefetch over a series plans one request per shard
- a sized profile over a series clips at its base_count, serves its
  own ground truth, and inherits queries from default
5.25.16-release 5.25.16-preview
2026-09-04 21:17:39 +00:00
Jonathan Shook cc4c23eded test(vectordata): mirror the reference's series and slab coverage
- a series whose shards disagree on shape is refused naming the odd
  one; a gap in the middle of a series is named, never skipped
- two shards sliced from one file share one storage and address their
  own windows of it; a local series reports local and complete
- the weakest access mode is the one true of every file, and a series
  with one unverified shard reports it over HTTP; a range-less server
  hands each shard over whole and the series still reads as one
- a mapped series window is prefetched without a fallback in play
- the whole-profile prebuffer visits slab facets whole, a sharded slab
  shard by shard, and an explicit entry that slices a slab plans its
  pages by file ordinal
2026-09-04 21:17:39 +00:00
Jonathan Shook 9be7d0c0b5 docs(vectordata): record slab windowing and namespaces in the contract
- slab containers are planned, prefetched, and prebuffered by the pages
  a window spans, through the index in the slab's tail
- a source may name a slab namespace, and the rule that keeps a URL
  scheme or drive letter from reading as one
- slab records are not decoded here; the clarification names what a
  slab facet does and does not take part in
2026-09-04 21:17:39 +00:00
Jonathan Shook 989e6e82b5 feat(vectordata): price a slab window at the pages it spans
- a slab window still reported degrades_to_full_download, so a sized
  profile over a slab-backed dataset was refused by the whole-profile
  prebuffer where the reference fetches the pages the window spans
- the slab's page index is read from the tail: the 16-byte footer, the
  terminal pages page or namespaces page, the named namespace's pages
  page when indirected, and the last page's own record count — a
  bounded read of two short pages, never a walk of the file, reported
  as prerequisite bytes
- a window maps to the byte extent of the pages holding it, one
  contiguous range since pages lie in ordinal order; a window running
  past the end stops at the last page, one starting past the end
  degrades rather than fabricating a range
- tests write slabs in the slabtastic layout, single- and
  multi-namespace, and check every ordinal against its page, the
  seams, the planner's bounds, a slab series across its seam, and over
  HTTP that ten records fetch a page and a sized profile fetches only
  its window's pages
2026-09-04 21:17:39 +00:00
Jonathan Shook d218e44913 feat(vectordata): carry a slab namespace through a source locator
- a source may name a namespace within a slab — `m.slab:content`,
  `m.slab:ns:[0..1K]` — or carry one beside it under namespace:/ns:,
  which applies to every source that names none of its own
- the text after the last `:` is a namespace only when the path before
  it has an extension and the text after names no directory, so a URL
  scheme or a drive letter never reads as one
- the namespace travels with the facet descriptor and with each shard
  entry, and the per-format mapping is addressed by the locator — the
  file plus its namespace — rather than the file alone
2026-09-04 21:17:39 +00:00
Jonathan Shook c488b3ad23 version bump 2026-09-04 21:17:39 +00:00
Jonathan Shook e5441a9594 docs(vectordata): true up the compatibility contract to vectordata-rs 2.1.1
- baseline moves from crate 1.8.0 to 2.1.1; the contract records the
  series model, the two window coordinate spaces, format_version,
  the `=count` suffix, axis-aware inheritance, shard-qualified plans,
  the window-aware whole-profile prebuffer, and the shard error
  taxonomy
- clarifications named where Java differs: a windowed reader's
  prebuffer fetches its window where the reference's is a no-op, and
  evicting a file from a series' open-file budget releases a
  reference rather than closing shared storage
- the README shows the uniform and explicit declaration forms and the
  whole-profile prebuffer
2026-09-04 21:17:39 +00:00
Jonathan Shook 99b98fa913 fix(vectordata): prebuffer a profile against the windows its facets declare
- the whole-profile prebuffer fetched every facet's file whole, so a
  sized profile over a large base downloaded the whole base while the
  selective prefetch beside it fetched only the window
- prebuffer(fallback, progress) now plans every facet with the
  shard-aware planner against the window it declares for itself, a
  series included, and refuses a declared window the format cannot
  map under REFUSE exactly as a requested window is; every facet is
  planned before any is fetched, and prebuffer(progress) is the
  REFUSE form
- the reader a view hands back for a windowed facet warms its window
  rather than the file it was cut from
- remote tests: a 500-record window over a three-shard base leaves the
  last shard untouched, through the view, through an inherited
  base_count window, and through the reader
2026-09-04 21:17:39 +00:00
Jonathan Shook c76a582dbe fix(vectordata): inherit profile facets by the axis they vary along
- neighbor facets no longer cross the size axis: a sized profile that
  omits its own ground truth fails with "lacks facet" instead of
  silently serving the full base's, since ground truth is derived
  from base_count
- base_vectors and metadata_content inherit under the child's
  base_count window unless the parent's already carries one
- `inherits:` names a parent, with `extends:` kept as a spelling; an
  unknown or self parent falls back to default, and a cycle leaves its
  members, and anything inheriting from them, with what they declare
- a `partition: true` profile is an oracle partition with independent
  base vectors and inherits nothing
2026-09-04 21:17:39 +00:00
Jonathan Shook 19f04125ee feat(vectordata): read a facet spread across several files
- a facet may be a series: the uniform form names `base__NNNN.fvec`
  with shard_stride, shard_count, and record_count; the explicit form
  lists entries in the source grammar, each bare, `=`-counted,
  windowed, or both, checked against each other
- ordinals map in O(1) whenever the lengths are uniform however the
  series was spelled, and by prefix-sum search otherwise; an entry
  window is in that file's ordinals, the facet window is in facet
  ordinals, and a suffix on a uniform pattern is the facet window
- storage, sidecars, and offset indexes are per file, so two shards of
  one file share one of each; the readers present a single surface,
  refuse shards that disagree on shape, and name a missing shard
  rather than reading a shorter facet
- prefetch plans carry ShardRange in place of ByteRange, decompose a
  window across the shards it spans, never merge across shards, and
  sum prerequisite bytes per file; a whole-facet request names every
  shard, and cache statistics report the weakest access mode
- format_version is a minimum reader requirement: a dataset above 2,
  or one stating less than its content needs, is refused naming both
  numbers; declarations are checked for self-consistency at load, and
  a directory falls back to knn_entries.yaml only when dataset.yaml is
  absent, so a refusal keeps its diagnosis
- a series holds open no more files than a quarter of the descriptor
  soft limit, floor 8, or VECTORDATA_SHARD_FD_CAP
2026-09-04 21:17:39 +00:00
J S f999cce819 Merge pull request #2301 from nosqlbench/dependabot/github_actions/actions/setup-java-6.0.0
build(deps): bump actions/setup-java from 5.6.0 to 6.0.0
2026-09-04 10:46:43 -05:00
J S 55dd413097 Merge branch 'main' into dependabot/github_actions/actions/setup-java-6.0.0 2026-09-04 10:46:32 -05:00
J S 52857adaf3 Merge pull request #2300 from nosqlbench/dependabot/github_actions/softprops/action-gh-release-3.0.3
build(deps): bump softprops/action-gh-release from 3.0.2 to 3.0.3
2026-09-04 10:46:15 -05:00
J S dca4386feb Merge branch 'main' into dependabot/github_actions/softprops/action-gh-release-3.0.3 2026-09-04 10:45:59 -05:00
Jonathan Shook 5a82d60305 fix(expr-api): render datetime seconds even on a whole minute
The ISO forms of LocalTime and LocalDateTime omit the seconds field
when the second is 00, so currentTime(), currentDateTime(),
currentTimeInZone() and millisToDateTime() each returned a shorter
string once a minute — HH:mm instead of HH:mm:ss. That failed
testCurrentTime in CI roughly one run in sixty, and silently handed
workloads a differently-shaped timestamp the rest of the time.

Each now formats with an explicit pattern rather than toString(), which
also makes the truncatedTo(SECONDS) calls redundant.

The new test pins the boundary through millisToDateTime, whose instant
comes from the caller: the wall-clock functions can only be asserted
for shape, which catches this one second in sixty. It builds a
timestamp on a whole minute, requires the seconds to be there, and
repeats at second 30 so a fix in the other direction is caught too.
5.25.15-release 5.25.15-preview
2026-09-02 20:19:36 +00:00
Jonathan Shook 59d604aed6 fix(virtdata): binding windows warm records without renumbering them
A binding window re-based the reader to zero, so BaseVectors(spec,
'[50000..100000)') exposed indices 0..49999. A workload running the
cycles that window names then indexed past the end and failed, and it
only ever worked from cycle 0, where the re-basing is the identity. It
also disagreed with the two surfaces beside it: VariableFacet and
prefetchCycles both speak absolute ordinals.

The window now selects which records to warm and nothing else. Indices
are absolute everywhere, so cycles address the records they name, and
the fetch still covers only the window — a [50000..100000) slice of a
100k profile warms 74 MiB rather than the full 146 MiB.

Reads outside the window demand-page rather than failing, which is
load-bearing rather than lenient: VirtData probes a newly resolved
function with a small sample index before any cycle runs, so refusing
out-of-window reads leaves a window above zero unable to resolve at
all. A test pins that.

WindowedReader keeps its restricting behaviour for the windowedFacet
expression function, where a caller asks for a restricted reader
directly and no resolver probe is involved.
2026-09-02 19:36:03 +00:00
Jonathan Shook 52dc31bfce feat(virtdata): meter the background prefetch and reach it directly
Asking for a prefetch with progress meant asking for prefetch=false and
then a binding mode — two knobs that read as contradicting each other,
because the background expr function was the one prefetch form that
never got a meter, so the only way to see a background download was to
route it through a binding.

prefetchBackground now announces its plan and watches the handle like
every other form, and prefetchCyclesBackground takes the ordinal range
directly. With the API reachable at the surface, the demo asks for what
it wants in one word: prefetch=load blocks on prefetchCycles before the
run, prefetch=background hands back a metered handle that fetches while
the cycles run, prefetch=none leaves reads to demand-page. The binding
mode knob is gone.
2026-09-02 15:54:14 +00:00
Jonathan Shook 66fc07c15f docs(stdout): correct the demo workload invocation
The documented 'nb5 run vectordata_demo' does not work: run is itself a
command, so the workload name is parsed as a second one and resolves to
no service. The scenario form drops the run — 'nb5 vectordata_demo
dataset=<name>:<profile>' — and the long form names the full bundled
path, 'nb5 run workload=activities/examples/vectordata_demo.yaml'.
Both are now shown in the workload and the guide.

Verified against the 5.25.15-release binary: the workload is bundled
and listed, both corrected forms load it, and a real dataset run meters
the download and reads base, query, and neighbor records.
2026-09-02 01:04:19 +00:00
Jonathan Shook 0b9e16ee20 feat(stdout): bundle the vectordata demo as a runnable workload
The demo only worked from a checkout. It now ships in the stdout
adapter's activities, so 'nb5 run vectordata_demo dataset=<name>:<profile>'
works from the distribution alone, with --cat and --copy for reading or
editing it.

Every catalog-touching expression is guarded on the dataset parameter
being given. Bundled workloads are parsed through the expression
pipeline by --list-workloads and --list-scenarios, so a workload that
opened a catalog unconditionally would fail listing for every user
without one configured; with no dataset named it now renders usage text
and touches nothing.
2026-09-01 23:23:47 +00:00
Jonathan Shook 0edf2abd5a version bump 2026-09-01 22:12:13 +00:00