stable-map

Crates.iostable-map
lib.rsstable-map
version
sourcesrc
created_at2024-11-29 20:18:08.203645
updated_at2024-11-29 20:18:08.203645
descriptionA hash map with temporarily stable indices
homepage
repositoryhttps://github.com/mahkoh/stable-map
max_upload_size
id1466042
Cargo.toml error:TOML parse error at line 17, column 1 | 17 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include`
size0
(mahkoh)

documentation

README

stable-map

crates.io docs.rs

This crate provides a hash map where each key is associated with an index. This index remains stable unless the user explicitly compacts the map. This allows for concurrent iteration over and modification of the map.

Example

Consider a service that allows clients to register callbacks:

use {
    parking_lot::Mutex,
    stable_map::StableMap,
    std::sync::{
        atomic::{AtomicUsize, Ordering::Relaxed},
        Arc,
    },
};

pub struct Service {
    next_callback_id: AtomicUsize,
    callbacks: Mutex<StableMap<CallbackId, Arc<dyn Callback>>>,
}

pub trait Callback {
    fn run(&self);
}

#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
pub struct CallbackId(usize);

impl Service {
    pub fn register_callback(&self, callback: Arc<dyn Callback>) -> CallbackId {
        let id = CallbackId(self.next_callback_id.fetch_add(1, Relaxed));
        self.callbacks.lock().insert(id, callback);
        id
    }

    pub fn unregister_callback(&self, id: CallbackId) {
        self.callbacks.lock().remove(&id);
    }

    fn execute_callbacks(&self) {
        let mut callbacks = self.callbacks.lock();
        for i in 0..callbacks.index_len() {
            if let Some(callback) = callbacks.get_by_index(i).cloned() {
                // Drop the mutex so that the callback can itself call
                // register_callback or unregister_callback.
                drop(callbacks);
                // Run the callback.
                callback.run();
                // Re-acquire the mutex.
                callbacks = self.callbacks.lock();
            }
        }
        // Compact the map so that index_len does not grow much larger than the actual
        // size of the map.
        callbacks.compact();
    }
}

License

This project is licensed under either of

  • Apache License, Version 2.0
  • MIT License

at your option.

Commit count: 1

cargo fmt