DMSCCache

Trait DMSCCache 

Source
pub trait DMSCCache: Send + Sync {
Show 13 methods // Required methods fn get<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 str, ) -> Pin<Box<dyn Future<Output = DMSCResult<Option<String>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn set<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 str, value: &'life2 str, ttl_seconds: Option<u64>, ) -> Pin<Box<dyn Future<Output = DMSCResult<()>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn delete<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 str, ) -> Pin<Box<dyn Future<Output = DMSCResult<bool>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn clear<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = DMSCResult<()>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn stats<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = DMSCCacheStats> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn cleanup_expired<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = DMSCResult<usize>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn exists<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 str, ) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn keys<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = DMSCResult<Vec<String>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; // Provided methods fn get_multi<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, keys: &'life1 [&'life2 str], ) -> Pin<Box<dyn Future<Output = DMSCResult<Vec<Option<String>>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait { ... } fn set_multi<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, items: &'life1 [(&'life2 str, &'life3 str)], ttl_seconds: Option<u64>, ) -> Pin<Box<dyn Future<Output = DMSCResult<()>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait { ... } fn delete_multi<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, keys: &'life1 [&'life2 str], ) -> Pin<Box<dyn Future<Output = DMSCResult<usize>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait { ... } fn exists_multi<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, keys: &'life1 [&'life2 str], ) -> Pin<Box<dyn Future<Output = DMSCResult<Vec<bool>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait { ... } fn delete_by_pattern<'life0, 'life1, 'async_trait>( &'life0 self, pattern: &'life1 str, ) -> Pin<Box<dyn Future<Output = DMSCResult<usize>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait { ... }
}
Expand description

Cache trait for DMSC cache implementations.

This trait defines the core interface for all cache backends in DMSC. Implementations must provide thread-safe, asynchronous cache operations with support for TTL-based expiration and comprehensive statistics tracking.

§Implementations

DMSC provides several built-in implementations:

§Thread Safety

All implementations must be Send + Sync to ensure safe concurrent access from multiple async tasks or threads. The trait uses interior mutability patterns internally.

§Async Operations

All operations are asynchronous and use async/await syntax. This enables non-blocking cache operations suitable for high-throughput applications.

§Key Operations

  1. Basic Operations: get, set, delete, exists
  2. Batch Operations: get_multi, set_multi, delete_multi
  3. Maintenance: clear, cleanup_expired, stats
  4. Pattern Matching: keys, delete_by_pattern

§Example

use dmsc::cache::DMSCCache;
use dmsc::cache::backends::DMSCMemoryCache;

async fn example() -> dmsc::core::DMSCResult<()> {
    let cache = DMSCMemoryCache::new();

    // Store a value with 1-hour TTL
    cache.set("user:123", "Alice", Some(3600)).await?;

    // Retrieve the value
    let value = cache.get("user:123").await?;
    assert_eq!(value, Some("Alice".to_string()));

    // Check if key exists
    assert!(cache.exists("user:123").await);

    // Get cache statistics
    let stats = cache.stats().await;
    println!("Hits: {}, Misses: {}", stats.hits, stats.misses);

    // Delete the value
    cache.delete("user:123").await?;

    Ok(())
}

Required Methods§

Source

fn get<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 str, ) -> Pin<Box<dyn Future<Output = DMSCResult<Option<String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Retrieves a value from the cache by key.

This method looks up the specified key in the cache. If the key exists and the value is not expired, it returns the value as a string. Expired entries are automatically removed during the lookup.

§Expiration Handling

If the cached value has an associated TTL (Time-To-Live) and the current time has passed the expiration timestamp, the entry is treated as missing and removed from the cache.

§Statistics

This operation updates cache statistics:

  • Increments hits counter on successful retrieval
  • Increments misses counter when key is not found or expired
§Parameters
  • key - The cache key to look up (typically a string identifier)
§Returns

A DMSCResult<Option<String>> containing:

  • Ok(Some(value)) if the key exists and is not expired
  • Ok(None) if the key doesn’t exist or has expired
  • Err(DMSCError) if an error occurred during the operation
§Examples
use dmsc::cache::backends::DMSCMemoryCache;

