Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Per-entry expiration. (Add more doc and tests) #260

Merged
merged 6 commits into from
Apr 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,3 @@ rustc_version = "0.4.0"
# Build the doc with some features enabled.
features = ["future"]
rustdoc-args = ["--cfg", "docsrs"]

# ----------------------------------
# RUSTSEC, etc.
#
# crossbeam-channel:
# - Workaround a bug in upstream related to TLS access on AArch64 Linux:
# - https://github.com/crossbeam-rs/crossbeam/pull/802 (Patched >= 0.5.4)
# - Addressed some stacked borrow violations found by Miri:
# - https://github.com/crossbeam-rs/crossbeam/blob/master/crossbeam-channel/CHANGELOG.md#version-052 (Patched >= 0.5.2)
#
# smallvec:
# - https://rustsec.org/advisories/RUSTSEC-2021-0003.html (Patched >= 1.6.1)
#
# Tokio:
# - https://rustsec.org/advisories/RUSTSEC-2021-0124.html (Patched >= 1.13.1)
# - https://rustsec.org/advisories/RUSTSEC-2021-0072.html (Patched >= 1.8.1)
80 changes: 19 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,9 @@ The `unsync::Cache` and `dash::Cache` have been moved to a separate crate called
- [Synchronous Cache](#example-synchronous-cache)
- [Asynchronous Cache](#example-asynchronous-cache)
- [Avoiding to clone the value at `get`](#avoiding-to-clone-the-value-at-get)
- Examples (Part 2)
- Example (Part 2)
- [Size Aware Eviction](#example-size-aware-eviction)
- [Expiration Policies](#example-expiration-policies)
- [Hashing Algorithm](#hashing-algorithm)
- [Expiration Policies](#expiration-policies)
- [Minimum Supported Rust Versions](#minimum-supported-rust-versions)
- Troubleshooting
- [Integer Overflow in Quanta Crate on Some x86_64 Machines](#integer-overflow-in-quanta-crate-on-some-x86_64-machines)
Expand Down Expand Up @@ -392,67 +391,26 @@ fn main() {
Note that weighted sizes are not used when making eviction selections.


## Example: Expiration Policies
## Expiration Policies

Moka supports the following expiration policies:

- **Time to live**: A cached entry will be expired after the specified duration past
from `insert`.
- **Time to idle**: A cached entry will be expired after the specified duration past
from `get` or `insert`.
- **Cache-level expiration policies:**
- Cache-level policies are applied to all entries in the cache.
- **Time to live (TTL)**: A cached entry will be expired after the specified
duration past from `insert`.
- **Time to idle (TTI)**: A cached entry will be expired after the specified
duration past from `get` or `insert`.
- **Per-entry expiration policy:**
- The per-entry expiration lets you sets a different expiration time for each
entry.

To set them, use the `CacheBuilder`.
For details and examples of above policies, see the "Example: Time-based Expiration"
section ([`sync::Cache`][doc-sync-cache-expiration],
[`future::Cache`][doc-future-cache-expiration]) of the document.

```rust
use moka::sync::Cache;
use std::time::Duration;

fn main() {
let cache = Cache::builder()
// Time to live (TTL): 30 minutes
.time_to_live(Duration::from_secs(30 * 60))
// Time to idle (TTI): 5 minutes
.time_to_idle(Duration::from_secs( 5 * 60))
// Create the cache.
.build();

// This entry will expire after 5 minutes (TTI) if there is no get().
cache.insert(0, "zero");

// This get() will extend the entry life for another 5 minutes.
cache.get(&0);

// Even though we keep calling get(), the entry will expire
// after 30 minutes (TTL) from the insert().
}
```

### A note on expiration policies

The cache builders will panic if configured with either `time_to_live` or `time to idle`
longer than 1000 years. This is done to protect against overflow when computing key
expiration.


## Hashing Algorithm

By default, a cache uses a hashing algorithm selected to provide resistance against
HashDoS attacks.

The default hashing algorithm is the one used by `std::collections::HashMap`, which
is currently SipHash 1-3, though this is subject to change at any point in the
future.

While its performance is very competitive for medium sized keys, other hashing
algorithms will outperform it for small keys such as integers as well as large keys
such as long strings. However those algorithms will typically not protect against
attacks such as HashDoS.

The hashing algorithm can be replaced on a per-`Cache` basis using the
`build_with_hasher` method of the `CacheBuilder`. Many alternative algorithms are
available on crates.io, such as the [AHash][ahash-crate] crate.

[ahash-crate]: https://crates.io/crates/ahash
[doc-sync-cache-expiration]: https://docs.rs/moka/latest/moka/sync/struct.Cache.html#example-time-based-expirations
[doc-future-cache-expiration]: https://docs.rs/moka/latest/moka/future/struct.Cache.html#example-time-based-expirations


## Minimum Supported Rust Versions
Expand Down Expand Up @@ -504,7 +462,7 @@ to the dependency declaration.

```toml:Cargo.toml
[dependencies]
moka = { version = "0.11", default-features = false }
moka = { version = "0.11", default-features = false, features = ["sync"] }
# Or
moka = { version = "0.11", default-features = false, features = ["future"] }
```
Expand Down Expand Up @@ -534,7 +492,7 @@ $ RUSTFLAGS='--cfg skeptic --cfg trybuild' cargo test \

```console
$ cargo +nightly -Z unstable-options --config 'build.rustdocflags="--cfg docsrs"' \
doc --no-deps --features 'future, dash'
doc --no-deps --features future
```

## Road Map
Expand Down
1 change: 0 additions & 1 deletion src/common/deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ impl<T> Deque<T> {
self.region
}

#[cfg(any(test, feature = "sync", feature = "future"))]
pub(crate) fn len(&self) -> usize {
self.len
}
Expand Down
7 changes: 7 additions & 0 deletions src/future/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,13 @@ impl<K, V, C> CacheBuilder<K, V, C> {
builder
}

/// Sets the given `expiry` to the cache.
///
/// See [the example][per-entry-expiration-example] for per-entry expiration
/// policy in the `Cache` documentation.
///
/// [per-entry-expiration-example]:
/// ./struct.Cache.html#per-entry-expiration-policy
pub fn expire_after(self, expiry: impl Expiry<K, V> + Send + Sync + 'static) -> Self {
let mut builder = self;
builder.expiration_policy.set_expiry(Arc::new(expiry));
Expand Down
Loading