PostgresStore
A durable CacheStore backed by Postgres with the pgvector extension.
This is the "durable semantic cache as a one-dependency choice": point it at a Postgres you already run and cached answers survive a restart and are shared across processes. As with every kmemo store, the adapter reimplements no match logic — the nearest-neighbour search is pgvector's cosine-distance operator (<=>), and dev.kmemo.SemanticCache still owns threshold, guards and verification.
Schema. One table (created on first use, or provision it yourself from the shipped schema.sql): id primary key, scope, prompt, response, embedding vector, created_at, expires_at (nullable, where null never expires), metadata jsonb, tags text[], embedder text and chunk_lengths integer[]. A table created by an earlier version gains the last three by ALTER TABLE ... ADD COLUMN IF NOT EXISTS on the next start, and rows already in it read as dev.kmemo.Embedder.UNDECLARED with no chunk boundaries, which is the honest record of a row nothing captured an embedder for and nothing ever streamed. The embedding column is left dimension-unconstrained so mixed embedding sizes are a storage error at query time, not a schema wall. The search is an exact scan by default (correct, and matching the conformance suite); add an HNSW/IVFFlat index on embedding once your dimension is fixed to scale it.
Expiry. Every read filters on expires_at IS NULL OR expires_at > now, where now comes from the injected clock — so expiry is deterministic under a fixed clock in tests, and honest under the system clock in production. purgeExpired deletes the dead rows when you want the space back.
Parameters
a pooled Postgres DataSource; the Postgres JDBC driver is the caller's dependency.
table name (validated as a plain identifier, since it is interpolated into SQL).
how long an entry stays valid, or null to keep it until removed.
time source; substitute a fixed clock in tests instead of sleeping.
Constructors
Functions
Deletes every row already past its TTL and returns how many went.