1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
// Copyright 2020-2022 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0
//! RLU Traits
//!
//! The most basic abstraction for implementing types of RLU consists of two traits [`Read`] and [`Write`].
//! Either provide a function to `get()` or `get_mut` of data respectively.
use crate::{RLUVar, ReadGuard, Result, WriteGuard};
/// [`Read<T>`] provides immutable read access to the synchronized data
/// via the current managing context.
pub trait Read<T>
where
T: Clone,
{
/// Returns an immutable [`ReadGuard`] on the value of [`RLUVar`]
///
/// This function effectively returns either the original value, if it
/// has not been modified, or an immutable reference to the underlying
/// write log, if the log has not been commited to memory yet. The [`ReadGuard`]
/// ensures that after dereferencing and reading the value, all outstanding
/// commits to the internal value will be conducted.
///
/// # Example
/// ```
/// use stronghold_rlu::*;
///
/// // create simple value, that should be managed by RLU
/// let value = 6usize;
///
/// // first we need to create a controller
/// let ctrl = RLU::new();
///
/// // via the controller we create a RLUVar reference
/// let rlu_var: RLUVar<usize> = ctrl.create(value);
///
/// // we clone the reference to it to use it inside a thread
/// let var_1 = rlu_var.clone();
///
/// // via the controller we can spawn a thread safe context
/// ctrl.execute(move |context| {
/// let inner = context.get(&var_1)?;
/// assert_eq!(*inner, 6);
/// Ok(())
/// });
/// ```
fn get<'a>(&'a self, var: &'a RLUVar<T>) -> Result<ReadGuard<'a, T>>;
}
/// [`Write<T>`] gives mutable access to synchronized value via the current managing
/// context.
pub trait Write<T>
where
T: Clone,
{
/// Returns an mutable [`WriteGuard`] on the value of [`RLUVar`]
///
/// This function returns a mutable copy if the original value. The [`WriteGuard`]
/// ensures that after dereferencing and writing to the value, the internal log
/// will be updated to the most recent change
///
/// # Example
/// ```
/// use stronghold_rlu::*;
///
/// // create simple value, that should be managed by RLU
/// let value = 6usize;
///
/// // first we need to create a controller
/// let ctrl = RLU::new();
///
/// // via the controller we create a RLUVar reference
/// let rlu_var: RLUVar<usize> = ctrl.create(value);
///
/// // we clone the reference to it to use it inside a thread
/// let var_1 = rlu_var.clone();
///
/// // via the controller we can spawn a thread safe context
/// ctrl.execute(move |mut context| {
/// let mut inner = context.get_mut(&var_1)?;
/// let data = &mut *inner;
/// *data += 10;
/// Ok(())
/// });
///
/// assert_eq!(rlu_var.get(), 16);
/// ```
fn get_mut<'a>(&'a self, var: &'a RLUVar<T>) -> Result<WriteGuard<'a, T>>;
}