Skip to content

Commit b0a2706

Browse files
committed
add arc
1 parent ec5168f commit b0a2706

File tree

6 files changed

+256
-54
lines changed

6 files changed

+256
-54
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
[package]
22
name = "algorithm"
3-
version = "0.1.5"
3+
version = "0.1.6"
44
edition = "2021"
55
authors = ["tickbh <[email protected]>"]
66
description = "about algorithm data structure, now has lru/lru-k/lfu/slab/rbtree/roaring_bitmap/timer_wheelss, 关于算法常用的数据结构"
77
repository = "https://github.com/tickbh/algorithm-rs"
88
license = "Apache-2.0"
9-
keywords = ["algorithm", "lru", "lfu", "timerwheel", "slab"]
9+
keywords = ["arc", "lru", "lfu", "timerwheel", "slab"]
1010

1111
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1212

src/cache/arc.rs

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -264,42 +264,80 @@ impl<K: Hash + Eq, V, S: BuildHasher> ArcCache<K, V, S> {
264264
// Drain { base: self }
265265
// }
266266

267-
/// 弹出栈顶上的数据, 最近使用的数据
267+
/// 弹出栈顶上的数据, 最常使用的数据
268268
///
269269
/// ```
270270
/// use algorithm::ArcCache;
271271
/// fn main() {
272272
/// let mut arc = ArcCache::new(3);
273273
/// arc.insert("hello", "algorithm");
274274
/// arc.insert("this", "arc");
275-
/// assert!(arc.pop()==Some(("this", "arc")));
275+
/// assert!(arc.pop_usual()==Some(("this", "arc")));
276276
/// assert!(arc.len() == 1);
277277
/// }
278278
/// ```
279-
pub fn pop(&mut self) -> Option<(K, V)> {
279+
pub fn pop_usual(&mut self) -> Option<(K, V)> {
280280
if self.main_lru.len() != 0 {
281-
return self.main_lru.pop();
281+
return self.main_lru.pop_usual();
282282
}
283-
self.main_lfu.pop()
283+
self.main_lfu.pop_usual()
284284
}
285285

286-
/// 弹出栈尾上的数据, 最久未使用的数据
286+
/// 弹出栈尾上的数据, 最不常使用的数据
287287
///
288288
/// ```
289289
/// use algorithm::ArcCache;
290290
/// fn main() {
291291
/// let mut arc = ArcCache::new(3);
292292
/// arc.insert("hello", "algorithm");
293293
/// arc.insert("this", "arc");
294-
/// assert!(arc.pop_last()==Some(("hello", "algorithm")));
294+
/// assert!(arc.pop_unusual()==Some(("hello", "algorithm")));
295295
/// assert!(arc.len() == 1);
296296
/// }
297297
/// ```
298-
pub fn pop_last(&mut self) -> Option<(K, V)> {
298+
pub fn pop_unusual(&mut self) -> Option<(K, V)> {
299299
if self.main_lru.len() != 0 {
300-
return self.main_lru.pop_last();
300+
return self.main_lru.pop_unusual();
301301
}
302-
self.main_lfu.pop_last()
302+
self.main_lfu.pop_unusual()
303+
}
304+
305+
/// 取出栈顶上的数据, 最常使用的数据
306+
///
307+
/// ```
308+
/// use algorithm::ArcCache;
309+
/// fn main() {
310+
/// let mut arc = ArcCache::new(3);
311+
/// arc.insert("hello", "algorithm");
312+
/// arc.insert("this", "arc");
313+
/// assert!(arc.peek_usual()==Some((&"this", &"arc")));
314+
/// assert!(arc.len() == 2);
315+
/// }
316+
/// ```
317+
pub fn peek_usual(&mut self) -> Option<(&K, &V)> {
318+
if self.main_lru.len() != 0 {
319+
return self.main_lru.peek_usual();
320+
}
321+
self.main_lfu.peek_usual()
322+
}
323+
324+
/// 取出栈尾上的数据, 最不常使用的数据
325+
///
326+
/// ```
327+
/// use algorithm::ArcCache;
328+
/// fn main() {
329+
/// let mut arc = ArcCache::new(3);
330+
/// arc.insert("hello", "algorithm");
331+
/// arc.insert("this", "arc");
332+
/// assert!(arc.peek_last()==Some((&"hello", &"algorithm")));
333+
/// assert!(arc.len() == 2);
334+
/// }
335+
/// ```
336+
pub fn peek_last(&mut self) -> Option<(&K, &V)> {
337+
if self.main_lru.len() != 0 {
338+
return self.main_lru.peek_unusual();
339+
}
340+
self.main_lfu.peek_unusual()
303341
}
304342

305343
pub fn contains_key<Q>(&mut self, k: &Q) -> bool
@@ -483,7 +521,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> ArcCache<K, V, S> {
483521
}
484522

485523
if self.main_lru.is_full() {
486-
let (pk, pv) = self.main_lru.pop_last().unwrap();
524+
let (pk, pv) = self.main_lru.pop_unusual().unwrap();
487525
self.ghost_lru.insert(pk, pv);
488526
}
489527
self.get_or_insert_mut(k, f)
@@ -585,7 +623,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> Iterator for IntoIter<K, V, S> {
585623
type Item = (K, V);
586624

587625
fn next(&mut self) -> Option<(K, V)> {
588-
self.base.pop()
626+
self.base.pop_usual()
589627
}
590628

591629
fn size_hint(&self) -> (usize, Option<usize>) {
@@ -638,7 +676,7 @@ impl<'a, K: Hash + Eq, V, S: BuildHasher> DoubleEndedIterator for Iter<'a, K, V,
638676
impl<K: Hash + Eq, V, S: BuildHasher> DoubleEndedIterator for IntoIter<K, V, S> {
639677
#[inline]
640678
fn next_back(&mut self) -> Option<(K, V)> {
641-
self.base.pop_last()
679+
self.base.pop_unusual()
642680
}
643681
}
644682

@@ -983,9 +1021,9 @@ mod tests {
9831021
m.insert(2, 4);
9841022
m.insert(1, 2);
9851023
assert_eq!(m.len(), 3);
986-
assert_eq!(m.pop(), Some((1, 2)));
1024+
assert_eq!(m.pop_usual(), Some((1, 2)));
9871025
assert_eq!(m.len(), 2);
988-
assert_eq!(m.pop_last(), Some((3, 6)));
1026+
assert_eq!(m.pop_unusual(), Some((3, 6)));
9891027
assert_eq!(m.len(), 1);
9901028
}
9911029

src/cache/lfu.rs

Lines changed: 77 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ impl<K, V> LfuEntry<K, V> {
118118
/// ```
119119
pub struct LfuCache<K, V, S> {
120120
map: HashMap<KeyRef<K>, NonNull<LfuEntry<K, V>>, S>,
121+
/// 因为HashSet的pop耗时太长, 所以取LruCache暂时做为平替
121122
times_map: HashMap<u8, LruCache<KeyRef<K>, (), DefaultHasher>>,
122123
cap: usize,
123124
max_freq: u8,
@@ -362,7 +363,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> LfuCache<K, V, S> {
362363

363364
pub fn full_decrease(&mut self) -> Option<(K, V)> {
364365
if self.cap == self.len() {
365-
let ret = self.pop_last();
366+
let ret = self.pop_unusual();
366367
self.cap = self.cap.saturating_sub(1);
367368
ret
368369
} else {
@@ -460,7 +461,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> LfuCache<K, V, S> {
460461
Drain { base: self }
461462
}
462463

463-
/// 弹出栈顶上的数据, 最近使用的数据
464+
/// 弹出栈顶上的数据, 最常使用的数据
464465
///
465466
/// ```
466467
/// use algorithm::LfuCache;
@@ -469,11 +470,11 @@ impl<K: Hash + Eq, V, S: BuildHasher> LfuCache<K, V, S> {
469470
/// lru.insert("hello", "algorithm");
470471
/// lru.insert("this", "lru");
471472
/// let _ = lru.get("this");
472-
/// assert!(lru.pop()==Some(("this", "lru")));
473+
/// assert!(lru.pop_usual()==Some(("this", "lru")));
473474
/// assert!(lru.len() == 1);
474475
/// }
475476
/// ```
476-
pub fn pop(&mut self) -> Option<(K, V)> {
477+
pub fn pop_usual(&mut self) -> Option<(K, V)> {
477478
if self.len() == 0 {
478479
return None;
479480
}
@@ -488,14 +489,13 @@ impl<K: Hash + Eq, V, S: BuildHasher> LfuCache<K, V, S> {
488489
let node = *Box::from_raw(value.as_ptr());
489490
let LfuEntry { key, val, .. } = node;
490491
return Some((key.assume_init(), val.assume_init()));
491-
// val.take(value)
492492
}
493493
}
494494
None
495495
}
496496
}
497497

498-
/// 弹出栈尾上的数据, 最久未使用的数据
498+
/// 弹出栈尾上的数据, 最不常使用的数据
499499
///
500500
/// ```
501501
/// use algorithm::LfuCache;
@@ -504,11 +504,11 @@ impl<K: Hash + Eq, V, S: BuildHasher> LfuCache<K, V, S> {
504504
/// lru.insert("hello", "algorithm");
505505
/// lru.insert("this", "lru");
506506
/// let _ = lru.get("this");
507-
/// assert!(lru.pop_last()==Some(("hello", "algorithm")));
507+
/// assert!(lru.pop_unusual()==Some(("hello", "algorithm")));
508508
/// assert!(lru.len() == 1);
509509
/// }
510510
/// ```
511-
pub fn pop_last(&mut self) -> Option<(K, V)> {
511+
pub fn pop_unusual(&mut self) -> Option<(K, V)> {
512512
if self.len() == 0 {
513513
return None;
514514
}
@@ -531,6 +531,70 @@ impl<K: Hash + Eq, V, S: BuildHasher> LfuCache<K, V, S> {
531531
}
532532
}
533533

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+
}
534598
pub fn contains_key<Q>(&mut self, k: &Q) -> bool
535599
where
536600
K: Borrow<Q>,
@@ -837,7 +901,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> LfuCache<K, V, S> {
837901
}
838902

839903
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)
841905
// let k = if let Some(k) = keys.iter().next() {
842906
// KeyRef { k: k.k }
843907
// } else {
@@ -894,7 +958,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> Iterator for IntoIter<K, V, S> {
894958
type Item = (K, V);
895959

896960
fn next(&mut self) -> Option<(K, V)> {
897-
self.base.pop()
961+
self.base.pop_usual()
898962
}
899963

900964
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> {
11171181
if self.base.len() == 0 {
11181182
return None;
11191183
}
1120-
self.base.pop_last()
1184+
self.base.pop_unusual()
11211185
}
11221186
}
11231187

@@ -1430,9 +1494,9 @@ mod tests {
14301494
let _ = m.get(&2);
14311495
m.insert(1, 2);
14321496
assert_eq!(m.len(), 3);
1433-
assert_eq!(m.pop_last(), Some((1, 2)));
1497+
assert_eq!(m.pop_unusual(), Some((1, 2)));
14341498
assert_eq!(m.len(), 2);
1435-
assert_eq!(m.pop_last(), Some((3, 6)));
1499+
assert_eq!(m.pop_unusual(), Some((3, 6)));
14361500
assert_eq!(m.len(), 1);
14371501
}
14381502

0 commit comments

Comments
 (0)