qdrant_client/builders/
optimizers_config_diff_builder.rs

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