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