@@ -118,6 +118,7 @@ impl<K, V> LfuEntry<K, V> {
118
118
/// ```
119
119
pub struct LfuCache < K , V , S > {
120
120
map : HashMap < KeyRef < K > , NonNull < LfuEntry < K , V > > , S > ,
121
+ /// 因为HashSet的pop耗时太长, 所以取LruCache暂时做为平替
121
122
times_map : HashMap < u8 , LruCache < KeyRef < K > , ( ) , DefaultHasher > > ,
122
123
cap : usize ,
123
124
max_freq : u8 ,
@@ -362,7 +363,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> LfuCache<K, V, S> {
362
363
363
364
pub fn full_decrease ( & mut self ) -> Option < ( K , V ) > {
364
365
if self . cap == self . len ( ) {
365
- let ret = self . pop_last ( ) ;
366
+ let ret = self . pop_unusual ( ) ;
366
367
self . cap = self . cap . saturating_sub ( 1 ) ;
367
368
ret
368
369
} else {
@@ -460,7 +461,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> LfuCache<K, V, S> {
460
461
Drain { base : self }
461
462
}
462
463
463
- /// 弹出栈顶上的数据, 最近使用的数据
464
+ /// 弹出栈顶上的数据, 最常使用的数据
464
465
///
465
466
/// ```
466
467
/// use algorithm::LfuCache;
@@ -469,11 +470,11 @@ impl<K: Hash + Eq, V, S: BuildHasher> LfuCache<K, V, S> {
469
470
/// lru.insert("hello", "algorithm");
470
471
/// lru.insert("this", "lru");
471
472
/// let _ = lru.get("this");
472
- /// assert!(lru.pop ()==Some(("this", "lru")));
473
+ /// assert!(lru.pop_usual ()==Some(("this", "lru")));
473
474
/// assert!(lru.len() == 1);
474
475
/// }
475
476
/// ```
476
- pub fn pop ( & mut self ) -> Option < ( K , V ) > {
477
+ pub fn pop_usual ( & mut self ) -> Option < ( K , V ) > {
477
478
if self . len ( ) == 0 {
478
479
return None ;
479
480
}
@@ -488,14 +489,13 @@ impl<K: Hash + Eq, V, S: BuildHasher> LfuCache<K, V, S> {
488
489
let node = * Box :: from_raw ( value. as_ptr ( ) ) ;
489
490
let LfuEntry { key, val, .. } = node;
490
491
return Some ( ( key. assume_init ( ) , val. assume_init ( ) ) ) ;
491
- // val.take(value)
492
492
}
493
493
}
494
494
None
495
495
}
496
496
}
497
497
498
- /// 弹出栈尾上的数据, 最久未使用的数据
498
+ /// 弹出栈尾上的数据, 最不常使用的数据
499
499
///
500
500
/// ```
501
501
/// use algorithm::LfuCache;
@@ -504,11 +504,11 @@ impl<K: Hash + Eq, V, S: BuildHasher> LfuCache<K, V, S> {
504
504
/// lru.insert("hello", "algorithm");
505
505
/// lru.insert("this", "lru");
506
506
/// let _ = lru.get("this");
507
- /// assert!(lru.pop_last ()==Some(("hello", "algorithm")));
507
+ /// assert!(lru.pop_unusual ()==Some(("hello", "algorithm")));
508
508
/// assert!(lru.len() == 1);
509
509
/// }
510
510
/// ```
511
- pub fn pop_last ( & mut self ) -> Option < ( K , V ) > {
511
+ pub fn pop_unusual ( & mut self ) -> Option < ( K , V ) > {
512
512
if self . len ( ) == 0 {
513
513
return None ;
514
514
}
@@ -531,6 +531,70 @@ impl<K: Hash + Eq, V, S: BuildHasher> LfuCache<K, V, S> {
531
531
}
532
532
}
533
533
534
+ /// 取出栈顶上的数据, 最常使用的数据
535
+ ///
536
+ /// ```
537
+ /// use algorithm::LfuCache;
538
+ /// fn main() {
539
+ /// let mut lru = LfuCache::new(3);
540
+ /// lru.insert("hello", "algorithm");
541
+ /// lru.insert("this", "lru");
542
+ /// let _ = lru.get("this");
543
+ /// assert!(lru.peek_usual()==Some((&"this", &"lru")));
544
+ /// assert!(lru.len() == 2);
545
+ /// }
546
+ /// ```
547
+ pub fn peek_usual ( & mut self ) -> Option < ( & K , & V ) > {
548
+ if self . len ( ) == 0 {
549
+ return None ;
550
+ }
551
+ unsafe {
552
+ for i in ( self . min_freq ..=self . max_freq ) . rev ( ) {
553
+ if let Some ( val) = self . times_map . get_mut ( & i) {
554
+ if val. is_empty ( ) {
555
+ continue ;
556
+ }
557
+ let key = val. peek_usual ( ) . unwrap ( ) . 0 ;
558
+ let val = self . map . get ( key) . unwrap ( ) . as_ptr ( ) ;
559
+ return Some ( ( & * ( * val) . key . as_ptr ( ) , & * ( * val) . val . as_ptr ( ) ) ) ;
560
+ }
561
+ }
562
+ None
563
+ }
564
+ }
565
+
566
+ /// 取出栈尾上的数据, 最不常使用的数据
567
+ ///
568
+ /// ```
569
+ /// use algorithm::LfuCache;
570
+ /// fn main() {
571
+ /// let mut lru = LfuCache::new(3);
572
+ /// lru.insert("hello", "algorithm");
573
+ /// lru.insert("this", "lru");
574
+ /// let _ = lru.get("this");
575
+ /// assert!(lru.peek_unusual()==Some((&"hello", &"algorithm")));
576
+ /// assert!(lru.len() == 2);
577
+ /// }
578
+ /// ```
579
+ pub fn peek_unusual ( & mut self ) -> Option < ( & K , & V ) > {
580
+ if self . len ( ) == 0 {
581
+ return None ;
582
+ }
583
+
584
+ unsafe {
585
+ for i in self . min_freq ..=self . max_freq {
586
+ if let Some ( val) = self . times_map . get_mut ( & i) {
587
+ if val. is_empty ( ) {
588
+ continue ;
589
+ }
590
+ let key = val. peek_usual ( ) . unwrap ( ) . 0 ;
591
+ let val = self . map . get ( key) . unwrap ( ) . as_ptr ( ) ;
592
+ return Some ( ( & * ( * val) . key . as_ptr ( ) , & * ( * val) . val . as_ptr ( ) ) ) ;
593
+ }
594
+ }
595
+ None
596
+ }
597
+ }
534
598
pub fn contains_key < Q > ( & mut self , k : & Q ) -> bool
535
599
where
536
600
K : Borrow < Q > ,
@@ -837,7 +901,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> LfuCache<K, V, S> {
837
901
}
838
902
839
903
fn _pop_one ( keys : & mut LruCache < KeyRef < K > , ( ) , DefaultHasher > ) -> Option < KeyRef < K > > {
840
- keys. pop ( ) . map ( |( k, _) | k)
904
+ keys. pop_usual ( ) . map ( |( k, _) | k)
841
905
// let k = if let Some(k) = keys.iter().next() {
842
906
// KeyRef { k: k.k }
843
907
// } else {
@@ -894,7 +958,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> Iterator for IntoIter<K, V, S> {
894
958
type Item = ( K , V ) ;
895
959
896
960
fn next ( & mut self ) -> Option < ( K , V ) > {
897
- self . base . pop ( )
961
+ self . base . pop_usual ( )
898
962
}
899
963
900
964
fn size_hint ( & self ) -> ( usize , Option < usize > ) {
@@ -1117,7 +1181,7 @@ impl<'a, K: Hash + Eq, V, S: BuildHasher> Iterator for Drain<'a, K, V, S> {
1117
1181
if self . base . len ( ) == 0 {
1118
1182
return None ;
1119
1183
}
1120
- self . base . pop_last ( )
1184
+ self . base . pop_unusual ( )
1121
1185
}
1122
1186
}
1123
1187
@@ -1430,9 +1494,9 @@ mod tests {
1430
1494
let _ = m. get ( & 2 ) ;
1431
1495
m. insert ( 1 , 2 ) ;
1432
1496
assert_eq ! ( m. len( ) , 3 ) ;
1433
- assert_eq ! ( m. pop_last ( ) , Some ( ( 1 , 2 ) ) ) ;
1497
+ assert_eq ! ( m. pop_unusual ( ) , Some ( ( 1 , 2 ) ) ) ;
1434
1498
assert_eq ! ( m. len( ) , 2 ) ;
1435
- assert_eq ! ( m. pop_last ( ) , Some ( ( 3 , 6 ) ) ) ;
1499
+ assert_eq ! ( m. pop_unusual ( ) , Some ( ( 3 , 6 ) ) ) ;
1436
1500
assert_eq ! ( m. len( ) , 1 ) ;
1437
1501
}
1438
1502
0 commit comments