Skip to content

Commit

Permalink
Update the access time of a cached entry immediately after the entry …
Browse files Browse the repository at this point in the history
…is read
  • Loading branch information
tatsuya6502 committed Dec 24, 2023
1 parent 42b44ed commit c878eed
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 7 deletions.
1 change: 0 additions & 1 deletion src/common/concurrent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,6 @@ impl<K, V> AccessTime for TrioArc<ValueEntry<K, V>> {
pub(crate) enum ReadOp<K, V> {
Hit {
value_entry: TrioArc<ValueEntry<K, V>>,
timestamp: Instant,
is_expiry_modified: bool,
},
// u64 is the hash of the key.
Expand Down
5 changes: 2 additions & 3 deletions src/future/base_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,12 +323,13 @@ where
);
}

entry.set_last_accessed(now);

let maybe_key = if need_key { Some(Arc::clone(k)) } else { None };
let ent = Entry::new(maybe_key, entry.value.clone(), false);
let maybe_op = if record_read {
Some(ReadOp::Hit {
value_entry: TrioArc::clone(entry),
timestamp: now,
is_expiry_modified,
})
} else {
Expand Down Expand Up @@ -1586,12 +1587,10 @@ where
match ch.try_recv() {
Ok(Hit {
value_entry,
timestamp,
is_expiry_modified,
}) => {
let kh = value_entry.entry_info().key_hash();
freq.increment(kh.hash);
value_entry.set_last_accessed(timestamp);
if is_expiry_modified {
self.update_timer_wheel(&value_entry, timer_wheel);
}
Expand Down
26 changes: 26 additions & 0 deletions src/future/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2739,6 +2739,32 @@ mod tests {
verify_notification_vec(&cache, actual, &expected).await;
}

// https://github.com/moka-rs/moka/issues/359
#[tokio::test]
async fn ensure_access_time_is_updated_immediately_after_read() {
let mut cache = Cache::builder()
.max_capacity(10)
.time_to_idle(Duration::from_secs(5))
.build();
cache.reconfigure_for_testing().await;

let (clock, mock) = Clock::mock();
cache.set_expiration_clock(Some(clock)).await;

// Make the cache exterior immutable.
let cache = cache;

cache.insert(1, 1).await;

mock.increment(Duration::from_secs(4));
assert_eq!(cache.get(&1).await, Some(1));

mock.increment(Duration::from_secs(2));
assert_eq!(cache.get(&1).await, Some(1));
cache.run_pending_tasks().await;
assert_eq!(cache.get(&1).await, Some(1));
}

#[tokio::test]
async fn time_to_live_by_expiry_type() {
// The following `Vec`s will hold actual and expected notifications.
Expand Down
26 changes: 26 additions & 0 deletions src/sync/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2407,6 +2407,32 @@ mod tests {
verify_notification_vec(&cache, actual, &expected);
}

// https://github.com/moka-rs/moka/issues/359
#[test]
fn ensure_access_time_is_updated_immediately_after_read() {
let mut cache = Cache::builder()
.max_capacity(10)
.time_to_idle(Duration::from_secs(5))
.build();
cache.reconfigure_for_testing();

let (clock, mock) = Clock::mock();
cache.set_expiration_clock(Some(clock));

// Make the cache exterior immutable.
let cache = cache;

cache.insert(1, 1);

mock.increment(Duration::from_secs(4));
assert_eq!(cache.get(&1), Some(1));

mock.increment(Duration::from_secs(2));
assert_eq!(cache.get(&1), Some(1));
cache.run_pending_tasks();
assert_eq!(cache.get(&1), Some(1));
}

#[test]
fn time_to_live_by_expiry_type() {
// Define an expiry type.
Expand Down
5 changes: 2 additions & 3 deletions src/sync_base/base_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,10 +349,11 @@ where
);
}

entry.set_last_accessed(now);

let v = entry.value.clone();
let op = ReadOp::Hit {
value_entry: entry,
timestamp: now,
is_expiry_modified,
};
read_recorder(op, now);
Expand Down Expand Up @@ -1407,12 +1408,10 @@ where
match ch.try_recv() {
Ok(Hit {
value_entry,
timestamp,
is_expiry_modified,
}) => {
let kh = value_entry.entry_info().key_hash();
freq.increment(kh.hash);
value_entry.set_last_accessed(timestamp);
if is_expiry_modified {
self.update_timer_wheel(&value_entry, timer_wheel);
}
Expand Down

0 comments on commit c878eed

Please sign in to comment.