Skip to content

Commit 8a9f4d6

Browse files
committed
lru带ttl设置
1 parent fa67f52 commit 8a9f4d6

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

src/cache/lru.rs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ pub(crate) struct LruEntry<K, V> {
2929
pub val: mem::MaybeUninit<V>,
3030
pub prev: *mut LruEntry<K, V>,
3131
pub next: *mut LruEntry<K, V>,
32-
32+
/// 带ttl的过期时间,单位秒
33+
/// 如果为u64::MAX,则表示不过期
3334
#[cfg(feature = "ttl")]
3435
pub expire: u64,
3536
}
@@ -115,12 +116,15 @@ pub struct LruCache<K, V, S> {
115116
head: *mut LruEntry<K, V>,
116117
/// 双向列表的尾
117118
tail: *mut LruEntry<K, V>,
118-
119+
/// 下一次检查的时间点,如果大于该时间点则全部检查是否过期
119120
#[cfg(feature = "ttl")]
120121
check_next: u64,
121-
122+
/// 每次大检查点的时间间隔,如果不想启用该特性,可以将该值设成u64::MAX
122123
#[cfg(feature = "ttl")]
123124
check_step: u64,
125+
/// 所有节点中是否存在带ttl的结点,如果均为普通的元素,则过期的将不进行检查
126+
#[cfg(feature = "ttl")]
127+
has_ttl: bool,
124128
}
125129

126130
impl<K: Hash + Eq, V> Default for LruCache<K, V, DefaultHasher> {
@@ -155,6 +159,8 @@ impl<K, V, S> LruCache<K, V, S> {
155159
check_step: DEFAULT_CHECK_STEP,
156160
#[cfg(feature = "ttl")]
157161
check_next: get_timestamp()+DEFAULT_CHECK_STEP,
162+
#[cfg(feature = "ttl")]
163+
has_ttl: false,
158164
}
159165
}
160166

@@ -604,7 +610,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> LruCache<K, V, S> {
604610
self.detach(node);
605611
#[cfg(feature = "ttl")]
606612
unsafe {
607-
if (*node).is_expire() {
613+
if self.has_ttl && (*node).is_expire() {
608614
self.map.remove(KeyWrapper::from_ref(k));
609615
let _ = *Box::from_raw(node);
610616
return None;
@@ -638,6 +644,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> LruCache<K, V, S> {
638644
/// 如果需要更新则需要手动的进行重新设置
639645
#[inline(always)]
640646
pub fn insert_with_ttl(&mut self, k: K, v: V, ttl: u64) -> Option<V> {
647+
self.has_ttl = true;
641648
self._capture_insert_with_ttl(k, v, ttl).map(|(_, v, _)| v)
642649
}
643650

@@ -719,6 +726,9 @@ impl<K: Hash + Eq, V, S: BuildHasher> LruCache<K, V, S> {
719726

720727
#[cfg(feature="ttl")]
721728
pub fn clear_expire(&mut self) {
729+
if !self.has_ttl {
730+
return;
731+
}
722732
let now = get_timestamp();
723733
if now < self.check_next {
724734
return;
@@ -755,6 +765,7 @@ impl<K: Hash + Eq, V, S: BuildHasher> LruCache<K, V, S> {
755765
K: Borrow<Q>,
756766
Q: Hash + Eq + ?Sized, {
757767
if let Some(v) = self.get_node(&k) {
768+
self.has_ttl = true;
758769
unsafe {
759770
(*v).expire = get_timestamp().saturating_add(expire);
760771
}
@@ -1640,4 +1651,17 @@ mod tests {
16401651
assert_eq!(lru.get("help"), None);
16411652
assert_eq!(lru.len(), 0);
16421653
}
1654+
1655+
1656+
#[test]
1657+
#[cfg(feature="ttl")]
1658+
fn test_ttl_get() {
1659+
let mut lru = LruCache::new(3);
1660+
lru.insert_with_ttl("help", "ok", 1);
1661+
lru.insert_with_ttl("author", "tickbh", 2);
1662+
lru.insert("now", "algorithm");
1663+
assert_eq!(lru.get_ttl(&"help"), Some(1));
1664+
assert_eq!(lru.get_ttl(&"author"), Some(2));
1665+
assert_eq!(lru.get_ttl(&"now"), Some(u64::MAX));
1666+
}
16431667
}

src/util.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ pub fn get_timestamp() -> u64 {
77
}
88

99
#[inline(always)]
10-
pub fn get_milltimestamp() -> u128 {
11-
SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).expect("ok").as_millis()
10+
pub fn get_milltimestamp() -> u64 {
11+
SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).expect("ok").as_millis() as u64
1212
}

0 commit comments

Comments
 (0)