Repository navigation
contextdb v2: vector columns, exact search by distance, compressed large values - #21
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds vector columns and exact search to the workspace under
v2/. Nothing that builds fromcrates/changes; the rootCargo.tomlandCargo.lockare untouched. One commit ondev6b44713.What is in it
VECTOR(n)columns;SELECT id, embedding <=> $q AS distance FROM notes ORDER BY distance LIMIT 10returns the nearest rows with their cosine distance, filtered by the statement'sWHERE. The answer equals a full sort by distance; rows at the same distance come in primary-key order. There is no hiddenscorecolumn.PARTITION_KEY (column, ...)lays vectors out so that a filtered search reads only its part;MAX_PARTITIONS(256 unless declared) counts the partitions that hold a vector.Database::run_maintenance_cyclepacks them into blocks, at most 4,096 a call, in one commit. Nothing in this version calls it on its own.lz4_flex) when that saves an eighth or more.v2/redb/README.md: a page that fills because records were added at its end stays full, and past 1 MiB the file grows in small steps where upstream doubles it (34 lines added, 15 removed inv2/redb/src).SET MEMORY_LIMITis refused, with the action to take, only below what the session's cache and the statement in flight already hold.WHERE k = -1uses an index ask = 1does. Stored bytes of a large value, a vector record or a vector declaration that disagree with themselves are reported as damage, never a panic..github/workflows/check.ymlnow states the size of the shipped code rounded up to 500 lines and the number of tests rounded up to 10, and fails when a change crosses either without editing the number; it also refuses a shipped file over 1,500 lines, a test-only name in shipped code, an ignored test and anallowattribute beyond the fourv2/AGENTS.mdnames.v2/AGENTS.mdgains "Making a change".Refused by name until a later version:
SEARCH_MODE INDEXEDandUSE VECTOR INDEXED(the index), a search withoutLIMIT, a second sort key after a distance, a distance inWHERE,ORDER BY ... DESCon a distance,OFFSETwith a search.<->and<#>are not in the grammar.Measured at this commit
By
v2/numbers.sh: a release build on a 16-core AMD Ryzen 9 9955HX with 64 GB of memory and an NVMe drive, with nothing else running.COUNT(*)of those rows; open after a clean closecargo testAgainst the current engine, like for like
The same rows loaded clean into both engines, 500 to a commit, into the same table: text passages with one 768-number embedding each, in 8 partitions (a real workload that is not in the repository). The same 100 questions, a read session at 1 GiB, one query at a time, one core each, 95th percentile, same machine. Both engines return the same ten rows in the same order for every question.
The figures of this change for one and several partitions are with no memory limit declared, which is its slower case (an 8 MiB page cache); under 64 MiB the all-partition find at 100,008 passages is 14.4 ms. Before the vectors are sealed the all-partition find is 42 ms at 11,588 passages and 382 ms at 100,008. 173 files of 343.9 MiB of session text, stored as rows, make a 227.9 MiB store.
Verification
check.ymlas written, on the commit, plus a cross-compiled lint foraarch64-apple-darwin: all pass. 155 of 155 tests and the documentation tests; the storage library's 202 (upstream's 196 and 6 for the changes); the build on Rust 1.89; 10,809 shipped lines against the stated 11,000 and 171 tests against the stated 180.5d6b3a66e: https://github.com/context-graph-ai/contextdb/actions/runs/42974637240 — green, 4 jobs (lint, tests on Linux, tests on macOS, Rust 1.89), 8 min (06:45–06:53 UTC). The existing workflow does not run for a change underv2/.Known limits of this version
run_maintenance_cycleafter writing vectors. A search before that returns the same rows, slower.UPDATEwrites a row's large values again even when it does not assign them.Databasethat return a plain value panic on a handle that was closed.