Crate coalesced_map

Crate coalesced_map 

Source
Expand description

A thread-safe, deduplicating map that ensures expensive computations are executed only once per key, even when multiple concurrent requests are made.

This map is designed for scenarios where multiple async tasks might request the same resource simultaneously. Instead of performing duplicate work, the CoalescedMap ensures that only the first request for a given key executes the initialization function, while subsequent concurrent requests wait for and receive the same result.

The implementation uses DashMap for thread-safe storage and tokio::sync::broadcast channels for coordinating between concurrent waiters.

§Example

use coalesced_map::{CoalescedMap, CoalescedGetError};
use std::{sync::Arc, time::Duration};

#[tokio::main]
async fn main() {
    // Create with default hasher (RandomState)
    let cache: CoalescedMap<String, Arc<String>> = CoalescedMap::new();

    // Or create with custom hasher
    use std::collections::hash_map::RandomState;
    let hasher = RandomState::new();
    let cache_with_hasher: CoalescedMap<String, Arc<String>, RandomState> =
        CoalescedMap::with_hasher(hasher);

    // Simulate multiple concurrent requests for the same expensive resource
    let key = "expensive_computation".to_string();

    let handle1 = {
        let cache = cache.clone();
        let key = key.clone();
        tokio::spawn(async move {
            cache.get_or_try_init(key, || async {
                // Simulate expensive work (e.g., network request, file I/O)
                tokio::time::sleep(Duration::from_millis(100)).await;
                println!("Performing expensive computation...");
                Ok(Arc::new("computed_result".to_string()))
            }).await
        })
    };

    let handle2 = {
        let cache = cache.clone();
        let key = key.clone();
        tokio::spawn(async move {
            cache.get_or_try_init(key, || async {
                // This function will NOT be executed due to coalescing
                println!("This should not print!");
                Ok(Arc::new("unused".to_string()))
            }).await
        })
    };

    let result1 = handle1.await.unwrap().unwrap();
    let result2 = handle2.await.unwrap().unwrap();

    // Both results are identical (same Arc instance)
    assert!(Arc::ptr_eq(&result1, &result2));
    assert_eq!(*result1, "computed_result");
}

Structs§

CoalescedMap
A thread-safe map that deduplicates concurrent async initialization requests.

Enums§

CoalescedGetError
Error type returned by CoalescedMap::get_or_try_init.
PendingOrFetched
Internal state for a coalesced entry.