module
Memo::USearchIndex
Overview
USearch HNSW index management for fast approximate nearest neighbor search.
Wraps USearch index lifecycle: file naming, open/save/close, type conversion, and vector operations. All Float64↔Float32 conversion happens here.
One index per service (isolated vector spaces). Index files are named by service format, model, and dimensions: memo.openai--text-embedding-3-small--1536.usearch
Extended Modules
Defined in:
memo/usearch_index.crConstant Summary
-
DEFAULT_INDEX_DIR =
begin if xdg = ENV["XDG_DATA_HOME"]? File.join(xdg, "memo", "indices") else home = Path.home.to_s if ((home == "/nonexistent") || home.empty?) || !(Dir.exists?(home)) "/var/lib/memo/indices" else File.join(home, ".local", "share", "memo", "indices") end end end -
Default directory for index files when no db_path is available (e.g., PostgreSQL backend). Follows XDG Base Directory spec, with fallback to /var/lib/memo/indices for system users.
Instance Method Summary
-
#add(index : USearch::Index, key : UInt64, embedding : Array(Float64))
Add a vector to the index.
-
#close(index : USearch::Index, path : String)
Save and close the index, freeing resources.
-
#delete_file(path : String)
Delete the index file from disk.
-
#filtered_search(index : USearch::Index, query : Array(Float64), k : Int32, &filter : UInt64 -> Bool) : Array(USearch::SearchResult)
Search with a filter predicate on keys.
-
#get_vector(index : USearch::Index, key : UInt64) : Array(Float64) | Nil
Retrieve a vector from the index by key.
-
#index_path(db_path : String, format : String, model : String, dimensions : Int32) : String
Build the index file path from a database path.
-
#index_path_in_dir(dir : String, format : String, model : String, dimensions : Int32, stem : String = "memo") : String
Build the index file path from an explicit directory.
-
#open(path : String, dimensions : Int32) : USearch::Index
Open or create a USearch index at a specific path.
-
#remove(index : USearch::Index, key : UInt64)
Remove a vector from the index by key.
-
#save(index : USearch::Index, path : String)
Save the index to disk.
-
#search(index : USearch::Index, query : Array(Float64), k : Int32) : Array(USearch::SearchResult)
Search for k nearest neighbors (unfiltered).
-
#to_f32(embedding : Array(Float64)) : Array(Float32)
Convert Float64 array to Float32 array for USearch.
Instance Method Detail
Add a vector to the index.
Key is the embedding rowid (SQLite rowid or PostgreSQL eid). Embedding is converted from Float64 to Float32 at this boundary.
Search with a filter predicate on keys.
Only results where the filter block returns true are included. Use this with a Set of valid rowids from SQL pre-filtering.
Retrieve a vector from the index by key.
Returns Float64 array for compatibility with the rest of Memo, or nil if the key doesn't exist.
Build the index file path from a database path.
Path: {db_dir}/{db_stem}.{format}--{model}--{dimensions}.usearch Path-unsafe characters in format/model are replaced with hyphens.
Build the index file path from an explicit directory.
Path: {dir}/{stem}.{format}--{model}--{dimensions}.usearch If no stem is provided, uses "memo" as default.
Open or create a USearch index at a specific path.
If the index file exists on disk, loads it. Otherwise creates a new empty index with cosine metric and f16 quantization.
Search for k nearest neighbors (unfiltered).
Returns USearch::SearchResult array with keys and distances. Cosine distance = 1 - similarity, so similarity = 1 - distance.
Convert Float64 array to Float32 array for USearch.