From e68c9fed9c2464e1945da0dee51655293d3a6eaa Mon Sep 17 00:00:00 2001 From: Tatsuya Kawano Date: Thu, 3 Aug 2023 22:13:47 +0800 Subject: [PATCH 1/4] Fix a bug that eviction listener's key-level locks are not removed when immediate notification mode is used --- src/future/cache.rs | 6 ++++++ src/sync/cache.rs | 10 ++++++++++ src/sync/segment.rs | 9 +++++++++ src/sync_base/base_cache.rs | 12 ++++++++++++ src/sync_base/key_lock.rs | 11 +++++++++-- 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/future/cache.rs b/src/future/cache.rs index 3673f76a..0797d56c 100644 --- a/src/future/cache.rs +++ b/src/future/cache.rs @@ -1821,6 +1821,10 @@ where fn set_expiration_clock(&self, clock: Option) { self.base.set_expiration_clock(clock); } + + fn key_locks_map_is_empty(&self) -> bool { + self.base.key_locks_map_is_empty() + } } pub struct BlockingOp<'a, K, V, S>(&'a Cache); @@ -1962,6 +1966,7 @@ mod tests { assert!(!cache.contains_key(&"b")); verify_notification_vec(&cache, actual, &expected); + assert!(cache.key_locks_map_is_empty()); } #[test] @@ -2151,6 +2156,7 @@ mod tests { assert_eq!(cache.weighted_size(), 25); verify_notification_vec(&cache, actual, &expected); + assert!(cache.key_locks_map_is_empty()); } #[tokio::test] diff --git a/src/sync/cache.rs b/src/sync/cache.rs index d45c15d4..2bb30f42 100644 --- a/src/sync/cache.rs +++ b/src/sync/cache.rs @@ -1898,6 +1898,10 @@ where pub(crate) fn set_expiration_clock(&self, clock: Option) { self.base.set_expiration_clock(clock); } + + pub(crate) fn key_locks_map_is_empty(&self) -> bool { + self.base.key_locks_map_is_empty() + } } // To see the debug prints, run test as `cargo test -- --nocapture` @@ -2017,6 +2021,7 @@ mod tests { assert_with_mode!(!cache.contains_key(&"b"), delivery_mode); verify_notification_vec(&cache, actual, &expected, delivery_mode); + assert_with_mode!(cache.key_locks_map_is_empty(), delivery_mode); } } @@ -2147,6 +2152,7 @@ mod tests { assert_eq_with_mode!(cache.weighted_size(), 25, delivery_mode); verify_notification_vec(&cache, actual, &expected, delivery_mode); + assert_with_mode!(cache.key_locks_map_is_empty(), delivery_mode); } } @@ -3837,6 +3843,8 @@ mod tests { assert_eq!(a[0], (Arc::new("alice"), "a3", RemovalCause::Expired)); a.clear(); } + + assert!(cache.key_locks_map_is_empty()); } // This test ensures the key-level lock for the immediate notification @@ -3967,6 +3975,8 @@ mod tests { for (i, (actual, expected)) in actual.iter().zip(&expected).enumerate() { assert_eq!(actual, expected, "expected[{}]", i); } + + assert!(cache.key_locks_map_is_empty()); } // NOTE: To enable the panic logging, run the following command: diff --git a/src/sync/segment.rs b/src/sync/segment.rs index 1854a757..fbba8a12 100644 --- a/src/sync/segment.rs +++ b/src/sync/segment.rs @@ -667,6 +667,13 @@ where exp_clock } + + fn key_locks_map_is_empty(&self) -> bool { + self.inner + .segments + .iter() + .all(|seg| seg.key_locks_map_is_empty()) + } } // For unit tests. @@ -891,6 +898,7 @@ mod tests { assert_with_mode!(!cache.contains_key(&"b"), delivery_mode); verify_notification_vec(&cache, actual, &expected, delivery_mode); + assert_with_mode!(cache.key_locks_map_is_empty(), delivery_mode); } } @@ -1040,6 +1048,7 @@ mod tests { assert_eq_with_mode!(cache.weighted_size(), 25, delivery_mode); verify_notification_vec(&cache, actual, &expected, delivery_mode); + assert_with_mode!(cache.key_locks_map_is_empty(), delivery_mode); } } diff --git a/src/sync_base/base_cache.rs b/src/sync_base/base_cache.rs index cf2c1cbd..d56bf305 100644 --- a/src/sync_base/base_cache.rs +++ b/src/sync_base/base_cache.rs @@ -629,6 +629,10 @@ where pub(crate) fn set_expiration_clock(&self, clock: Option) { self.inner.set_expiration_clock(clock); } + + pub(crate) fn key_locks_map_is_empty(&self) -> bool { + self.inner.key_locks_map_is_empty() + } } struct EvictionState<'a, K, V> { @@ -2026,6 +2030,14 @@ where *exp_clock = None; } } + + fn key_locks_map_is_empty(&self) -> bool { + self.key_locks + .as_ref() + .map(|m| m.is_empty()) + // If key_locks is None, consider it is empty. + .unwrap_or(true) + } } // diff --git a/src/sync_base/key_lock.rs b/src/sync_base/key_lock.rs index 7253273a..abc96873 100644 --- a/src/sync_base/key_lock.rs +++ b/src/sync_base/key_lock.rs @@ -30,11 +30,11 @@ where S: BuildHasher, { fn drop(&mut self) { - if TrioArc::count(&self.lock) <= 1 { + if TrioArc::count(&self.lock) <= 2 { self.map.remove_if( self.hash, |k| k == &self.key, - |_k, v| TrioArc::count(v) <= 1, + |_k, v| TrioArc::count(v) <= 2, ); } } @@ -86,3 +86,10 @@ where } } } + +#[cfg(test)] +impl KeyLockMap { + pub(crate) fn is_empty(&self) -> bool { + self.locks.len() == 0 + } +} From e812abdc251cefe593a293c395b803476d69118c Mon Sep 17 00:00:00 2001 From: Tatsuya Kawano Date: Thu, 3 Aug 2023 22:14:28 +0800 Subject: [PATCH 2/4] The `master` branch has been renamed to `main` --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f8b9bdb3..e2b76d56 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ algorithm to determine which entries to evict when the capacity is exceeded. [release-badge]: https://img.shields.io/crates/v/moka.svg [docs-badge]: https://docs.rs/moka/badge.svg [deps-rs-badge]: https://deps.rs/repo/github/moka-rs/moka/status.svg -[coveralls-badge]: https://coveralls.io/repos/github/moka-rs/moka/badge.svg?branch=master +[coveralls-badge]: https://coveralls.io/repos/github/moka-rs/moka/badge.svg?branch=main [license-badge]: https://img.shields.io/crates/l/moka.svg [fossa-badge]: https://app.fossa.com/api/projects/git%2Bgithub.com%2Fmoka-rs%2Fmoka.svg?type=shield @@ -29,7 +29,7 @@ algorithm to determine which entries to evict when the capacity is exceeded. [crate]: https://crates.io/crates/moka [docs]: https://docs.rs/moka [deps-rs]: https://deps.rs/repo/github/moka-rs/moka -[coveralls]: https://coveralls.io/github/moka-rs/moka?branch=master +[coveralls]: https://coveralls.io/github/moka-rs/moka?branch=main [fossa]: https://app.fossa.com/projects/git%2Bgithub.com%2Fmoka-rs%2Fmoka?ref=badge_shield [caffeine-git]: https://github.com/ben-manes/caffeine @@ -111,9 +111,9 @@ routers. Here are some highlights: ## Change Log - For v0.10.x releases: - [CHANGELOG.md (`maint-010` branch)](https://github.com/moka-rs/moka/blob/maint-010/CHANGELOG.md) + [CHANGELOG.md (`v0.10.x` branch)](https://github.com/moka-rs/moka/blob/v0.10.x/CHANGELOG.md) - For the latest release: - [CHANGELOG.md (`master` branch)](https://github.com/moka-rs/moka/blob/master/CHANGELOG.md) + [CHANGELOG.md (`main` branch)](https://github.com/moka-rs/moka/blob/main/CHANGELOG.md) The `unsync::Cache` and `dash::Cache` have been moved to a separate crate called [Mini Moka][mini-moka-crate]: From 25b9bd8caf3e9379205696ae839fd44c4e63f322 Mon Sep 17 00:00:00 2001 From: Tatsuya Kawano Date: Fri, 4 Aug 2023 21:07:18 +0800 Subject: [PATCH 3/4] Update the change log --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d856fdd0..0a1ba4dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Moka Cache — Change Log +## Version 0.10.4 + +### Fixed + +- Fixed a bug in `sync::Cache` and `sync::SegmentedCache` where memory usage kept + increasing when the eviction listener was set with the `Immediate` delivery mode. + ([#297][gh-pull-0297]) + + ## Version 0.10.3 ### Fixed @@ -632,6 +641,7 @@ The minimum supported Rust version (MSRV) is now 1.51.0 (2021-03-25). [gh-issue-0034]: https://github.com/moka-rs/moka/issues/34/ [gh-issue-0031]: https://github.com/moka-rs/moka/issues/31/ +[gh-pull-0297]: https://github.com/moka-rs/moka/pull/297/ [gh-pull-0286]: https://github.com/moka-rs/moka/pull/286/ [gh-pull-0259]: https://github.com/moka-rs/moka/pull/259/ [gh-pull-0251]: https://github.com/moka-rs/moka/pull/251/ From 4d3e0b654bde1e9dfec61849fb4e1e6b6d70e311 Mon Sep 17 00:00:00 2001 From: Tatsuya Kawano Date: Fri, 4 Aug 2023 21:08:11 +0800 Subject: [PATCH 4/4] Bump the version to v0.10.4 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 238d2184..0af511e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "moka" -version = "0.10.3" +version = "0.10.4" edition = "2018" rust-version = "1.60" # Released on April 7, 2022, supporting 2021 edition.