Struct SyncSieveCache

Source
pub struct SyncSieveCache<K, V>
where K: Eq + Hash + Clone + Send + Sync, V: Send + Sync,
{ /* private fields */ }
Expand description

A thread-safe wrapper around SieveCache.

This provides a thread-safe implementation of the SIEVE cache algorithm by wrapping the standard SieveCache in an Arc<Mutex<>>. It offers the same functionality as the underlying cache but with thread safety guarantees.

§Thread Safety

All operations acquire a lock on the entire cache, which provides strong consistency but may become a bottleneck under high contention. For workloads with high concurrency, consider using ShardedSieveCache instead, which partitions the cache into multiple independently-locked segments.

§Examples

let cache = SyncSieveCache::new(100).unwrap();

// Multiple threads can safely access the cache
cache.insert("key1".to_string(), "value1".to_string());
assert_eq!(cache.get(&"key1".to_string()), Some("value1".to_string()));

Implementations§

Source§

impl<K, V> SyncSieveCache<K, V>
where K: Eq + Hash + Clone + Send + Sync, V: Send + Sync,

Source

pub fn new(capacity: usize) -> Result<Self, &'static str>

Creates a new thread-safe cache with the given capacity.

§Errors

Returns an error if the capacity is zero.

§Examples
let cache = SyncSieveCache::<String, String>::new(100).unwrap();
Source

pub fn capacity(&self) -> usize

Returns the capacity of the cache.

§Examples
let cache = SyncSieveCache::<String, u32>::new(100).unwrap();
assert_eq!(cache.capacity(), 100);
Source

pub fn len(&self) -> usize

Returns the number of cached values.

§Examples
let cache = SyncSieveCache::new(100).unwrap();
cache.insert("key".to_string(), "value".to_string());
assert_eq!(cache.len(), 1);
Source

pub fn is_empty(&self) -> bool

Returns true when no values are currently cached.

§Examples
let cache = SyncSieveCache::<String, String>::new(100).unwrap();
assert!(cache.is_empty());

cache.insert("key".to_string(), "value".to_string());
assert!(!cache.is_empty());
Source

pub fn contains_key<Q>(&self, key: &Q) -> bool
where Q: Hash + Eq + ?Sized, K: Borrow<Q>,

Returns true if there is a value in the cache mapped to by key.

§Examples
let cache = SyncSieveCache::new(100).unwrap();
cache.insert("key".to_string(), "value".to_string());

assert!(cache.contains_key(&"key".to_string()));
assert!(!cache.contains_key(&"missing".to_string()));
Source

pub fn get<Q>(&self, key: &Q) -> Option<V>
where Q: Hash + Eq + ?Sized, K: Borrow<Q>, V: Clone,

Gets a clone of the value in the cache mapped to by key.

If no value exists for key, this returns None.

§Note

Unlike the unwrapped SieveCache, this returns a clone of the value rather than a reference, since the mutex guard would be dropped after this method returns. This means that V must implement Clone.

§Examples
let cache = SyncSieveCache::new(100).unwrap();
cache.insert("key".to_string(), "value".to_string());

assert_eq!(cache.get(&"key".to_string()), Some("value".to_string()));
assert_eq!(cache.get(&"missing".to_string()), None);
Source

pub fn insert(&self, key: K, value: V) -> bool

Maps key to value in the cache, possibly evicting old entries.

This method returns true when this is a new entry, and false if an existing entry was updated.

§Examples
let cache = SyncSieveCache::new(100).unwrap();

// Insert a new key
assert!(cache.insert("key1".to_string(), "value1".to_string()));

// Update an existing key
assert!(!cache.insert("key1".to_string(), "updated_value".to_string()));
Source

pub fn remove<Q>(&self, key: &Q) -> Option<V>
where K: Borrow<Q>, Q: Eq + Hash + ?Sized,

Removes the cache entry mapped to by key.

This method returns the value removed from the cache. If key did not map to any value, then this returns None.

§Examples
let cache = SyncSieveCache::new(100).unwrap();
cache.insert("key".to_string(), "value".to_string());

// Remove an existing key
assert_eq!(cache.remove(&"key".to_string()), Some("value".to_string()));

// Attempt to remove a missing key
assert_eq!(cache.remove(&"key".to_string()), None);
Source

pub fn evict(&self) -> Option<V>

Removes and returns a value from the cache that was not recently accessed.

This implements the SIEVE eviction algorithm to select an entry for removal. If no suitable value exists, this returns None.

§Examples
let cache = SyncSieveCache::new(2).unwrap();
cache.insert("key1".to_string(), "value1".to_string());
cache.insert("key2".to_string(), "value2".to_string());

// Accessing key1 marks it as recently used
assert_eq!(cache.get(&"key1".to_string()), Some("value1".to_string()));

// Insert a new key, which should evict key2
cache.insert("key3".to_string(), "value3".to_string());

// key2 should have been evicted
assert_eq!(cache.get(&"key2".to_string()), None);
Source

pub fn with_lock<F, T>(&self, f: F) -> T
where F: FnOnce(&mut SieveCache<K, V>) -> T,

Gets exclusive access to the underlying cache to perform multiple operations atomically.

This is useful when you need to perform a series of operations that depend on each other and you want to ensure that no other thread can access the cache between operations.

§Examples
let cache = SyncSieveCache::new(100).unwrap();

cache.with_lock(|inner_cache| {
    // Perform multiple operations atomically
    inner_cache.insert("key1".to_string(), "value1".to_string());
    inner_cache.insert("key2".to_string(), "value2".to_string());

    // We can check internal state mid-transaction
    assert_eq!(inner_cache.len(), 2);
});

Trait Implementations§

Source§

impl<K, V> Clone for SyncSieveCache<K, V>
where K: Eq + Hash + Clone + Send + Sync + Clone, V: Send + Sync + Clone,

Source§

fn clone(&self) -> SyncSieveCache<K, V>

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<K, V> Freeze for SyncSieveCache<K, V>

§

impl<K, V> RefUnwindSafe for SyncSieveCache<K, V>

§

impl<K, V> Send for SyncSieveCache<K, V>

§

impl<K, V> Sync for SyncSieveCache<K, V>

§

impl<K, V> Unpin for SyncSieveCache<K, V>

§

impl<K, V> UnwindSafe for SyncSieveCache<K, V>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.