async fn example() -> dmsc::core::DMSCResult<()> {
    let cache = DMSCMemoryCache::new();

    // Key doesn't exist
    let result = cache.get("missing").await?;
    assert_eq!(result, None);

    // Store a value
    cache.set("key", "value", None).await?;

    // Key exists
    let result = cache.get("key").await?;
    assert_eq!(result, Some("value".to_string()));

    Ok(())
}
Source

fn set<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 str, value: &'life2 str, ttl_seconds: Option<u64>, ) -> Pin<Box<dyn Future<Output = DMSCResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Stores a value in the cache with an optional TTL.

This method inserts or updates a cache entry with the specified key and value. The entry will automatically expire after the specified TTL duration if provided.

§Overwrite Behavior

If a value already exists for the given key, it will be overwritten with the new value. The expiration time will be reset based on the new TTL.

§TTL Handling
  • Some(seconds): The entry will expire after the specified number of seconds
  • None: The entry will never expire automatically
§Storage Format

The value is stored as a string. For complex types, serialize them to a string format (e.g., JSON) before caching.

§Parameters
  • key - The cache key to store the value under
  • value - The string value to cache
  • ttl_seconds - Optional time-to-live in seconds (None for persistent storage)
§Returns

A DMSCResult<()> indicating success or failure

§Examples
use dmsc::cache::backends::DMSCMemoryCache;

async fn example() -> dmsc::core::DMSCResult<()> {
    let cache = DMSCMemoryCache::new();

    // Store a value without expiration
    cache.set("persistent", "data", None).await?;

    // Store a value with 1-hour expiration
    cache.set("temp", "data", Some(3600)).await?;

    Ok(())
}
Source

fn delete<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 str, ) -> Pin<Box<dyn Future<Output = DMSCResult<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Removes a value from the cache by key.

This method deletes the specified key from the cache. If the key doesn’t exist, the operation still succeeds but returns false.

§Behavior
  • The entry is completely removed from the cache
  • If the key doesn’t exist, no error is raised
  • No statistics are updated for delete operations
§Parameters
  • key - The cache key to delete
§Returns

A DMSCResult<bool> containing:

  • Ok(true) if the key was found and deleted
  • Ok(false) if the key didn’t exist
  • Err(DMSCError) if an error occurred during the operation
§Examples
use dmsc::cache::backends::DMSCMemoryCache;

async fn example() -> dmsc::core::DMSCResult<()> {
    let cache = DMSCMemoryCache::new();

    // Delete non-existent key
    let deleted = cache.delete("missing").await?;
    assert!(!deleted);

    // Store and delete
    cache.set("key", "value", None).await?;
    let deleted = cache.delete("key").await?;
    assert!(deleted);

    Ok(())
}
Source

fn clear<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = DMSCResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Removes all entries from the cache.

This method clears all cached values regardless of their expiration status. The operation is typically O(n) where n is the number of cached entries.

§Behavior
  • All entries are immediately removed
  • Statistics are reset to their default values
  • This operation cannot be undone
§Returns

A DMSCResult<()> indicating success or failure

§Examples
use dmsc::cache::backends::DMSCMemoryCache;

async fn example() -> dmsc::core::DMSCResult<()> {
    let cache = DMSCMemoryCache::new();

    // Add some entries
    cache.set("a", "1", None).await?;
    cache.set("b", "2", None).await?;
    cache.set("c", "3", None).await?;

    // Clear all entries
    cache.clear().await?;

    // Verify cache is empty
    assert!(!cache.exists("a").await);

    Ok(())
}
Source

fn stats<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = DMSCCacheStats> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Returns current cache statistics.

This method retrieves performance metrics and usage statistics from the cache. The statistics provide insights into cache effectiveness and resource usage.

§Statistics Collected
  • hits: Number of successful cache lookups
  • misses: Number of cache lookups that returned None
  • entries: Current number of entries in the cache
  • memory_usage_bytes: Estimated memory consumption
  • avg_hit_rate: Ratio of hits to total lookups
  • eviction_count: Number of entries evicted due to size limits
§Thread Safety

The returned statistics are a snapshot taken at call time. Other threads may modify the cache immediately after, making the statistics slightly stale.

