- Added support for per-entry expiration (#248):
- In addition to the existing TTL and TTI (time-to-idle) expiration times that
apply to all entries in the cache, the
sync
andfuture
caches can now allow different expiration times for individual entries.
- In addition to the existing TTL and TTI (time-to-idle) expiration times that
apply to all entries in the cache, the
- Added the
remove
method to thesync
andfuture
caches (#255):- Like the
invalidate
method, this method discards any cached value for the key, but returns a clone of the value.
- Like the
- Fixed the caches mutating a deque node through a
NonNull
pointer derived from a shared reference. (#259)
- Removed
unsync
cache that was marked as deprecated in v0.10.0.
Bumped the minimum supported Rust version (MSRV) to 1.60 (2022-04-07). (#252)
- Upgraded
quanta
crate to v0.11.0. (#251)- This resolved "RUSTSEC-2020-0168:
mach
is unmaintained" (#243) by replacingmach
withmach2
. quanta
v0.11.0's MSRV is 1.60, so we also bumped the MSRV of Moka to 1.60.
- This resolved "RUSTSEC-2020-0168:
- Fixed a bug that
future
cache'sblocking().invalidate(key)
method does not trigger the eviction listener. (#242)
- Now
sync
andfuture
caches will not cache anything when the max capacity is set to zero (#230):- Previously, they would cache some entries for short time (< 0.5 secs) even though the max capacity is zero.
- The following caches have been moved to a separate crate called
Mini-Moka:
moka::unsync::Cache
→mini_moka::unsync::Cache
moka::dash::Cache
→mini_moka::sync::Cache
- The following methods have been removed from
sync
andfuture
caches (#199). They were deprecated in v0.8.0:get_or_insert_with
(Useget_with
instead)get_or_try_insert_with
(Usetry_get_with
instead)
- The following methods of
sync
andfuture
caches have been marked as deprecated (#193):get_with_if
(Useentry
API'sor_insert_with_if
instead)
- Add
entry
andentry_by_ref
APIs tosync
andfuture
caches (#193):- They allow users to perform more complex operations on a cache entry. At this
point, the following operations (methods) are provided:
or_default
or_insert
or_insert_with
or_insert_with_if
or_optionally_insert_with
or_try_insert_with
- The above methods return
Entry
type, which providesis_fresh
method to check if the value was freshly computed or already existed in the cache.
- They allow users to perform more complex operations on a cache entry. At this
point, the following operations (methods) are provided:
- Fix an issue that
get_with
method offuture
cache inflates future size by ~7x, sometimes causing stack overflow (#212):- This was caused by a known
rustc
optimization issue on async functions (rust-lang/rust#62958). - Added a workaround to our cache and now it will only inflate the size by ~2.5x.
- This was caused by a known
- Fix a bug that setting the number of segments of
sync
cache will disable notifications. (#207)
- Add examples for
build_with_hasher
method of cache builders. (#216)
- Prevent race condition in
get_with
family methods to avoid evaluatinginit
closure or future multiple times in concurrent calls. (#195)
- Add
optionally_get_with
method tosync
andfuture
caches (#187, by @LMJW):- It is similar to
try_get_with
but takes an init closure/future returning anOption<V>
instead ofResult<V, E>
.
- It is similar to
- Add
by_ref
version of API forget_with
,optionally_get_with
, andtry_get_with
ofsync
andfuture
caches (#190, by @LMJW):- They are similar to the non-
by_ref
versions but take a reference of the key instead of an owned key. If the key does not exist in the cache, the key will be cloned to create new entry in the cache.
- They are similar to the non-
- Fix memory leak after dropping a
sync
orfuture
cache (#177):- This leaked the value part of cache entries.
- Add an experimental
js
feature to makeunsync
andsync
caches to compile forwasm32-unknown-unknown
target (#173, by @aspect):- Note that we have not tested if these caches work correctly in wasm32 environment.
- Add an option to the cache builder of the following caches not to start and use the
global thread pools for housekeeping tasks (#165):
sync::Cache
sync::SegmentedCache
- Ensure that the following caches will drop the value of evicted entries immediately
after eviction (#169):
sync::Cache
sync::SegmentedCache
future::Cache
- Fix segmentation faults in
sync
andfuture
caches under heavy loads on many-core machine (#34):- NOTE: Although this issue was found in our testing environment ten months ago (v0.5.1), no user reported that they had the same issue.
- NOTE: In v0.8.4, we added a mitigation to reduce the chance of the segfaults occurring.
- Upgrade crossbeam-epoch from v0.8.2 to v0.9.9 (#157):
- This will make GitHub Dependabot to stop alerting about a security advisory CVE-2022-23639 for crossbeam-utils versions < 0.8.7.
- Moka v0.9.1 or older was not vulnerable to the CVE:
- Although the older crossbeam-epoch v0.8.2 depends on an affected version of crossbeam-utils, epoch v0.8.2 does not use the affected functions of utils. (#162)
- Relax a too restrictive requirement
Arc<K>: Borrow<Q>
for the key&Q
of thecontains_key
,get
andinvalidate
methods in the following caches (withK
as the key type) (#167). The requirement is nowK: Borrow<Q>
so these methods will accept&[u8]
for the key&Q
when the stored keyK
isVec<u8>
.sync::Cache
sync::SegmentedCache
future::Cache
- Add support for eviction listener to the following caches (#145).
Eviction listener is a callback function that will be called when an entry is
removed from the cache:
sync::Cache
sync::SegmentedCache
future::Cache
- Add a crate feature
sync
for enabling and disablingsync
caches. (#141 by @Milo123459, and #143)- This feature is enabled by default.
- When using experimental
dash
cache, opting out ofsync
will reduce the number of dependencies.
- Add a crate feature
logging
to enable optional log crate dependency. (#159)- Currently log will be emitted only when an eviction listener has panicked.
- Fix a bug caused
invalidate_all
andinvalidate_entries_if
of the following caches will not invalidate entries inserted just before calling them (#155):sync::Cache
sync::SegmentedCache
future::Cache
- Experimental
dash::Cache
- Add basic stats (
entry_count
andweighted_size
) methods to all caches. (#137) - Add
Debug
impl to the following caches (#138):sync::Cache
sync::SegmentedCache
future::Cache
unsync::Cache
- Remove unnecessary
K: Clone
bound from the following caches when they areClone
(#133):sync::Cache
future::Cache
- Experimental
dash::Cache
- Fix the following issue by upgrading Quanta crate to v0.10.0 (#126):
- Quanta v0.9.3 or older may not work correctly on some x86_64 machines where the Time Stamp Counter (TSC) is not synched across the processor cores. (#119)
- For more details about the issue, see the relevant section of the README.
- Add
get_with_if
method to the following caches (#123):sync::Cache
sync::SegmentedCache
future::Cache
The followings are internal changes to improve memory safety in unsafe Rust usages in Moka:
- Remove pointer-to-integer transmute by converting
UnsafeWeakPointer
fromusize
to*mut T
. (#127, by saethlin) - Increase the num segments of the waiters hash table from 16 to 64
(#129) to reduce the chance of the following issue occurring:
- Segfaults under heavy workloads on a many-core machine. (#34)
- Make Quanta crate optional (but enabled by default)
(#121)
- Quanta v0.9.3 or older may not work correctly on some x86_64 machines where the Time Stamp Counter (TSC) is not synched across the processor cores. (#119)
- This issue was fixed by Quanta v0.10.0. You can prevent the issue by upgrading Moka to v0.8.4 or newer.
- For more details about the issue, see the relevant section of the README.
- Add iterator to the following caches: (#114)
sync::Cache
sync::SegmentedCache
future::Cache
unsync::Cache
- Implement
IntoIterator
to the all caches (including experimentaldash::Cache
) (#114)
- Fix the
dash::Cache
iterator not to return expired entries. (#116) - Prevent "index out of bounds" error when
sync::SegmentedCache
was created with a non-power-of-two segments. (#117)
- Add
contains_key
method to check if a key is present without resetting the idle timer or updating the historic popularity estimator. (#107)
As a part of stabilizing the cache API, the following cache methods have been renamed:
get_or_insert_with(K, F)
→get_with(K, F)
get_or_try_insert_with(K, F)
→try_get_with(K, F)
Old methods are still available but marked as deprecated. They will be removed in a future version.
Also policy
method was added to all caches and blocking
method was added to
future::Cache
. They return a Policy
struct or BlockingOp
struct
respectively. Some uncommon cache methods were moved to these structs, and old
methods were removed without deprecating.
Please see #105 for the complete list of the affected methods.
- API stabilization. (Smaller core cache API, shorter names for common methods) (#105)
- Performance related:
- Update the minimum versions of dependencies:
- crossbeam-channel to v0.5.4. (#100)
- scheduled-thread-pool to v0.2.5. (#103, by @Milo123459)
- (dev-dependency) skeptic to v0.13.5. (#104)
- Add a synchronous cache
moka::dash::Cache
, which usesdashmap::DashMap
as the internal storage. (#99) - Add iterator to
moka::dash::Cache
. (#101)
Please note that the above additions are highly experimental and their APIs will be frequently changed in next few releases.
The minimum supported Rust version (MSRV) is now 1.51.0 (2021-03-25).
- Addressed a memory utilization issue that will get worse when keys have hight
cardinality (#72):
- Reduce memory overhead in the internal concurrent hash table (cht). (#79)
- Fix a bug that can create oversized frequency sketch when weigher is set. (#75)
- Change
EntryInfo
fromenum
tostruct
to reduce memory utilization. (#76) - Replace some
std::sync::Arc
usages withtriomphe::Arc
to reduce memory utilization. (#80) - Embed
CacheRegion
value into a 2-bit tag space ofTagNonNull
pointer. (#84)
- Fix a bug that will use wrong (oversized) initial capacity for the internal cht. (#83)
- Add
unstable-debug-counters
feature for testing purpose. (#82)
- Import (include) cht source files for better integration. (#77, #86)
- Improve the CI coverage for Clippy lints and fix some Clippy warnings in unit tests. (#73, by @06chaynes)
- Important Fix: A memory leak issue (#65 below) was found in all previous versions (since v0.1.0) and fixed in this version. All users are encouraged to upgrade to this or newer version.
- Fix a memory leak that will happen when evicting/expiring an entry or manually invalidating an entry. (#65)
- Update the minimum depending version of crossbeam-channel from v0.5.0 to v0.5.2. (#67)
- Breaking change: The type of the
max_capacity
has been changed fromusize
tou64
. This was necessary to have the weight-based cache management consistent across different CPU architectures.
- Add support for weight-based (size aware) cache management. (#24)
- Add support for unbound cache. (#24)
- Fix a bug in
get_or_insert_with
andget_or_try_insert_with
methods offuture::Cache
, which caused a panic if previously inserting task aborted. (#59)
- Remove
Send
and'static
bounds fromget_or_insert_with
andget_or_try_insert_with
methods offuture::Cache
. (#53, by @tinou98)
- Protect overflow when computing expiration. (#56, by @barkanido)
- Fix a bug in
get_or_insert_with
andget_or_try_insert_with
methods offuture::Cache
andsync::Cache
; a panic in theinit
future/closure causes subsequent calls on the same key to get "unreachable code" panics. (#43)
- Change
get_or_try_insert_with
to return a concrete error type rather than a trait object. (#23, #37)
- Restore quanta dependency on some 32-bit platforms such as
armv5te-unknown-linux-musleabi
ormips-unknown-linux-musl
. (#42, by @messense)
- Add support for some 32-bit platforms where
std::sync::atomic::AtomicU64
is not provided. (e.g.armv5te-unknown-linux-musleabi
ormips-unknown-linux-musl
) (#38)- On these platforms, you will need to disable the default features of Moka. See the relevant section of the README.
- Fix a bug in
get_or_insert_with
andget_or_try_insert_with
methods offuture::Cache
by adding missing boundsSend
and'static
to theinit
future. Without this fix, these methods will accept non-Send
or non-'static
future and may cause undefined behavior. (#31) - Fix
usize
overflow on big cache capacity. (#28)
- Add examples for
get_or_insert_with
andget_or_try_insert_with
methods to the docs. (#30)
- Downgrade crossbeam-epoch used in moka-cht from v0.9.x to v0.8.x as a possible workaround for segmentation faults on many-core CPU machines. (#33)
- Replace a dependency cht v0.4 with moka-cht v0.5. (#22)
- Add
get_or_insert_with
andget_or_try_insert_with
methods tosync
andfuture
caches. (#20)
- Breaking change: Now
sync::{Cache, SegmentedCache}
andfuture::Cache
requireSend
,Sync
and'static
for the generic parametersK
(key),V
(value) andS
(hasher state). This is necessary to prevent potential undefined behaviors in applications using single-threaded async runtime such as Actix-rt. (#19)
- Add
invalidate_entries_if
method tosync
,future
andunsync
caches. (#12)
- Stop skeptic from having to be compiled by all downstream users. (#16, by @paolobarbolini)
- Add an unsync cache (
moka::unsync::Cache
) and its builder for single-thread applications. (#9) - Add
invalidate_all
method tosync
,future
andunsync
caches. (#11)
- Fix problems including segfault caused by race conditions between the sync/eviction thread and client writes. (Addressed as a part of #11).
- Add an asynchronous, futures aware cache (
moka::future::Cache
) and its builder. (#7)
- Add thread-safe, highly concurrent in-memory cache implementations
(
moka::sync::{Cache, SegmentedCache}
) with the following features:- Bounded by the maximum number of elements.
- Maintains good hit rate by using entry replacement algorithms inspired by
Caffeine:
- Admission to a cache is controlled by the Least Frequently Used (LFU) policy.
- Eviction from a cache is controlled by the Least Recently Used (LRU) policy.
- Expiration policies:
- Time to live
- Time to idle