[][src]Struct corundum::cell::LogCell

pub struct LogCell<T: PSafe + ?Sized, A: MemPool> { /* fields omitted */ }

A persistent mutable memory location with recoverability

This is one of the safe ways to provide interior mutability for pointer wrappers. It takes a log, if it was not already taken, before updating the value.

Using get() function, you can obtain a copy of data. To update data, you can use set() which writes a log to the given journal before mutation.

It does not implement Sync, so it is not possible to share LogCell between threads. To provide thread-safe interior mutability, use Mutex.

PCell is a compact version of LogCell tha can be find in the pool module.

Implementations

impl<T: PSafe, A: MemPool> LogCell<T, A>[src]

pub const fn new(value: T, _j: &Journal<A>) -> LogCell<T, A>[src]

Creates a new LogCell containing the given value.

Examples

use corundum::alloc::*;
use corundum::cell::LogCell;

Heap::transaction(|j| {
    let c = LogCell::new(5, j);
}).unwrap();

pub fn set(&self, val: T, journal: &Journal<A>)[src]

Sets the contained value.

Examples

use corundum::alloc::*;
use corundum::boxed::Pbox;
use corundum::cell::LogCell;

Heap::transaction(|j| {
    let c = Pbox::new(LogCell::new(5, j), j);
    c.set(10, j);
}).unwrap();

Errors

If LogCell is not in the persistent memory, it will raise an 'invalid address' error. To make sure that the LogCell is in the persistent memory, use dynamic allocation using Pbox as shown above.

pub fn swap(&self, other: &Self, journal: &Journal<A>)[src]

Swaps the values of two Cells.

Difference with std::mem::swap is that this function doesn't require &mut reference. It takes a log of both sides, if required, and then swaps the values.

Examples

use corundum::default::*;
use corundum::cell::LogCell;

let _pool = BuddyAlloc::open_no_root("foo.pool", O_CF).unwrap();
     
BuddyAlloc::transaction(|j| {
    let c1 = Pbox::new(LogCell::new(5i32, j), j);
    let c2 = Pbox::new(LogCell::new(10i32, j), j);
    c1.swap(&c2, j);
    assert_eq!(10, c1.get());
    assert_eq!(5, c2.get());
}).unwrap();

pub fn replace(&self, val: T, journal: &Journal<A>) -> T[src]

Replaces the contained value, and returns it.

Examples

use corundum::alloc::*;
use corundum::boxed::Pbox;
use corundum::cell::LogCell;

Heap::transaction(|j| {
    let cell = Pbox::new(LogCell::new(5, j), j);
    assert_eq!(cell.get(), 5);
    assert_eq!(cell.replace(10, j), 5);
    assert_eq!(cell.get(), 10);
}).unwrap();

pub fn into_inner(self) -> T[src]

Unwraps the value.

Examples

use corundum::alloc::*;
use corundum::cell::LogCell;

Heap::transaction(|j| {
    let c = LogCell::new(5, j);
    let five = c.into_inner();

    assert_eq!(five, 5);
}).unwrap();

pub fn add(&self, val: T, journal: &Journal<A>) where
    T: AddAssign
[src]

Increments the contained value by val.

pub fn sub(&self, val: T, journal: &Journal<A>) where
    T: SubAssign
[src]

Subtracts the contained value by val.

pub fn mul(&self, val: T, journal: &Journal<A>) where
    T: MulAssign
[src]

Multiplies the contained value with val.

pub fn div(&self, val: T, journal: &Journal<A>) where
    T: DivAssign
[src]

Divides the contained value with val.

pub fn rem(&self, val: T, journal: &Journal<A>) where
    T: RemAssign
[src]

Divides the contained value with val and keeps the reminding.

impl<T: PSafe, A: MemPool> LogCell<T, A>[src]

pub fn get(&self) -> T where
    T: Copy
[src]

Returns a copy of the contained value.

Examples

use corundum::alloc::*;
use corundum::cell::LogCell;

Heap::transaction(|j| {
    let c = LogCell::new(5, j);
    let five = c.get();
     
    assert_eq!(five, 5);
}).unwrap();

pub fn get_ref(&self) -> &T[src]

pub fn update<F>(&self, journal: &Journal<A>, f: F) -> T where
    F: FnOnce(T) -> T,
    T: Copy
[src]

Updates the contained value using a function and returns the new value.

Examples

#![feature(cell_update)]

use corundum::alloc::*;
use corundum::boxed::Pbox;
use corundum::cell::LogCell;

Heap::transaction(|j| {
    let c = Pbox::new(LogCell::new(5, j), j);
    let new = c.update(j, |x| x + 1);

    assert_eq!(new, 6);
    assert_eq!(c.get(), 6);
}).unwrap();

pub fn update_inplace<F>(&self, f: F) where
    F: FnOnce(&T), 
