playit_agent_core/utils/
key_to_id.rs1use 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}