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}