oxify_vector/
lib.rs

1//! # OxiFY Vector
2//!
3//! Ported from OxiRS (<https://github.com/cool-japan/oxirs>)
4//! Original implementation: Copyright (c) OxiRS Contributors
5//! Adapted for OxiFY (simplified for LLM workflow focus)
6//! License: MIT OR Apache-2.0 (compatible with OxiRS)
7//!
8//! In-memory vector search and similarity operations for RAG and embeddings.
9//!
10//! This crate provides:
11//! - Vector similarity search (cosine, euclidean, dot product, manhattan)
12//! - Brute-force exact search for small to medium datasets
13//! - Batch search for multiple queries
14//! - Radius search for finding neighbors within distance
15//!
16//! ## Example
17//!
18//! ```rust
19//! use oxify_vector::{VectorSearchIndex, SearchConfig, DistanceMetric};
20//! use std::collections::HashMap;
21//!
22//! # fn example() -> anyhow::Result<()> {
23//! // Create embeddings
24//! let mut embeddings = HashMap::new();
25//! embeddings.insert("doc1".to_string(), vec![0.1, 0.2, 0.3]);
26//! embeddings.insert("doc2".to_string(), vec![0.2, 0.3, 0.4]);
27//! embeddings.insert("doc3".to_string(), vec![0.3, 0.4, 0.5]);
28//!
29//! // Build search index
30//! let config = SearchConfig::default();
31//! let mut index = VectorSearchIndex::new(config);
32//! index.build(&embeddings)?;
33//!
34//! // Search for similar documents
35//! let query = vec![0.15, 0.25, 0.35];
36//! let results = index.search(&query, 2)?;
37//!
38//! for result in results {
39//!     println!("{}: score = {:.4}", result.entity_id, result.score);
40//! }
41//! # Ok(())
42//! # }
43//! ```
44
45pub mod adaptive;
46pub mod cache;
47pub mod colbert;
48pub mod distributed;
49pub mod embeddings;
50pub mod filter;
51pub mod gpu;
52pub mod hnsw;
53pub mod hybrid;
54pub mod ivf;
55pub mod lsh;
56pub mod metrics;
57pub mod multi_index;
58pub mod optimizer;
59pub mod otel;
60pub mod persistence;
61pub mod profiling;
62pub mod quantization;
63pub mod recall_eval;
64pub mod search;
65pub mod simd;
66pub mod types;
67
68// Re-export commonly used types
69pub use adaptive::{AdaptiveConfig, AdaptiveIndex, AdaptiveStats};
70pub use cache::{CacheConfig, CacheStats, QueryCache};
71pub use colbert::{ColbertConfig, ColbertIndex, ColbertSearchResult, ColbertStats, MultiVectorDoc};
72pub use distributed::{ConsistentHash, DistributedIndex, DistributedStats, ShardConfig};
73pub use embeddings::{
74    CachedEmbeddingProvider, EmbeddingCache, EmbeddingProvider, MockEmbeddingProvider,
75    OpenAIConfig, OpenAIEmbeddingProvider,
76};
77pub use filter::{Filter, FilterCondition, FilterValue, Metadata};
78pub use gpu::{GpuBatchProcessor, GpuConfig, GpuStats};
79pub use hnsw::{HnswConfig, HnswIndex, HnswStats};
80pub use hybrid::{HybridConfig, HybridIndex, HybridSearchResult, HybridStats};
81pub use ivf::{IvfPqConfig, IvfPqIndex, IvfPqStats};
82pub use lsh::{LshConfig, LshIndex, LshStats};
83pub use metrics::{IndexStats as MetricsIndexStats, LatencyTimer, Metrics, SearchStats};
84pub use multi_index::{MultiIndexConfig, MultiIndexSearch, ScoreMergeStrategy};
85pub use optimizer::{OptimizerConfig, QueryOptimizer, QueryPlan, SearchStrategy};
86pub use otel::{init_tracing, shutdown_tracing, TracingConfig};
87pub use profiling::{
88    Bottleneck, ImpactLevel, IndexHealthChecker, ProfilingConfig, QueryProfile, QueryProfiler,
89    Recommendation,
90};
91pub use quantization::{
92    BinaryQuantizationConfig, BinaryQuantizedIndex, BinaryQuantizedIndexStats, BinaryQuantizer,
93    FourBitQuantizedIndex, FourBitQuantizedIndexStats, FourBitQuantizer, QuantizationConfig,
94    QuantizedIndexStats, QuantizedVectorIndex, ScalarQuantizer,
95};
96pub use recall_eval::{AggregatedMetrics, EvaluationConfig, QueryMetrics, RecallEvaluator};
97pub use search::VectorSearchIndex;
98pub use types::{DistanceMetric, IndexStats, SearchConfig, SearchResult};
99
100#[cfg(test)]
101mod tests {
102    use super::*;
103    use std::collections::HashMap;
104
105    #[test]
106    fn test_basic_search() {
107        let mut embeddings = HashMap::new();
108        embeddings.insert("doc1".to_string(), vec![1.0, 0.0, 0.0]);
109        embeddings.insert("doc2".to_string(), vec![0.0, 1.0, 0.0]);
110
111        let config = SearchConfig::default();
112        let mut index = VectorSearchIndex::new(config);
113        assert!(index.build(&embeddings).is_ok());
114
115        let query = vec![0.9, 0.1, 0.0];
116        let results = index.search(&query, 1).unwrap();
117
118        assert_eq!(results.len(), 1);
119        assert_eq!(results[0].entity_id, "doc1");
120    }
121}