[src]

Updates the contained value using an updater function with an immutable reference to the inner value

Examples

use corundum::alloc::*;
use corundum::boxed::Pbox;
use corundum::cell::LogCell;

Heap::transaction(|j| {
    let c = Pbox::new(LogCell::new(LogCell::new(5, j), j), j);
    c.update_inplace(|x| x.set(6, j));

    assert_eq!(c.get_ref().get(), 6);
}).unwrap();

pub fn update_inplace_mut<F>(&self, journal: &Journal<A>, f: F) where
    F: FnOnce(&mut T), 
[src]

Updates the contained value using an updater function with a mutable reference to the inner value.

Examples

#![feature(cell_update)]

use corundum::alloc::*;
use corundum::boxed::Pbox;
use corundum::cell::LogCell;

Heap::transaction(|j| {
    let c = Pbox::new(LogCell::new(5, j), j);
    c.update_inplace_mut(j, |x| { *x = 6 });

    assert_eq!(c.get(), 6);
}).unwrap();

impl<T: PSafe + ?Sized, A: MemPool> LogCell<T, A>[src]

pub fn get_mut(&mut self, journal: &Journal<A>) -> &mut T[src]

Returns a mutable reference to the underlying data.

This call borrows LogCell mutably (at compile-time) which guarantees that we possess the only reference.

Examples

use corundum::alloc::*;
use corundum::boxed::Pbox;
use corundum::cell::LogCell;

Heap::transaction(|j| {
    let mut c = Pbox::new(LogCell::new(5, j), j);
    let mut n = c.get_mut(j);
    *n += 1;

    assert_eq!(c.get(), 6);
}).unwrap();

pub unsafe fn as_mut(&self) -> &mut T[src]

Returns a mutable reference to the underlying data without taking a log

Safety

This function violates borrow rules as it allows multiple mutable references.

Examples

use corundum::default::*;
use corundum::cell::LogCell;
 
type P = BuddyAlloc;
 
let root = P::open::<LogCell<i32,P>>("foo.pool", O_CF).unwrap();
 
unsafe {
    let mut data = root.as_mut();
    *data = 20;
}
 

impl<T: PSafe + Default, A: MemPool> LogCell<T, A>[src]

pub fn take(&self, journal: &Journal<A>) -> T[src]

Takes the value of the cell, leaving Default::default() in its place.

Examples

use corundum::alloc::*;
use corundum::boxed::Pbox;
use corundum::cell::LogCell;

Heap::transaction(|j| {
    let c = Pbox::new(LogCell::new(5, j), j);
    let five = c.take(j);

    assert_eq!(five, 5);
    assert_eq!(c.get(), 0);
}).unwrap();

Trait Implementations

impl<T: Debug + PSafe, A: MemPool> Debug for LogCell<T, A>[src]

impl<T: PSafe + Default, A: MemPool> Default for LogCell<T, A>[src]

impl<T: PSafe + Eq + Copy, A: MemPool> Eq for LogCell<T, A>[src]

impl<T: PSafe + Ord + Copy, A: MemPool> Ord for LogCell<T, A>[src]

impl<T: PSafe + Logger<A> + Copy, A: MemPool> PClone<A> for LogCell<T, A>[src]

impl<T: PSafe + ?Sized, A: MemPool> PSafe for LogCell<T, A>[src]

impl<T: PSafe + PartialEq + Copy, A: MemPool> PartialEq<LogCell<T, A>> for LogCell<T, A>[src]

impl<T: PSafe + PartialOrd + Copy, A: MemPool> PartialOrd<LogCell<T, A>> for LogCell<T, A>[src]

impl<T: PSafe + ?Sized, A: MemPool> RefUnwindSafe for LogCell<T, A>[src]

impl<T: PSafe + Send + ?Sized, A: MemPool> Send for LogCell<T, A>[src]

impl<T: ?Sized, A: MemPool> !Sync for LogCell<T, A>[src]

impl<T: PSafe + ?Sized, A: MemPool> TxInSafe for LogCell<T, A>[src]

impl<T: ?Sized, A: MemPool> !TxOutSafe for LogCell<T, A>[src]

impl<T: PSafe + ?Sized, A: MemPool> UnwindSafe for LogCell<T, A>[src]

Auto Trait Implementations

impl<T: ?Sized, A> LooseTxInUnsafe for LogCell<T, A> where
    A: LooseTxInUnsafe,
    T: LooseTxInUnsafe
[src]

impl<T: ?Sized, A> Unpin for LogCell<T, A> where
    A: Unpin,
    T: Unpin
[src]

impl<T: ?Sized, A> VSafe for LogCell<T, A> where
    A: VSafe,
    T: VSafe
[src]

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<V, T> VZip<V> for T where
    V: MultiLane<T>,