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}