reifydb_core/interface/catalog/
config.rs1use std::{fmt, str::FromStr, time::Duration as StdDuration};
5
6use reifydb_type::value::{Value, duration::Duration, r#type::Type};
7
8use crate::common::CommitVersion;
9
10#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
11pub enum ConfigKey {
12 OracleWindowSize,
13 OracleWaterMark,
14 RowTtlScanBatchSize,
15 RowTtlScanInterval,
16}
17
18impl ConfigKey {
19 pub fn all() -> &'static [Self] {
20 &[Self::OracleWindowSize, Self::OracleWaterMark, Self::RowTtlScanBatchSize, Self::RowTtlScanInterval]
21 }
22
23 pub fn default_value(&self) -> Value {
24 match self {
25 Self::OracleWindowSize => Value::Uint8(500),
26 Self::OracleWaterMark => Value::Uint8(20),
27 Self::RowTtlScanBatchSize => Value::Uint8(10000),
28 Self::RowTtlScanInterval => Value::Duration(Duration::from_seconds(60).unwrap()),
29 }
30 }
31
32 pub fn description(&self) -> &'static str {
33 match self {
34 Self::OracleWindowSize => "Number of transactions per conflict-detection window.",
35 Self::OracleWaterMark => "Number of conflict windows retained before cleanup is triggered.",
36 Self::RowTtlScanBatchSize => "Max rows to examine per batch during a row TTL scan.",
37 Self::RowTtlScanInterval => "How often the row TTL actor should scan for expired rows.",
38 }
39 }
40
41 pub fn requires_restart(&self) -> bool {
42 match self {
43 Self::OracleWindowSize => false,
44 Self::OracleWaterMark => false,
45 Self::RowTtlScanBatchSize => false,
46 Self::RowTtlScanInterval => false,
47 }
48 }
49
50 pub fn expected_types(&self) -> &'static [Type] {
51 match self {
52 Self::OracleWindowSize => &[Type::Uint8],
53 Self::OracleWaterMark => &[Type::Uint8],
54 Self::RowTtlScanBatchSize => &[Type::Uint8],
55 Self::RowTtlScanInterval => &[Type::Duration],
56 }
57 }
58}
59
60impl fmt::Display for ConfigKey {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 match self {
63 Self::OracleWindowSize => write!(f, "ORACLE_WINDOW_SIZE"),
64 Self::OracleWaterMark => write!(f, "ORACLE_WATER_MARK"),
65 Self::RowTtlScanBatchSize => write!(f, "ROW_TTL_SCAN_BATCH_SIZE"),
66 Self::RowTtlScanInterval => write!(f, "ROW_TTL_SCAN_INTERVAL"),
67 }
68 }
69}
70
71impl FromStr for ConfigKey {
72 type Err = String;
73
74 fn from_str(s: &str) -> Result<Self, Self::Err> {
75 match s {
76 "ORACLE_WINDOW_SIZE" => Ok(Self::OracleWindowSize),
77 "ORACLE_WATER_MARK" => Ok(Self::OracleWaterMark),
78 "ROW_TTL_SCAN_BATCH_SIZE" => Ok(Self::RowTtlScanBatchSize),
79 "ROW_TTL_SCAN_INTERVAL" => Ok(Self::RowTtlScanInterval),
80 _ => Err(format!("Unknown system configuration key: {}", s)),
81 }
82 }
83}
84
85#[derive(Debug, Clone)]
91pub struct Config {
92 pub key: ConfigKey,
94 pub value: Value,
96 pub default_value: Value,
98 pub description: &'static str,
100 pub requires_restart: bool,
102}
103
104pub trait GetConfig: Send + Sync {
106 fn get_config(&self, key: ConfigKey) -> Value;
108 fn get_config_at(&self, key: ConfigKey, version: CommitVersion) -> Value;
110
111 fn get_config_uint8(&self, key: ConfigKey) -> u64 {
113 let val = self.get_config(key);
114 match val {
115 Value::Uint8(v) => v,
116 v => panic!("config key '{}' expected Uint8, got {:?}", key, v),
117 }
118 }
119
120 fn get_config_duration(&self, key: ConfigKey) -> StdDuration {
122 let val = self.get_config(key);
123 match val {
124 Value::Duration(v) => {
125 let total_nanos =
126 (v.get_days() as i128 * 24 * 3600 * 1_000_000_000) + (v.get_nanos() as i128);
127 StdDuration::from_nanos(total_nanos.max(0) as u64)
128 }
129 v => panic!("config key '{}' expected Duration, got {:?}", key, v),
130 }
131 }
132}