Module txn_lock::map

source ·
Expand description

A futures-aware read-write lock on a HashMap which supports transactional versioning.

Example usage:

use std::collections::HashMap;
use std::sync::Arc;

use futures::executor::block_on;

use txn_lock::map::*;
use txn_lock::Error;

let one = "one";
let two = "two";

let map = TxnMapLock::<u64, String, f32>::new(1);

assert_eq!(block_on(map.insert(1, one.to_string(), 1.0)).expect("insert"), None);

let value = block_on(map.get(1, one)).expect("read").expect("value");
assert_eq!(value, 1.0);

assert_eq!(map.try_insert(1, one.to_string(), 2.0).unwrap_err(), Error::WouldBlock);

std::mem::drop(value);

let (state_at_txn_1, deltas) = block_on(map.read_and_commit(1));
assert_eq!(deltas.expect("deltas").len(), 1);
assert_eq!(state_at_txn_1.len(), 1);

let mut value = map.try_get_mut(2, one).expect("read").expect("value");
assert_eq!(value, 1.0);
*value = 2.0;

assert_eq!(map.try_remove(2, one).unwrap_err(), Error::WouldBlock);
std::mem::drop(value);

let value = block_on(map.remove(2, one)).expect("remove").expect("value");
assert_eq!(*value, 2.0);

assert_eq!(map.try_insert(2, two.to_string(), 1.0).expect("insert"), None);

assert!(map.try_remove(2, one).expect("remove").is_none());

assert_eq!(map.try_insert(2, two.to_string(), 2.0).expect("insert"), Some(1.0.into()));

map.rollback(&2);

let value = map.try_get(1, one).expect("read");
assert_eq!(*(value.expect("guard")), 1.0);

assert!(map.try_remove(3, two).expect("remove").is_none());

map.finalize(2);

assert_eq!(map.try_get(1, one).unwrap_err(), Error::Outdated);

let value = map.try_get(3, one).expect("read");
assert_eq!(*(value.expect("guard")), 1.0);

map.commit(3);

let extension = [
    ("one".to_string(), 1.0),
    ("two".to_string(), 2.0),
    ("three".to_string(), 3.0),
    ("four".to_string(), 4.0),
    ("five".to_string(), 5.0),
];

map.try_extend(4, extension).expect("extend");

for (key, mut value) in map.try_iter_mut(4).expect("iter") {
    *value *= 2.;
}

let expected = HashMap::<String, f32>::from_iter([
    ("two".to_string(), 4.0),
    ("three".to_string(), 6.0),
    ("one".to_string(), 2.0),
    ("four".to_string(), 8.0),
    ("five".to_string(), 10.0),
]);

let actual = map.try_iter(4).expect("iter").collect::<Vec<_>>();
assert_eq!(actual.len(), expected.len());

for (k, v) in actual {
    assert_eq!(expected.get(&*k), Some(&*v));
}

let actual = map.try_clear(4).expect("clear");
assert_eq!(actual, expected.into_iter().map(|(k, v)| (k.into(), v.into())).collect());

Structs§

Enums§

Type Aliases§