playit_agent_core/utils/
key_to_id.rs

1use std::{collections::{hash_map, HashMap}, hash::Hash};
2
3use super::id_slab::IdSlab;
4
5pub struct KeyToId<K: Eq + Hash + Clone, V> {
6    items: IdSlab<V>,
7    lookup: HashMap<K, u64>,
8}
9
10impl<K: Eq + Hash + Clone, V> Default for KeyToId<K, V> {
11    fn default() -> Self {
12        Self {
13            items: IdSlab::with_capacity(1024 * 1024),
14            lookup: HashMap::new(),
15        }
16    }
17}
18
19impl<K: Eq + Hash + Clone, V> KeyToId<K, V> {
20    pub fn get_or_add<F: FnOnce() -> V>(&mut self, key: K, value_fn: F) -> Option<u64> {
21        match self.lookup.entry(key) {
22            hash_map::Entry::Occupied(o) => Some(*o.get()),
23            hash_map::Entry::Vacant(v) => {
24                let entry = self.items.vacant_entry()?;
25
26                let id = entry.id();
27                entry.insert(value_fn());
28
29                v.insert(id);
30                Some(id)
31            }
32        }
33    }
34
35    pub fn remove(&mut self, key: &K) -> Option<(u64, V)> {
36        let id = self.lookup.remove(key)?;
37        let removed_item = self.items.remove(id).expect("item at id not found");
38        Some((id, removed_item))
39    }
40}