Skip to main content

oxihuman_core/
priority_map.rs

1#![allow(dead_code)]
2// Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)
3// SPDX-License-Identifier: Apache-2.0
4
5use std::collections::BTreeMap;
6
7/// A map that maintains entries ordered by priority.
8#[allow(dead_code)]
9#[derive(Debug, Clone)]
10pub struct PriorityMap {
11    entries: BTreeMap<i32, Vec<(String, String)>>,
12}
13
14#[allow(dead_code)]
15pub fn new_priority_map() -> PriorityMap {
16    PriorityMap {
17        entries: BTreeMap::new(),
18    }
19}
20
21#[allow(dead_code)]
22pub fn insert_priority(map: &mut PriorityMap, key: &str, value: &str, priority: i32) {
23    map.entries
24        .entry(priority)
25        .or_default()
26        .push((key.to_string(), value.to_string()));
27}
28
29#[allow(dead_code)]
30pub fn get_highest(map: &PriorityMap) -> Option<(&str, &str)> {
31    map.entries
32        .iter()
33        .next_back()
34        .and_then(|(_, v)| v.first())
35        .map(|(k, v)| (k.as_str(), v.as_str()))
36}
37
38#[allow(dead_code)]
39pub fn remove_highest(map: &mut PriorityMap) -> Option<(String, String)> {
40    if let Some((&prio, _)) = map.entries.iter().next_back() {
41        let bucket = map.entries.get_mut(&prio)?;
42        let item = bucket.remove(0);
43        if bucket.is_empty() {
44            map.entries.remove(&prio);
45        }
46        Some(item)
47    } else {
48        None
49    }
50}
51
52#[allow(dead_code)]
53pub fn priority_count(map: &PriorityMap) -> usize {
54    map.entries.values().map(|v| v.len()).sum()
55}
56
57#[allow(dead_code)]
58pub fn has_key_pm(map: &PriorityMap, key: &str) -> bool {
59    map.entries
60        .values()
61        .any(|v| v.iter().any(|(k, _)| k == key))
62}
63
64#[allow(dead_code)]
65pub fn clear_priority_map(map: &mut PriorityMap) {
66    map.entries.clear();
67}
68
69#[allow(dead_code)]
70pub fn priority_to_vec(map: &PriorityMap) -> Vec<(String, String, i32)> {
71    let mut result = Vec::new();
72    for (&prio, bucket) in &map.entries {
73        for (k, v) in bucket {
74            result.push((k.clone(), v.clone(), prio));
75        }
76    }
77    result
78}
79
80#[cfg(test)]
81mod tests {
82    use super::*;
83
84    #[test]
85    fn test_new_priority_map() {
86        let m = new_priority_map();
87        assert_eq!(priority_count(&m), 0);
88    }
89
90    #[test]
91    fn test_insert_and_count() {
92        let mut m = new_priority_map();
93        insert_priority(&mut m, "a", "1", 10);
94        insert_priority(&mut m, "b", "2", 20);
95        assert_eq!(priority_count(&m), 2);
96    }
97
98    #[test]
99    fn test_get_highest() {
100        let mut m = new_priority_map();
101        insert_priority(&mut m, "low", "1", 1);
102        insert_priority(&mut m, "high", "2", 100);
103        let (k, _) = get_highest(&m).expect("should succeed");
104        assert_eq!(k, "high");
105    }
106
107    #[test]
108    fn test_remove_highest() {
109        let mut m = new_priority_map();
110        insert_priority(&mut m, "a", "1", 5);
111        insert_priority(&mut m, "b", "2", 10);
112        let (k, _) = remove_highest(&mut m).expect("should succeed");
113        assert_eq!(k, "b");
114        assert_eq!(priority_count(&m), 1);
115    }
116
117    #[test]
118    fn test_has_key_pm() {
119        let mut m = new_priority_map();
120        insert_priority(&mut m, "x", "1", 5);
121        assert!(has_key_pm(&m, "x"));
122        assert!(!has_key_pm(&m, "y"));
123    }
124
125    #[test]
126    fn test_clear_priority_map() {
127        let mut m = new_priority_map();
128        insert_priority(&mut m, "a", "1", 5);
129        clear_priority_map(&mut m);
130        assert_eq!(priority_count(&m), 0);
131    }
132
133    #[test]
134    fn test_priority_to_vec() {
135        let mut m = new_priority_map();
136        insert_priority(&mut m, "a", "1", 5);
137        insert_priority(&mut m, "b", "2", 10);
138        let v = priority_to_vec(&m);
139        assert_eq!(v.len(), 2);
140    }
141
142    #[test]
143    fn test_get_highest_empty() {
144        let m = new_priority_map();
145        assert!(get_highest(&m).is_none());
146    }
147
148    #[test]
149    fn test_remove_highest_empty() {
150        let mut m = new_priority_map();
151        assert!(remove_highest(&mut m).is_none());
152    }
153
154    #[test]
155    fn test_same_priority() {
156        let mut m = new_priority_map();
157        insert_priority(&mut m, "a", "1", 5);
158        insert_priority(&mut m, "b", "2", 5);
159        assert_eq!(priority_count(&m), 2);
160    }
161}