qdrant_client/builders/
optimizers_config_diff_builder.rs

1use crate::qdrant::*;
2
3#[derive(Clone)]
4pub struct OptimizersConfigDiffBuilder {
5    ///
6    /// The minimal fraction of deleted vectors in a segment, required to perform segment optimization
7    pub(crate) deleted_threshold: Option<Option<f64>>,
8    ///
9    /// The minimal number of vectors in a segment, required to perform segment optimization
10    pub(crate) vacuum_min_vector_number: Option<Option<u64>>,
11    ///
12    /// Target amount of segments the optimizer will try to keep.
13    /// Real amount of segments may vary depending on multiple parameters:
14    ///
15    /// - Amount of stored points.
16    /// - Current write RPS.
17    ///
18    /// It is recommended to select the default number of segments as a factor of the number of search threads,
19    /// so that each segment would be handled evenly by one of the threads.
20    pub(crate) default_segment_number: Option<Option<u64>>,
21    ///
22    /// Do not create segments larger this size (in kilobytes).
23    /// Large segments might require disproportionately long indexation times,
24    /// therefore it makes sense to limit the size of segments.
25    ///
26    /// If indexing speed is more important - make this parameter lower.
27    /// If search speed is more important - make this parameter higher.
28    /// Note: 1Kb = 1 vector of size 256
29    /// If not set, will be automatically selected considering the number of available CPUs.
30    pub(crate) max_segment_size: Option<Option<u64>>,
31    ///
32    /// Maximum size (in kilobytes) of vectors to store in-memory per segment.
33    /// Segments larger than this threshold will be stored as read-only memmaped file.
34    ///
35    /// Memmap storage is disabled by default, to enable it, set this threshold to a reasonable value.
36    ///
37    /// To disable memmap storage, set this to `0`.
38    ///
39    /// Note: 1Kb = 1 vector of size 256
40    pub(crate) memmap_threshold: Option<Option<u64>>,
41    ///
42    /// Maximum size (in kilobytes) of vectors allowed for plain index, exceeding this threshold will enable vector indexing
43    ///
44    /// Default value is 20,000, based on <<https://github.com/google-research/google-research/blob/master/scann/docs/algorithms.md>.>
45    ///
46    /// To disable vector indexing, set to `0`.
47    ///
48    /// Note: 1kB = 1 vector of size 256.
49    pub(crate) indexing_threshold: Option<Option<u64>>,
50    ///
51    /// Interval between forced flushes.
52    pub(crate) flush_interval_sec: Option<Option<u64>>,
53    ///
54    /// Max number of threads (jobs) for running optimizations per shard.
55    /// Each optimization job will also use `max_indexing_threads` threads by itself for index building.
56    ///
57    /// - If `auto` - have no limit and choose dynamically to saturate CPU.
58    /// - If `disabled` or `0` - no optimization threads, optimizations will be disabled.
59    pub(crate) max_optimization_threads: Option<Option<MaxOptimizationThreads>>,
60}
61
62impl OptimizersConfigDiffBuilder {
63    ///
64    /// The minimal fraction of deleted vectors in a segment, required to perform segment optimization
65    #[allow(unused_mut)]
66    pub fn deleted_threshold(self, value: f64) -> Self {
67        let mut new = self;
68        new.deleted_threshold = Option::Some(Option::Some(value));
69        new
70    }
71    ///
72    /// The minimal number of vectors in a segment, required to perform segment optimization
73    #[allow(unused_mut)]
74    pub fn vacuum_min_vector_number(self, value: u64) -> Self {
75        let mut new = self;
76        new.vacuum_min_vector_number = Option::Some(Option::Some(value));
77        new
78    }
79    ///
80    /// Target amount of segments the optimizer will try to keep.
81    /// Real amount of segments may vary depending on multiple parameters:
82    ///
83    /// - Amount of stored points.
84    /// - Current write RPS.
85    ///
86    /// It is recommended to select the default number of segments as a factor of the number of search threads,
87    /// so that each segment would be handled evenly by one of the threads.
88    #[allow(unused_mut)]
89    pub fn default_segment_number(self, value: u64) -> Self {
90        let mut new = self;
91        new.default_segment_number = Option::Some(Option::Some(value));
92        new
93    }
94    ///
95    /// Do not create segments larger this size (in kilobytes).
96    /// Large segments might require disproportionately long indexation times,
97    /// therefore it makes sense to limit the size of segments.
98    ///
99    /// If indexing speed is more important - make this parameter lower.
100    /// If search speed is more important - make this parameter higher.
101    /// Note: 1Kb = 1 vector of size 256
102    /// If not set, will be automatically selected considering the number of available CPUs.
103    #[allow(unused_mut)]
104    pub fn max_segment_size(self, value: u64) -> Self {
105        let mut new = self;
106        new.max_segment_size = Option::Some(Option::Some(value));
107        new
108    }
109    ///
110    /// Maximum size (in kilobytes) of vectors to store in-memory per segment.
111    /// Segments larger than this threshold will be stored as read-only memmaped file.
112    ///
113    /// Memmap storage is disabled by default, to enable it, set this threshold to a reasonable value.
114    ///
115    /// To disable memmap storage, set this to `0`.
116    ///
117    /// Note: 1Kb = 1 vector of size 256
118    #[allow(unused_mut)]
119    pub fn memmap_threshold(self, value: u64) -> Self {
120        let mut new = self;
121        new.memmap_threshold = Option::Some(Option::Some(value));
122        new
123    }
124    ///
125    /// Maximum size (in kilobytes) of vectors allowed for plain index, exceeding this threshold will enable vector indexing
126    ///
127    /// Default value is 20,000, based on <<https://github.com/google-research/google-research/blob/master/scann/docs/algorithms.md>.>
128    ///
129    /// To disable vector indexing, set to `0`.
130    ///
131    /// Note: 1kB = 1 vector of size 256.
132    #[allow(unused_mut)]
133    pub fn indexing_threshold(self, value: u64) -> Self {
134        let mut new = self;
135        new.indexing_threshold = Option::Some(Option::Some(value));
136        new
137    }
138    ///
139    /// Interval between forced flushes.
140    #[allow(unused_mut)]
141    pub fn flush_interval_sec(self, value: u64) -> Self {
142        let mut new = self;
143        new.flush_interval_sec = Option::Some(Option::Some(value));
144        new
145    }
146    ///
147    /// Max number of threads (jobs) for running optimizations per shard.
148    /// Each optimization job will also use `max_indexing_threads` threads by itself for index building.
149    ///
150    /// - If `auto` - have no limit and choose dynamically to saturate CPU.
151    /// - If `disabled` or `0` - no optimization threads, optimizations will be disabled.
152    ///
153    /// ```no_run
154    ///# use qdrant_client::{Qdrant, QdrantError};
155    /// use qdrant_client::qdrant::{OptimizersConfigDiffBuilder, UpdateCollectionBuilder, MaxOptimizationThreadsBuilder};
156    ///
157    ///# async fn create_collection(client: &Qdrant)
158    ///# -> Result<(), QdrantError> {
159    /// let optimizers_config = OptimizersConfigDiffBuilder::default()
160    ///     // Use exactly 8 threads
161    ///     .max_optimization_threads(8)
162    ///     // Or automatically choose
163    ///     .max_optimization_threads(MaxOptimizationThreadsBuilder::auto())
164    ///     // Or disable
165    ///     .max_optimization_threads(MaxOptimizationThreadsBuilder::disabled());
166    ///
167    /// client
168    ///     .update_collection(
169    ///         UpdateCollectionBuilder::new("my_collection").optimizers_config(optimizers_config),
170    ///     )
171    ///     .await?;
172    ///# Ok(())
173    ///# }
174    /// ```
175    #[allow(unused_mut)]
176    pub fn max_optimization_threads<VALUE: Into<MaxOptimizationThreads>>(
177        self,
178        value: VALUE,
179    ) -> Self {
180        let mut new = self;
181        new.max_optimization_threads = Option::Some(Option::Some(value.into()));
182        new
183    }
184
185    fn build_inner(self) -> Result<OptimizersConfigDiff, std::convert::Infallible> {
186        Ok(OptimizersConfigDiff {
187            deleted_threshold: self.deleted_threshold.unwrap_or_default(),
188            vacuum_min_vector_number: self.vacuum_min_vector_number.unwrap_or_default(),
189            default_segment_number: self.default_segment_number.unwrap_or_default(),
190            max_segment_size: self.max_segment_size.unwrap_or_default(),
191            memmap_threshold: self.memmap_threshold.unwrap_or_default(),
192            indexing_threshold: self.indexing_threshold.unwrap_or_default(),
193            flush_interval_sec: self.flush_interval_sec.unwrap_or_default(),
194            max_optimization_threads: self.max_optimization_threads.unwrap_or_default(),
195            // Deprecated: replaced with max_optimization_threads
196            deprecated_max_optimization_threads: None,
197        })
198    }
199    /// Create an empty builder, with all fields set to `None` or `PhantomData`.
200    fn create_empty() -> Self {
201        Self {
202            deleted_threshold: core::default::Default::default(),
203            vacuum_min_vector_number: core::default::Default::default(),
204            default_segment_number: core::default::Default::default(),
205            max_segment_size: core::default::Default::default(),
206            memmap_threshold: core::default::Default::default(),
207            indexing_threshold: core::default::Default::default(),
208            flush_interval_sec: core::default::Default::default(),
209            max_optimization_threads: core::default::Default::default(),
210        }
211    }
212}
213
214impl From<OptimizersConfigDiffBuilder> for OptimizersConfigDiff {
215    fn from(value: OptimizersConfigDiffBuilder) -> Self {
216        value.build_inner().unwrap_or_else(|_| {
217            panic!(
218                "Failed to convert {0} to {1}",
219                "OptimizersConfigDiffBuilder", "OptimizersConfigDiff"
220            )
221        })
222    }
223}
224
225impl OptimizersConfigDiffBuilder {
226    /// Builds the desired type. Can often be omitted.
227    pub fn build(self) -> OptimizersConfigDiff {
228        self.build_inner().unwrap_or_else(|_| {
229            panic!(
230                "Failed to build {0} into {1}",
231                "OptimizersConfigDiffBuilder", "OptimizersConfigDiff"
232            )
233        })
234    }
235}
236
237impl Default for OptimizersConfigDiffBuilder {
238    fn default() -> Self {
239        Self::create_empty()
240    }
241}