This document details the architectural principles, internal data structures, storage formats, and concurrency guarantees that power Vectrust.
Vectrust is designed as an embedded, zero-dependency, library-first vector database engine. It compiles directly into your Rust application without requiring external server processes, network daemons, or C++ runtimes.
+---------------------------------------------------------------------------------+
| User Application |
+---------------------------------------------------------------------------------+
|
v
+---------------------------------------------------------------------------------+
| Vectrust DB |
| - Collection Lifecycle Management |
| - Multi-Collection Namespace Routing |
+---------------------------------------------------------------------------------+
|
+--------------------+--------------------+
| |
v v
+----------------------------------+ +----------------------------------+
| Collection A | | Collection B |
| - Arc<RwLock<CollectionInner>> | | - Arc<RwLock<CollectionInner>> |
+----------------------------------+ +----------------------------------+
|
+-----------+-----------+----------------------+
| | |
v v v
+------------------+ +-------------------+ +-----------------------+
| Index Engine | | Metadata Store | | Storage Engine |
| - HNSW (ANN) | | - JSON Payloads | | - Write-Ahead Log |
| - Flat (Exact) | | - Path Resolver | | - Atomic Snapshots |
| - Auto-Vec SIMD | | - Predicate Eval | | - CRC32 Checksums |
+------------------+ +-------------------+ +-----------------------+
Vectrust supports four core distance metrics in vectrust::metric::Metric:
| Manhattan (L1): $d(a, b) = \sum | a_i - b_i | $ |
Modern CPUs can execute multiple vector instructions per cycle (e.g. AVX2, AVX-512, ARM NEON) if data dependencies between successive loop iterations are decoupled.
Vectrust implements distance loops with an 8-way parallel accumulator pattern:
let chunks_a = a.chunks_exact(8);
let chunks_b = b.chunks_exact(8);
let mut sum0 = 0.0f32;
let mut sum1 = 0.0f32;
// ...
let mut sum7 = 0.0f32;
for (ca, cb) in chunks_a.zip(chunks_b) {
sum0 += (ca[0] - cb[0]) * (ca[0] - cb[0]);
sum1 += (ca[1] - cb[1]) * (ca[1] - cb[1]);
// ...
sum7 += (ca[7] - cb[7]) * (ca[7] - cb[7]);
}
let total = (sum0 + sum1) + (sum2 + sum3) + (sum4 + sum5) + (sum6 + sum7);
This loop structure allows LLVM to vectorize across FMA (Fused Multiply-Add) registers with zero loop-carried dependency stalls.
Vectrust provides two complementary vector indexing engines implementing VectorIndex:
FlatIndex)par_iter) when indexing larger collections ($N > 2000$).HnswIndex)entry_point in max_level. Greedily steps to the single nearest neighbor at each layer until descending to Layer 1.ef_search.In many vector databases, applying a filter causes one of two issues:
Vectrust’s Approach:
During graph exploration, non-matching nodes are utilized for routing (preventing disconnected partitions), while only candidates satisfying filter.matches(payload) enter the dynamic candidate priority queue. If the filter is hyper-selective, an automatic secondary fallback guarantees that up to top_k results are retrieved without degraded recall.
Vectrust combines an append-only Write-Ahead Log (WAL) with Atomic Snapshots and CRC32 validation.
Directory Layout:
data_dir/
└── collections/
└── my_collection/
├── snapshot.bin # Compressed binary state dump (CRC32 validated)
├── snapshot.tmp # Staging file during atomic snapshot creation
└── wal.log # Append-only journal of operations post-snapshot
Every mutation (insert, delete, update_payload) is appended to wal.log before being applied in memory:
+----------------+----------------+----------------+--------------------+
| Record Length | CRC32 Hash | Record Type | Bincode Payload |
| (4 bytes) | (4 bytes) | (1 byte) | (N bytes) |
+----------------+----------------+----------------+--------------------+
sync_on_write flag controls whether fsync() / FlushFileBuffers() is executed on every mutation.When calling collection.compact():
snapshot.tmp) with a 4-byte magic header (VECS), 2-byte version, 4-byte CRC32, and 8-byte payload length.snapshot.bin (using atomic rename semantics on Windows and POSIX).wal.log file is safely truncated to 0 bytes.Vectrust is optimized for high-concurrency read-heavy search workloads:
parking_lot::RwLock, which avoids thread poisoning and provides microsecond-level lock acquisition overhead.collection.search(...) simultaneously without waiting on each other.collection.search_batch(queries) acquires a single shared read lock and evaluates all queries across available CPU cores using Rayon worker threads.Collection and Vectrust wrap internal state in Arc, making cloning cheap and thread-safe.