Skip to main content

velesdb_core/database/
vector_ops.rs

1//! Vector collection creation and retrieval operations.
2
3use crate::collection::VectorCollection;
4use crate::{CollectionType, DistanceMetric, Result, StorageMode};
5
6use super::Database;
7
8#[allow(deprecated)]
9impl Database {
10    /// Creates a new vector collection.
11    ///
12    /// # Errors
13    ///
14    /// Returns an error if a collection with the same name already exists.
15    pub fn create_vector_collection(
16        &self,
17        name: &str,
18        dimension: usize,
19        metric: DistanceMetric,
20    ) -> Result<()> {
21        self.create_vector_collection_with_options(name, dimension, metric, StorageMode::default())
22    }
23
24    /// Creates a new vector collection with custom storage options.
25    ///
26    /// # Errors
27    ///
28    /// Returns an error if a collection with the same name already exists.
29    pub fn create_vector_collection_with_options(
30        &self,
31        name: &str,
32        dimension: usize,
33        metric: DistanceMetric,
34        storage_mode: StorageMode,
35    ) -> Result<()> {
36        self.ensure_collection_name_available(name)?;
37        let path = self.data_dir.join(name);
38        let coll = VectorCollection::create(path, name, dimension, metric, storage_mode)?;
39        self.register_vector_collection(name, &coll, dimension, metric, storage_mode);
40        Ok(())
41    }
42
43    /// Creates a new vector collection with custom HNSW parameters.
44    ///
45    /// When `m` or `ef_construction` are `Some`, those values override the
46    /// dimension-based auto-tuned defaults from [`HnswParams::auto`].
47    ///
48    /// # Errors
49    ///
50    /// Returns an error if a collection with the same name already exists.
51    pub fn create_vector_collection_with_hnsw(
52        &self,
53        name: &str,
54        dimension: usize,
55        metric: DistanceMetric,
56        storage_mode: StorageMode,
57        m: Option<usize>,
58        ef_construction: Option<usize>,
59    ) -> Result<()> {
60        self.ensure_collection_name_available(name)?;
61        let path = self.data_dir.join(name);
62        let coll = VectorCollection::create_with_hnsw(
63            path,
64            name,
65            dimension,
66            metric,
67            storage_mode,
68            m,
69            ef_construction,
70        )?;
71        self.register_vector_collection(name, &coll, dimension, metric, storage_mode);
72        Ok(())
73    }
74
75    /// Registers a vector collection in both legacy and typed registries,
76    /// notifies the observer, and bumps the schema version.
77    fn register_vector_collection(
78        &self,
79        name: &str,
80        coll: &VectorCollection,
81        dimension: usize,
82        metric: DistanceMetric,
83        storage_mode: StorageMode,
84    ) {
85        self.collections
86            .write()
87            .insert(name.to_string(), coll.inner.clone());
88        self.vector_colls
89            .write()
90            .insert(name.to_string(), coll.clone());
91
92        if let Some(ref obs) = self.observer {
93            let kind = CollectionType::Vector {
94                dimension,
95                metric,
96                storage_mode,
97            };
98            obs.on_collection_created(name, &kind);
99        }
100
101        self.schema_version
102            .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
103    }
104
105    /// Returns a `VectorCollection` by name.
106    ///
107    /// Checks the typed registry first.  If not found there, falls back to
108    /// opening the collection directory from disk (e.g. for collections created
109    /// via the legacy `create_collection` API that were not registered in the
110    /// typed registry).  The opened instance is cached back into the registry
111    /// so subsequent calls avoid the disk round-trip.
112    ///
113    /// Returns `None` if the collection does not exist on disk.
114    #[must_use]
115    pub fn get_vector_collection(&self, name: &str) -> Option<VectorCollection> {
116        if let Some(c) = self.vector_colls.read().get(name).cloned() {
117            return Some(c);
118        }
119        self.open_vector_collection_from_disk(name)
120    }
121
122    /// Disk fallback for `get_vector_collection`.
123    fn open_vector_collection_from_disk(&self, name: &str) -> Option<VectorCollection> {
124        let cfg = self.read_collection_config(name)?;
125        if cfg.graph_schema.is_some() || cfg.metadata_only {
126            return None;
127        }
128        let coll = VectorCollection::open(self.data_dir.join(name)).ok()?;
129        self.vector_colls
130            .write()
131            .insert(name.to_string(), coll.clone());
132        Some(coll)
133    }
134}