Skip to main content

linkrs_query/executor/streaming/
interner.rs

1use dashmap::DashMap;
2use std::sync::Arc;
3
4#[derive(Clone)]
5pub struct StrInterner {
6    inner: Arc<DashMap<String, Arc<str>>>,
7}
8
9impl StrInterner {
10    pub fn new() -> Self {
11        Self {
12            inner: Arc::new(DashMap::new()),
13        }
14    }
15
16    pub fn with_capacity(capacity: usize) -> Self {
17        Self {
18            inner: Arc::new(DashMap::with_capacity(capacity)),
19        }
20    }
21
22    pub fn intern(&self, s: &str) -> Arc<str> {
23        if let Some(entry) = self.inner.get(s) {
24            return Arc::clone(&entry);
25        }
26        let interned: Arc<str> = Arc::from(s);
27        self.inner
28            .insert(interned.to_string(), Arc::clone(&interned));
29        interned
30    }
31
32    pub fn intern_string(&self, s: String) -> Arc<str> {
33        if let Some(entry) = self.inner.get(s.as_str()) {
34            return Arc::clone(&entry);
35        }
36        let interned: Arc<str> = Arc::from(s);
37        self.inner
38            .insert(interned.to_string(), Arc::clone(&interned));
39        interned
40    }
41
42    pub fn len(&self) -> usize {
43        self.inner.len()
44    }
45
46    pub fn is_empty(&self) -> bool {
47        self.inner.is_empty()
48    }
49
50    pub fn clear(&self) {
51        self.inner.clear();
52    }
53}
54
55impl Default for StrInterner {
56    fn default() -> Self {
57        Self::new()
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    #[test]
66    fn test_intern_basic() {
67        let interner = StrInterner::new();
68        let a = interner.intern("hello world");
69        let b = interner.intern("hello world");
70        assert!(Arc::ptr_eq(&a, &b));
71    }
72
73    #[test]
74    fn test_intern_distinct() {
75        let interner = StrInterner::new();
76        let a = interner.intern("hello");
77        let b = interner.intern("world");
78        assert!(!Arc::ptr_eq(&a, &b));
79    }
80
81    #[test]
82    fn test_intern_string() {
83        let interner = StrInterner::new();
84        let s = String::from("test string");
85        let a = interner.intern_string(s);
86        let b = interner.intern("test string");
87        assert!(Arc::ptr_eq(&a, &b));
88    }
89}