libnsave/tmohash/
tmo.rs

1use super::iter::*;
2use core::fmt;
3use hashbrown::HashMap;
4use std::{
5    borrow::Borrow,
6    hash::Hash,
7    mem,
8    ptr::{self, NonNull},
9};
10
11struct KeyRef<K> {
12    k: *const K,
13}
14
15impl<K: Hash> Hash for KeyRef<K> {
16    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
17        unsafe { (*self.k).hash(state) }
18    }
19}
20
21impl<K: PartialEq> PartialEq for KeyRef<K> {
22    fn eq(&self, other: &Self) -> bool {
23        unsafe { (*self.k).eq(&*other.k) }
24    }
25}
26
27impl<K: Eq> Eq for KeyRef<K> {}
28
29impl<K> Borrow<K> for KeyRef<K> {
30    fn borrow(&self) -> &K {
31        unsafe { &*self.k }
32    }
33}
34
35#[derive(Debug)]
36pub(crate) struct Node<K, V> {
37    pub(crate) key: mem::MaybeUninit<K>,
38    pub(crate) value: mem::MaybeUninit<V>,
39    pub(crate) prev: *mut Node<K, V>,
40    pub(crate) next: *mut Node<K, V>,
41}
42
43impl<K, V> Node<K, V> {
44    fn new_dummy() -> Self {
45        Node {
46            key: mem::MaybeUninit::uninit(),
47            value: mem::MaybeUninit::uninit(),
48            prev: ptr::null_mut(),
49            next: ptr::null_mut(),
50        }
51    }
52
53    fn init_dummy(&mut self, key: K, val: V) {
54        unsafe {
55            self.key.as_mut_ptr().write(key);
56            self.value.as_mut_ptr().write(val);
57        }
58    }
59}
60
61pub struct TmoHash<K, V>
62where
63    K: Eq + Hash,
64{
65    hash: HashMap<KeyRef<K>, NonNull<Node<K, V>>>,
66    capacity: usize,
67    pool: *mut Node<K, V>,
68    pool_num: usize,
69    head: *mut Node<K, V>, // 可能最老的节点,新的节点都在tail,那老的节点会逐渐剩下到head上
70    tail: *mut Node<K, V>,
71}
72
73impl<K, V> TmoHash<K, V>
74where
75    K: Eq + Hash,
76{
77    pub fn new(capacity: usize) -> TmoHash<K, V> {
78        let mut tmo = TmoHash {
79            hash: HashMap::with_capacity(capacity),
80            capacity,
81            pool: Box::into_raw(Box::new(Node::new_dummy())),
82            pool_num: 0,
83            head: Box::into_raw(Box::new(Node::new_dummy())),
84            tail: Box::into_raw(Box::new(Node::new_dummy())),
85        };
86
87        unsafe {
88            (*tmo.head).next = tmo.tail;
89            (*tmo.tail).prev = tmo.head;
90        }
91        for _ in 0..capacity {
92            let dummy = Box::new(Node::<K, V>::new_dummy());
93            tmo.pool_put(dummy);
94        }
95        tmo
96    }
97
98    fn pool_put(&mut self, node: Box<Node<K, V>>) {
99        if !self.pool_is_full() {
100            let node = Box::into_raw(node);
101            unsafe {
102                (*node).next = (*self.pool).next;
103                (*self.pool).next = node;
104            };
105            self.pool_num += 1;
106        }
107    }
108
109    fn pool_get(&mut self) -> Option<Box<Node<K, V>>> {
110        if self.pool_is_empty() {
111            return None;
112        }
113
114        unsafe {
115            let node_ptr = (*self.pool).next;
116            (*self.pool).next = (*node_ptr).next;
117            self.pool_num -= 1;
118            Some(Box::from_raw(node_ptr))
119        }
120    }
121
122    /// 返回内存池中当前剩余node的数量
123    pub fn pool_len(&self) -> usize {
124        self.pool_num
125    }
126
127    fn pool_is_empty(&self) -> bool {
128        self.pool_num == 0
129    }
130
131    fn pool_is_full(&self) -> bool {
132        self.pool_num >= self.capacity
133    }
134
135    /// 释放内存池中所有node
136    fn pool_clear(&mut self) {
137        unsafe {
138            let mut p = (*self.pool).next;
139            while !p.is_null() {
140                let next = (*p).next;
141                let _ = Box::from_raw(p);
142                p = next;
143            }
144            let _ = Box::from_raw(self.pool);
145        }
146        self.pool_num = 0;
147    }
148
149    /// 新结点添加到尾部,头部是老的,尾部是新的
150    fn list_attach(&mut self, node: *mut Node<K, V>) {
151        unsafe {
152            let prev = (*self.tail).prev;
153            (*node).prev = prev;
154            (*node).next = self.tail;
155            (*prev).next = node;
156            (*self.tail).prev = node;
157        }
158    }
159
160    fn list_detach(&mut self, node: *mut Node<K, V>) {
161        unsafe {
162            (*(*node).prev).next = (*node).next;
163            (*(*node).next).prev = (*node).prev;
164        }
165    }
166
167    fn insert_inner(&mut self, key: K, val: V) -> Option<*mut Node<K, V>> {
168        if self.capacity == 0 || self.is_full() || self.pool_is_empty() {
169            return None;
170        }
171
172        if let Some(mut node) = self.pool_get() {
173            node.init_dummy(key, val);
174            unsafe {
175                let new = NonNull::new_unchecked(Box::into_raw(node));
176                let new_ptr = new.as_ptr();
177                let keyref = (*new_ptr).key.as_ptr();
178                self.list_attach(new_ptr);
179                self.hash.insert(KeyRef { k: keyref }, new);
180                return Some(new_ptr);
181            }
182        }
183        None
184    }
185
186    /// 插入一个k v对儿,如果已经存在,会替代。
187    /// 返回插入value的引用
188    /// 因为限于在流表场景下使用,所以在insert之前,用户需要确保节点不存在,也就是不要产生替代的情况
189    /// # Example
190    ///
191    /// ```
192    /// use libnsave::tmohash::TmoHash;
193    ///
194    /// let mut tmo = TmoHash::new(10);
195    /// assert_eq!(Some(&"a"), tmo.insert(1, "a"));
196    /// assert!(tmo.contains_key(&1));
197    /// assert!(!tmo.contains_key(&2));
198    /// ```
199    pub fn insert(&mut self, key: K, val: V) -> Option<&V> {
200        if let Some(new_ptr) = self.insert_inner(key, val) {
201            unsafe {
202                return Some(&*(*new_ptr).value.as_mut_ptr());
203            }
204        }
205        None
206    }
207
208    /// 插入一个k v对儿,如果已经存在,会替代。
209    /// 返回插入value的可变引用
210    /// 因为限于在流表场景下使用,所以在insert之前,用户需要确保节点不存在,也就是不要产生替代的情况
211    /// # Example
212    ///
213    /// ```
214    /// use libnsave::tmohash::TmoHash;
215    ///
216    /// let mut tmo = TmoHash::new(10);
217    /// assert_eq!(Some(&mut "a"), tmo.insert_mut(1, "a"));
218    /// assert!(tmo.contains_key(&1));
219    /// assert!(!tmo.contains_key(&2));
220    /// ```
221    pub fn insert_mut(&mut self, key: K, val: V) -> Option<&mut V> {
222        if let Some(new_ptr) = self.insert_inner(key, val) {
223            unsafe {
224                return Some(&mut *(*new_ptr).value.as_mut_ptr());
225            }
226        }
227        None
228    }
229
230    /// 删除一个key
231    ///
232    /// #Example
233    ///
234    /// ```
235    /// use libnsave::tmohash::TmoHash;
236    ///
237    /// let mut tmo = TmoHash::new(10);
238    /// tmo.insert(1, "a");
239    /// tmo.insert(2, "b");
240    /// tmo.insert(3, "c");
241    /// tmo.remove(&2);
242    /// assert!(tmo.contains_key(&1));
243    /// assert!(tmo.contains_key(&3));
244    /// assert!(!tmo.contains_key(&2));
245    /// ```
246    pub fn remove(&mut self, k: &K) {
247        if let Some(node) = self.hash.remove(k) {
248            let mut node = unsafe { Box::from_raw(node.as_ptr()) };
249            self.list_detach(&mut *node);
250            self.pool_put(node);
251        }
252    }
253
254    /// 根据key,判断是否存在节点
255    ///
256    /// #Example
257    ///
258    /// ```
259    /// use libnsave::tmohash::TmoHash;
260    ///
261    /// let mut tmo = TmoHash::new(10);
262    /// tmo.insert(1, "a");
263    /// tmo.insert(2, "b");
264    /// assert!(tmo.contains_key(&1));
265    /// assert!(tmo.contains_key(&2));
266    /// assert!(!tmo.contains_key(&3));
267    /// ```
268    pub fn contains_key(&self, key: &K) -> bool {
269        self.hash.contains_key(key)
270    }
271
272    /// 返回最大容量
273    ///
274    /// #Example
275    ///
276    /// ```
277    /// use libnsave::tmohash::TmoHash;
278    ///
279    /// let mut tmo: TmoHash<usize, String> = TmoHash::new(10);
280    /// assert_eq!(tmo.capacity(), 10);
281    /// ```
282    pub fn capacity(&self) -> usize {
283        self.capacity
284    }
285
286    /// 返回已有数据的个数
287    ///
288    /// #Example
289    ///
290    /// ```
291    /// use libnsave::tmohash::TmoHash;
292    ///
293    /// let mut tmo = TmoHash::new(10);
294    /// assert_eq!(tmo.len(), 0);
295    /// tmo.insert(1, "a");
296    /// tmo.insert(2, "b");
297    /// assert_eq!(tmo.len(), 2);
298    /// ```
299    pub fn len(&self) -> usize {
300        self.hash.len()
301    }
302
303    /// 返回是否为空
304    ///
305    /// #Example
306    ///
307    /// ```
308    /// use libnsave::tmohash::TmoHash;
309    ///
310    /// let mut tmo = TmoHash::new(10);
311    /// assert!(tmo.is_empty());
312    /// tmo.insert(1, "a");
313    /// assert!(!tmo.is_empty());
314    /// ```
315    pub fn is_empty(&self) -> bool {
316        self.hash.is_empty()
317    }
318
319    /// 返回是否已满
320    ///
321    /// #Example
322    ///
323    /// ```
324    /// use libnsave::tmohash::TmoHash;
325    ///
326    /// let mut tmo: TmoHash<usize, usize> = TmoHash::new(10);
327    /// assert!(!tmo.is_full());
328    /// for i in 0..10 {
329    ///     tmo.insert(i, i);
330    /// }
331    /// assert!(tmo.is_full());
332    /// ```
333    pub fn is_full(&self) -> bool {
334        self.hash.len() >= self.capacity
335    }
336
337    /// 根据key,查询返回value的引用。因为是不变引用,说明没有更新,所以不需要重新移动到链表尾部
338    ///
339    /// #Example
340    ///
341    /// ```
342    /// use libnsave::tmohash::TmoHash;
343    ///
344    /// let mut tmo = TmoHash::new(10);
345    /// tmo.insert(1, "a");
346    /// tmo.insert(2, "b");
347    /// tmo.insert(3, "c");
348    /// assert_eq!(Some((&"a")), tmo.get(&1));
349    /// assert_eq!(Some((&"b")), tmo.get(&2));
350    /// assert_eq!(Some((&"c")), tmo.get(&3));
351    /// assert_ne!(Some((&"d")), tmo.get(&4));
352    /// ```
353    pub fn get(&self, k: &K) -> Option<&V> {
354        if let Some(node) = self.hash.get(k) {
355            let node_ptr = node.as_ptr();
356            Some(unsafe { &*(*node_ptr).value.as_ptr() })
357        } else {
358            None
359        }
360    }
361
362    /// 根据key,查询返回value的可变引用
363    ///
364    /// #Example
365    ///
366    /// ```
367    /// use libnsave::tmohash::TmoHash;
368    ///
369    /// let mut tmo = TmoHash::new(10);
370    /// tmo.insert(1, "a");
371    /// tmo.insert(2, "b");
372    /// tmo.insert(3, "c");
373    /// let node = tmo.get_mut(&1).unwrap();
374    /// *node = &"d";
375    /// assert_eq!(Some((&"d")), tmo.get(&1));
376    /// ```
377    pub fn get_mut(&mut self, k: &K) -> Option<&mut V> {
378        if let Some(node) = self.hash.get(k) {
379            let node_ptr = node.as_ptr();
380            self.list_detach(node_ptr);
381            self.list_attach(node_ptr);
382            Some(unsafe { &mut *(*node_ptr).value.as_mut_ptr() })
383        } else {
384            None
385        }
386    }
387
388    /// 从最老的node开始迭代
389    ///
390    /// #Example
391    ///
392    /// ```
393    /// use libnsave::tmohash::TmoHash;
394    ///
395    /// let mut tmo = TmoHash::new(10);
396    /// tmo.insert("a", 1);
397    /// tmo.insert("b", 2);
398    /// tmo.insert("c", 3);
399    /// let sum = tmo.iter().map(|x| x.1).sum();
400    /// assert_eq!(6, sum);
401    /// ```
402    pub fn iter(&self) -> Iter<'_, K, V> {
403        Iter {
404            done: 0,
405            len: self.len(),
406            next: unsafe { (*self.head).next },
407            phantom: std::marker::PhantomData,
408        }
409    }
410
411    /// 从最老的一端开始遍历,根据闭包返回确定是否保留此节点
412    /// 闭包为true 删除,为fals 不删除,保留
413    ///
414    /// 遇到第一个不满足条件的就返回。用于老化tmo场景。
415    /// 从最老开始,一直删除到不满足闭包条件的第一个node为止。并不遍历所有节点。只从最老开始遍历到第一个不需要老化为止。
416    /// 这样,既能尽快删除了所有需要老化的节点,也不会遍历过多
417    ///
418    /// #Example
419    ///
420    /// ```
421    /// use libnsave::tmohash::TmoHash;
422    ///
423    /// let mut tmo = TmoHash::new(10);
424    /// tmo.insert("a", 1);
425    /// tmo.insert("b", 2);
426    /// tmo.insert("c", 3);
427    /// tmo.insert("d", 10);
428    /// tmo.insert("e", 11);
429    /// tmo.insert("f", 12);
430    /// tmo.insert("g", 4);
431    /// tmo.timeout(|&_k, &v| v < 10);
432    /// assert_eq!(4, tmo.len());
433    /// assert!(!tmo.contains_key(&"a"));
434    /// assert!(!tmo.contains_key(&"b"));
435    /// assert!(!tmo.contains_key(&"c"));
436    /// assert!(tmo.contains_key(&"g"));
437    /// ```
438    pub fn timeout<F>(&mut self, fun: F)
439    where
440        F: Fn(&K, &V) -> bool,
441    {
442        if self.is_empty() {
443            return;
444        }
445
446        unsafe {
447            let mut p = (*self.head).next;
448            while p != self.tail {
449                let next = (*p).next;
450
451                let key_ref = &(*(*p).key.as_ptr());
452                let val_ref = &(*(*p).value.as_ptr());
453                if fun(key_ref, val_ref) {
454                    self.remove(key_ref);
455                } else {
456                    return;
457                }
458
459                p = next;
460            }
461        }
462    }
463
464    fn clear(&mut self) {
465        self.timeout(|_k, _v| true);
466        self.pool_clear();
467        unsafe {
468            let _ = Box::from_raw(self.head);
469            let _ = Box::from_raw(self.tail);
470        }
471    }
472}
473
474impl<K, V> Drop for TmoHash<K, V>
475where
476    K: Hash + Eq,
477{
478    fn drop(&mut self) {
479        self.clear();
480    }
481}
482
483unsafe impl<K: Send, V: Send> Send for TmoHash<K, V> where K: Eq + Hash {}
484unsafe impl<K: Sync, V: Sync> Sync for TmoHash<K, V> where K: Eq + Hash {}
485
486impl<K, V> fmt::Debug for TmoHash<K, V>
487where
488    K: fmt::Debug + Hash + Eq,
489    V: fmt::Debug,
490{
491    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
492        write!(f, "TmoHash [")?;
493        if self.is_empty() {
494            return write!(f, "]");
495        } else {
496            write!(f, " ")?;
497        }
498        let mut comma = false;
499        let iter = self.iter();
500        for kv in iter {
501            if comma {
502                write!(f, ", ")?;
503            } else {
504                comma = true;
505            }
506            write!(f, "({:?}, {:?})", kv.0, kv.1)?;
507        }
508        write!(f, " ]")
509    }
510}
511
512/// display
513///
514/// # Examples
515///
516/// ```
517/// use libnsave::tmohash::TmoHash;
518///
519/// let mut tmo = TmoHash::new(10);
520/// tmo.insert(1, "a");
521/// tmo.insert(2, "b");
522/// tmo.insert(3, "c");
523/// assert_eq!("[1: a, 2: b, 3: c]", format!("{}", tmo));
524/// ```
525impl<K, V> fmt::Display for TmoHash<K, V>
526where
527    K: fmt::Display + Hash + Eq + Clone,
528    V: fmt::Display,
529{
530    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
531        let items = self
532            .iter()
533            .map(|x| format!("{}: {}", x.0, x.1))
534            .collect::<Vec<String>>();
535        write!(f, "[{}]", items.join(", "))
536    }
537}
538
539#[cfg(test)]
540mod tests {
541    use super::*;
542    use crate::tmohash::tmo;
543
544    #[test]
545    fn test_new() {
546        let tmo: tmo::TmoHash<i32, &str> = TmoHash::new(10);
547        assert_eq!(10, tmo.pool_len());
548        assert_eq!(10, tmo.capacity());
549        assert_eq!(0, tmo.len());
550        assert!(tmo.is_empty());
551        assert!(!tmo.is_full());
552    }
553
554    #[test]
555    fn test_insert() {
556        let mut tmo = TmoHash::new(10);
557        assert_eq!(10, tmo.pool_len());
558
559        tmo.insert("a", 1);
560        assert_eq!(9, tmo.pool_len());
561        assert_eq!(1, tmo.len());
562
563        tmo.insert("b", 2);
564        assert_eq!(8, tmo.pool_len());
565        assert_eq!(2, tmo.len());
566    }
567
568    #[test]
569    fn test_debug() {
570        let mut tmo = TmoHash::new(10);
571        tmo.insert(1, "a");
572        tmo.insert(2, "b");
573        tmo.insert(3, "c");
574        assert_eq!(
575            "TmoHash [ (1, \"a\"), (2, \"b\"), (3, \"c\") ]",
576            format!("{:?}", tmo)
577        );
578    }
579
580    #[test]
581    fn test_display() {
582        let mut tmo: TmoHash<usize, &str> = TmoHash::new(10);
583        assert_eq!("[]", format!("{}", tmo));
584
585        tmo.insert(1, "a");
586        tmo.insert(2, "b");
587        tmo.insert(3, "c");
588        assert_eq!("[1: a, 2: b, 3: c]", format!("{}", tmo));
589    }
590
591    #[test]
592    fn test_iter_debug() {
593        let mut tmo = TmoHash::new(10);
594        tmo.insert(1, "a");
595        tmo.insert(2, "b");
596        tmo.insert(3, "c");
597
598        let mut iter = tmo.iter();
599        iter.next();
600        assert_eq!("Iter [1/3 next: 2]", format!("{:?}", iter));
601
602        iter.next();
603        iter.next();
604        assert_eq!("Iter [3/3]", format!("{:?}", iter));
605    }
606
607    #[test]
608    fn test_iter_display() {
609        let mut tmo = TmoHash::new(10);
610        tmo.insert(1, "a");
611        tmo.insert(2, "b");
612        tmo.insert(3, "c");
613
614        let mut iter = tmo.iter();
615        iter.next();
616        assert_eq!("Iter [1/3 next: 2]", format!("{}", iter));
617
618        iter.next();
619        iter.next();
620        assert_eq!("Iter [3/3]", format!("{}", iter));
621    }
622
623    #[test]
624    fn test_pool() {
625        let mut tmo = TmoHash::new(10);
626        assert_eq!(10, tmo.pool_len());
627
628        tmo.insert(1, "a");
629        assert_eq!(9, tmo.pool_len());
630        tmo.insert(2, "b");
631        assert_eq!(8, tmo.pool_len());
632        tmo.insert(3, "c");
633        assert_eq!(7, tmo.pool_len());
634
635        tmo.remove(&1);
636        assert_eq!(8, tmo.pool_len());
637        tmo.remove(&2);
638        assert_eq!(9, tmo.pool_len());
639        tmo.remove(&3);
640        assert_eq!(10, tmo.pool_len());
641    }
642}