§Returns

A DMSCCacheStats struct containing all cache metrics

§Examples
use dmsc::cache::backends::DMSCMemoryCache;

async fn example() {
    let cache = DMSCMemoryCache::new();

    // Perform some cache operations
    let _ = cache.get("missing").await;
    cache.set("key", "value", None).await.unwrap();
    let _ = cache.get("key").await;

    // Get statistics
    let stats = cache.stats().await;
    println!("Hits: {}, Misses: {}", stats.hits, stats.misses);
    println!("Hit rate: {:.1}%", stats.avg_hit_rate * 100.0);
}
Source

fn cleanup_expired<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = DMSCResult<usize>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Removes all expired entries from the cache.

This method scans the cache and removes entries that have exceeded their TTL (Time-To-Live). This is useful for reclaiming memory used by expired entries.

§Performance

The performance characteristics depend on the implementation:

  • In-memory caches: Typically O(n) where n is total entries
  • Distributed caches: May involve network round-trips for each entry
§Automatic Cleanup

Many implementations automatically remove expired entries during normal operations (e.g., during get() calls). This explicit cleanup is useful for periodic maintenance or when entries have no recent access.

§Returns

A DMSCResult<usize> containing the number of expired entries removed

§Examples
use dmsc::cache::backends::DMSCMemoryCache;

async fn example() -> dmsc::core::DMSCResult<()> {
    let cache = DMSCMemoryCache::new();

    // Add entries with short TTL
    cache.set("short-lived", "data", Some(1)).await?;

    // Wait for expiration
    tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;

    // Cleanup expired entries
    let cleaned = cache.cleanup_expired().await?;
    println!("Cleaned {} expired entries", cleaned);

    Ok(())
}
Source

fn exists<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 str, ) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Checks if a key exists in the cache and is not expired.

This method provides a lightweight way to check key existence without retrieving the value. Expired entries are automatically removed.

§Expiration Check

If the key exists but the value is expired, the entry is removed and the method returns false.

§Performance

This operation is typically faster than get() because it doesn’t need to deserialize or return the cached value.

§Parameters
  • key - The cache key to check
§Returns

A boolean indicating whether the key exists and is not expired

§Examples
use dmsc::cache::backends::DMSCMemoryCache;

async fn example() -> dmsc::core::DMSCResult<()> {
    let cache = DMSCMemoryCache::new();

    assert!(!cache.exists("missing").await);

    cache.set("key", "value", None).await?;
    assert!(cache.exists("key").await);

    Ok(())
}
Source

fn keys<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = DMSCResult<Vec<String>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Retrieves all cache keys.

This method returns a list of all keys currently stored in the cache, including expired ones. Use cleanup_expired() to remove expired entries first.

§Order

The order of returned keys is implementation-defined. Do not rely on any particular ordering.

§Performance

This operation may be expensive for large caches as it typically requires iterating through all entries.

§Returns

A DMSCResult<Vec<String>> containing all cache keys

§Examples
use dmsc::cache::backends::DMSCMemoryCache;

async fn example() -> dmsc::core::DMSCResult<()> {
    let cache = DMSCMemoryCache::new();

    cache.set("a", "1", None).await?;
    cache.set("b", "2", None).await?;
    cache.set("c", "3", None).await?;

    let keys = cache.keys().await?;
    assert_eq!(keys.len(), 3);

    Ok(())
}

Provided Methods§

Source

fn get_multi<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, keys: &'life1 [&'life2 str], ) -> Pin<Box<dyn Future<Output = DMSCResult<Vec<Option<String>>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Retrieves multiple values from the cache in a single operation.

This method is a convenience wrapper that fetches multiple keys efficiently. The results are returned in the same order as the input keys.

§Partial Results

If some keys exist and others don’t, the result vector will contain Some(value) for existing keys and None for missing keys.

§Parameters
  • keys - A slice of cache keys to retrieve
§Returns

A DMSCResult<Vec<Option<String>>> containing values in key order

§Examples
use dmsc::cache::backends::DMSCMemoryCache;

