Skip to main content

qdrant_client/builders/
optimizers_config_diff_builder.rs

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