Skip to main content

linkrs_api/api_core/
cost_profile.rs

1//! Canonical storage-profile to cost-model mapping.
2//!
3//! Both the embedded constructors and the network server resolve a
4//! [`StorageCostProfile`] first and then map the resolved preset onto a
5//! [`CostModelConfig`]. The mapping lives here exactly once so the two
6//! assembly paths cannot drift apart.
7
8use std::collections::HashMap;
9
10use linkrs_config::{RuntimeConfig, StorageCostProfile};
11use linkrs_query::optimizer::CostModelConfig;
12
13/// Map an already-resolved storage profile onto its cost preset.
14///
15/// Callers resolve `Auto` beforehand (`resolve` / `resolve_for_runtime`);
16/// the `Auto` arm keeps the documented SSD default for direct callers.
17pub fn cost_config_for_profile(profile: StorageCostProfile) -> CostModelConfig {
18    match profile {
19        StorageCostProfile::Hdd => CostModelConfig::for_hdd(),
20        StorageCostProfile::Ssd | StorageCostProfile::Auto => CostModelConfig::for_ssd(),
21        StorageCostProfile::Memory => CostModelConfig::for_in_memory(),
22    }
23}
24
25/// Resolve every per-space profile override with runtime knowledge.
26///
27/// Each entry goes through the same resolution as the global profile, so a
28/// memory-mode deployment short-circuits all spaces to the in-memory preset
29/// and `Auto` entries reuse the data-directory probe. Returns the resolved
30/// cost configs together with their display labels for EXPLAIN.
31pub fn resolve_space_cost_configs(
32    profiles: &HashMap<String, StorageCostProfile>,
33    runtime: &RuntimeConfig,
34) -> (HashMap<String, CostModelConfig>, HashMap<String, String>) {
35    let mut configs = HashMap::with_capacity(profiles.len());
36    let mut labels = HashMap::with_capacity(profiles.len());
37    for (space, profile) in profiles {
38        let resolved = profile.resolve_for_runtime(runtime);
39        configs.insert(space.clone(), cost_config_for_profile(resolved));
40        labels.insert(space.clone(), format!("{resolved:?}"));
41    }
42    (configs, labels)
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn presets_map_to_matching_cost_configs() {
51        assert_eq!(
52            cost_config_for_profile(StorageCostProfile::Hdd).random_page_cost,
53            CostModelConfig::for_hdd().random_page_cost
54        );
55        assert_eq!(
56            cost_config_for_profile(StorageCostProfile::Ssd).random_page_cost,
57            CostModelConfig::for_ssd().random_page_cost
58        );
59        assert_eq!(
60            cost_config_for_profile(StorageCostProfile::Memory).random_page_cost,
61            CostModelConfig::for_in_memory().random_page_cost
62        );
63    }
64
65    #[test]
66    fn auto_maps_to_ssd_default() {
67        assert_eq!(
68            cost_config_for_profile(StorageCostProfile::Auto).random_page_cost,
69            CostModelConfig::for_ssd().random_page_cost
70        );
71    }
72}