async fn example() -> dmsc::core::DMSCResult<()> {
    let cache = DMSCMemoryCache::new();

    cache.set("a", "1", None).await?;
    cache.set("b", "2", None).await?;

    let results = cache.get_multi(&["a", "b", "c"]).await?;
    assert_eq!(results, vec![
        Some("1".to_string()),
        Some("2".to_string()),
        None
    ]);

    Ok(())
}
Source

fn set_multi<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, items: &'life1 [(&'life2 str, &'life3 str)], ttl_seconds: Option<u64>, ) -> Pin<Box<dyn Future<Output = DMSCResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Stores multiple key-value pairs in the cache.

This method is a convenience wrapper for setting multiple entries efficiently. All entries use the same TTL if provided.

§Parameters
  • items - A slice of (key, value) tuples to store
  • ttl_seconds - Optional TTL for all entries
§Returns

A DMSCResult<()> indicating success or failure

§Examples
use dmsc::cache::backends::DMSCMemoryCache;

async fn example() -> dmsc::core::DMSCResult<()> {
    let cache = DMSCMemoryCache::new();

    let items = vec![
        ("a", "1"),
        ("b", "2"),
        ("c", "3"),
    ];

    cache.set_multi(&items, Some(3600)).await?;

    Ok(())
}
Source

fn delete_multi<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, keys: &'life1 [&'life2 str], ) -> Pin<Box<dyn Future<Output = DMSCResult<usize>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Removes multiple keys from the cache.

This method is a convenience wrapper for deleting multiple entries efficiently.

§Atomicity

This operation is not atomic - each delete is performed independently. Partial failures may result in some keys being deleted while others remain.

§Parameters
  • keys - A slice of cache keys to delete
§Returns

A DMSCResult<usize> containing the number of keys deleted

§Examples
use dmsc::cache::backends::DMSCMemoryCache;

async fn example() -> dmsc::core::DMSCResult<()> {
    let cache = DMSCMemoryCache::new();

    cache.set("a", "1", None).await?;
    cache.set("b", "2", None).await?;
    cache.set("c", "3", None).await?;

    let count = cache.delete_multi(&["a", "b"]).await?;
    assert_eq!(count, 2);

    Ok(())
}
Source

fn exists_multi<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, keys: &'life1 [&'life2 str], ) -> Pin<Box<dyn Future<Output = DMSCResult<Vec<bool>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Checks if multiple keys exist in the cache.

This method is a convenience wrapper for checking multiple keys efficiently.

§Parameters
  • keys - A slice of cache keys to check
§Returns

A DMSCResult<Vec<bool>> indicating existence of each key

§Examples
use dmsc::cache::backends::DMSCMemoryCache;

async fn example() -> dmsc::core::DMSCResult<()> {
    let cache = DMSCMemoryCache::new();

    cache.set("a", "1", None).await?;

    let results = cache.exists_multi(&["a", "b"]).await?;
    assert_eq!(results, vec![true, false]);

    Ok(())
}
Source

fn delete_by_pattern<'life0, 'life1, 'async_trait>( &'life0 self, pattern: &'life1 str, ) -> Pin<Box<dyn Future<Output = DMSCResult<usize>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Removes all keys matching a regex pattern.

This method is useful for bulk invalidation of related cache entries. For example, invalidating all user-related cache entries when a user updates their profile.

§Pattern Format

The pattern is a regular expression. Common patterns include:

  • user:* - Matches all keys starting with “user:”
  • *:session - Matches all keys ending with “:session”
  • .* - Matches all keys
§Performance

This operation requires fetching all keys and filtering by regex. For large caches, consider using key prefixes for better performance.

§Parameters
  • pattern - A regular expression pattern to match keys against
§Returns

A DMSCResult<usize> containing the number of keys deleted

§Examples
use dmsc::cache::backends::DMSCMemoryCache;

async fn example() -> dmsc::core::DMSCResult<()> {
    let cache = DMSCMemoryCache::new();

    cache.set("user:123:profile", "data", None).await?;
    cache.set("user:123:settings", "data", None).await?;
    cache.set("product:456", "data", None).await?;

    let count = cache.delete_by_pattern("user:.*").await?;
    assert_eq!(count, 2);

    Ok(())
}

Implementors§