State and threading¶
The store owns its configuration and row structure. Your application owns the meaning and mutability of its metadata payloads and coordinates concurrent use.
Inspection and retrieval¶
dimensions, normalize, and file_path are read-only properties. Configure
dimensions and normalization in the constructor; use open(path) or save(path)
to establish a binding.
vectors and metadata return zero-copy, non-writeable NumPy views of active
rows. Ordinary assignment and enabling writes are rejected. Request fresh views
after add(), clear(), or reload(); a view describes rows present when it
was requested. It may keep an old buffer alive after the store releases it.
These are inspection views, not tamper-proof snapshots. Deliberately modifying
backing memory via .base, private attributes, or ctypes is unsupported.
Call .copy() when you need a mutable independent row array. A metadata array
copy still shares the payload objects inside it.
get() returns an independent float32 vector copy and the original metadata
payload. Search hits share that metadata too:
from numpy_vector_store import VectorStore
payload = {"title": "Original"}
store = VectorStore[dict[str, str]](dimensions=2)
store.add([[1.0, 0.0]], [payload])
row = store.get(0)
assert row is not None
vector, metadata = row
vector[0] = 99.0 # Your own vector copy.
metadata["title"] = "Reviewed" # The shared metadata object.
print(float(store.vectors[0, 0]))
print(payload["title"])
print(store.get(100)) # A missing row returns None.
1.0
Reviewed
None
Use frozen application objects or copy metadata at your own boundary when you need immutable payloads. The library does not deep-copy arbitrary Python objects.
Concurrent reads¶
There are no internal locks. Search, get(), and inspection can run concurrently
on one instance only while its state and shared metadata payloads are unchanged.
If any thread may call add(), clear(), reload(), or save(), or mutate a
shared metadata payload, synchronize every access to that instance with the
same application lock or an equivalent mechanism. Locking only the writer is
insufficient. This also includes inspection and search while another thread saves.
A save must not overlap in-memory mutation. Atomic archive replacement protects visibility at the destination path, not the consistency of arrays read from a changing store. Separate instances or processes writing one destination also need external writer coordination; the last successful replacement can win.
These ownership rules are part of the public compatibility contract.