a3s_vec/collection/
configuration.rs1use super::CollectionResourceLimits;
4use crate::config::{current_config, ConfigBuilder, Durability, IoBackend};
5use crate::error::Result;
6use crate::storage_ceilings::StorageCeilings;
7
8#[derive(Debug, Clone, Default)]
21pub struct CollectionOptions {
22 pub(super) read_only: bool,
23 pub(super) durability: Option<Durability>,
24 pub(super) io_backend: Option<IoBackend>,
25 pub(super) resource_limits: CollectionResourceLimits,
26 pub(super) storage_ceilings: Option<StorageCeilings>,
27}
28
29impl CollectionOptions {
30 pub fn new() -> Result<Self> {
31 Ok(Self::default())
32 }
33
34 pub fn set_read_only(&mut self, read_only: bool) -> Result<()> {
35 self.read_only = read_only;
36 Ok(())
37 }
38
39 pub fn read_only(&self) -> bool {
40 self.read_only
41 }
42
43 pub fn set_durability(&mut self, value: Durability) -> Result<()> {
44 self.durability = Some(value);
45 Ok(())
46 }
47
48 pub fn durability(&self) -> Option<Durability> {
49 self.durability
50 }
51
52 pub fn set_io_backend(&mut self, value: IoBackend) -> Result<()> {
57 self.io_backend = Some(value);
58 Ok(())
59 }
60
61 pub fn io_backend(&self) -> Option<IoBackend> {
63 self.io_backend
64 }
65
66 pub fn set_resource_limits(&mut self, value: CollectionResourceLimits) -> Result<()> {
68 self.resource_limits = value;
69 Ok(())
70 }
71
72 pub fn resource_limits(&self) -> CollectionResourceLimits {
74 self.resource_limits
75 }
76
77 pub fn set_storage_ceilings(&mut self, value: StorageCeilings) -> Result<()> {
83 self.storage_ceilings = Some(value);
84 Ok(())
85 }
86
87 pub fn storage_ceilings(&self) -> Option<StorageCeilings> {
89 self.storage_ceilings
90 }
91}
92
93pub(super) fn options_config(options: &CollectionOptions) -> ConfigBuilder {
94 resolve_options_config(options, current_config())
95}
96
97pub(super) fn resolved_storage_ceilings(options: &CollectionOptions) -> StorageCeilings {
99 options
100 .storage_ceilings
101 .unwrap_or_else(|| current_config().storage_ceilings)
102}
103
104fn resolve_options_config(
105 options: &CollectionOptions,
106 mut process_config: ConfigBuilder,
107) -> ConfigBuilder {
108 if let Some(durability) = options.durability {
109 process_config.durability = durability;
110 }
111 if let Some(io_backend) = options.io_backend {
112 process_config.io_backend = io_backend;
113 }
114 if let Some(storage_ceilings) = options.storage_ceilings {
115 process_config.storage_ceilings = storage_ceilings;
116 }
117 process_config
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123 use crate::config::Durability;
124
125 #[test]
126 fn process_durability_is_used_without_a_collection_override() {
127 let process = ConfigBuilder::default().durability(Durability::Interval);
128 let resolved = resolve_options_config(&CollectionOptions::default(), process);
129
130 assert_eq!(resolved.durability, Durability::Interval);
131 }
132
133 #[test]
134 fn collection_durability_overrides_the_process_default() {
135 let process = ConfigBuilder::default()
136 .durability(Durability::Interval)
137 .wal_max_ops(3)
138 .wal_max_bytes(1024);
139 let mut options = CollectionOptions::default();
140 options
141 .set_durability(Durability::Manual)
142 .expect("durability override must be valid");
143 let resolved = resolve_options_config(&options, process);
144
145 assert_eq!(resolved.durability, Durability::Manual);
146 assert_eq!(resolved.wal_max_ops, Some(3));
147 assert_eq!(resolved.wal_max_bytes, Some(1024));
148 }
149
150 #[test]
151 fn collection_storage_ceilings_override_the_process_default() {
152 let process = ConfigBuilder::default().storage_ceilings(
153 StorageCeilings::new()
154 .try_with_max_snapshot_bytes(1_024)
155 .expect("process ceiling must be valid"),
156 );
157 let mut options = CollectionOptions::default();
158 options
159 .set_storage_ceilings(
160 StorageCeilings::new()
161 .try_with_max_snapshot_bytes(4_096)
162 .expect("collection ceiling must be valid"),
163 )
164 .expect("storage ceilings must be accepted");
165 let resolved = resolve_options_config(&options, process);
166 assert_eq!(resolved.storage_ceilings.max_snapshot_bytes(), 4_096);
167 }
168
169 #[test]
170 fn process_io_backend_is_used_without_a_collection_override() {
171 let process = ConfigBuilder::default().io_backend(IoBackend::Mmap);
172 let resolved = resolve_options_config(&CollectionOptions::default(), process.clone());
173 assert_eq!(resolved.io_backend, process.io_backend);
174 }
175}