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}