Skip to main content

sonic/
config.rs

1// Sonic
2//
3// Fast, lightweight and schema-less search backend
4// Copyright: 2019, Valerian Saliou <valerian@valeriansaliou.name>
5// Copyright: 2026, Rémi Bardon <remi@remibardon.name>
6// License: Mozilla Public License v2.0 (MPL v2.0)
7
8//! Sonic library configuration.
9//!
10//! It does not include server nor channel configuration, which are specific
11//! to the `sonic-server` binary.
12
13use std::path::PathBuf;
14use std::sync::Arc;
15
16use serde::Deserialize;
17
18use crate::util::serde::env_var;
19
20#[derive(Deserialize)]
21pub struct Config {
22    pub search: ConfigSearch,
23
24    pub store: ConfigStore,
25}
26
27impl Config {
28    pub fn validate(&self) {
29        // Check 'write_buffer' for KV
30        if self.store.kv.database.write_buffer == 0 {
31            panic!("write_buffer for kv must not be zero");
32        }
33
34        // Check 'flush_after' for KV
35        if self.store.kv.database.flush_after >= self.store.kv.pool.inactive_after {
36            panic!("flush_after for kv must be strictly lower than inactive_after");
37        }
38
39        // Check 'consolidate_after' for FST
40        if self.store.fst.graph.consolidate_after >= self.store.fst.pool.inactive_after {
41            panic!("consolidate_after for fst must be strictly lower than inactive_after");
42        }
43    }
44}
45
46#[derive(Deserialize)]
47pub struct ConfigSearch {
48    pub query_limit_default: u16,
49
50    pub query_limit_maximum: u16,
51
52    pub query_alternates_try: usize,
53
54    pub suggest_limit_default: u16,
55
56    pub suggest_limit_maximum: u16,
57
58    pub list_limit_default: u16,
59
60    pub list_limit_maximum: u16,
61}
62
63#[derive(Deserialize)]
64pub struct ConfigStore {
65    pub kv: Arc<ConfigStoreKV>,
66
67    pub fst: Arc<ConfigStoreFST>,
68}
69
70#[derive(Deserialize)]
71pub struct ConfigStoreKV {
72    #[serde(deserialize_with = "env_var::path_buf")]
73    pub path: PathBuf,
74
75    pub retain_word_objects: usize,
76
77    pub pool: ConfigStoreKVPool,
78
79    pub database: ConfigStoreKVDatabase,
80}
81
82#[derive(Deserialize)]
83pub struct ConfigStoreKVPool {
84    pub inactive_after: u64,
85}
86
87#[derive(Deserialize)]
88pub struct ConfigStoreKVDatabase {
89    pub flush_after: u64,
90
91    pub compress: bool,
92
93    pub parallelism: u16,
94
95    pub max_files: Option<u32>,
96
97    pub max_compactions: u16,
98
99    pub max_flushes: u16,
100
101    pub write_buffer: usize,
102
103    pub write_ahead_log: bool,
104}
105
106#[derive(Deserialize)]
107pub struct ConfigStoreFST {
108    #[serde(deserialize_with = "env_var::path_buf")]
109    pub path: PathBuf,
110
111    pub pool: ConfigStoreFSTPool,
112
113    pub graph: ConfigStoreFSTGraph,
114}
115
116#[derive(Deserialize)]
117pub struct ConfigStoreFSTPool {
118    pub inactive_after: u64,
119}
120
121#[derive(Deserialize)]
122pub struct ConfigStoreFSTGraph {
123    pub consolidate_after: u64,
124
125    pub max_size: usize,
126
127    pub max_words: usize,
128}
129
130#[cfg(test)]
131pub(crate) mod tests {
132    pub fn defaults_toml() -> &'static str {
133        r#"
134        [channel]
135        inet = "[::1]:1491"
136        tcp_timeout = 300
137
138        [search]
139        query_limit_default = 10
140        query_limit_maximum = 100
141        query_alternates_try = 4
142        suggest_limit_default = 5
143        suggest_limit_maximum = 20
144        list_limit_default = 100
145        list_limit_maximum = 500
146
147        [store.kv]
148        path = "./data/store/kv/"
149        retain_word_objects = 1000
150        pool.inactive_after = 1800
151        database.flush_after = 900
152        database.compress = true
153        database.parallelism = 2
154        database.max_compactions = 1
155        database.max_flushes = 1
156        database.write_buffer = 16384
157        database.write_ahead_log = true
158
159        [store.fst]
160        path = "./data/store/fst/"
161        pool.inactive_after = 300
162        graph.consolidate_after = 180
163        graph.max_size = 2048
164        graph.max_words = 250000
165        "#
166    }
167}