[−][src]Struct crndm::boxed::Pbox
A pointer type for persistent heap allocation.
If Pbox
is mutable, the underlying data can mutate after taking a log.
It is necessary because compound types containing a Pbox
may provide
interior mutability (via LogCell
or LogRefCell
) though which the
Pbox
become mutably available. The log taken for interior mutability works
only on the pointer value and does not include the referent object. Therefore,
Pbox
provides a logging mechanism to provide mutable dereferencing.
Examples
Create a boxed object in the persistent memory
use crndm::default::*; type P = BuddyAlloc; let _ = P::open_no_root("foo.pool", O_CF).unwrap(); transaction(|j| { let five = Pbox::new(5, j); assert_eq!(*five, 5); }).unwrap();
Examples
Move a value from the stack to the persistent memory by creating a Pbox
:
transaction(|j| { let val: u8 = 5; let boxed: Pbox<u8> = Pbox::new(val, j); }).unwrap();
Move a value from a Pbox
back to the stack by dereferencing:
transaction(|j| { let boxed: Pbox<u8> = Pbox::new(5, j); let val: u8 = *boxed; }).unwrap();
Creating a recursive data structure:
#[derive(Debug)] enum List<T: PSafe> { Cons(T, Pbox<List<T>>), Nil, } transaction(|j| { let list: List<i32> = List::Cons(1, Pbox::new(List::Cons(2, Pbox::new(List::Nil, j)), j)); println!("{:?}", list); }).unwrap();
This will print Cons(1, Cons(2, Nil))
.
Recursive structures must be boxed, because if the definition of Cons
looked like this:
Cons(T, List<T>),
It wouldn't work. This is because the size of a List
depends on how many
elements are in the list, and so we don't know how much memory to allocate
for a Cons
. By introducing a Pbox<T>
, which has a defined size, we know
how big Cons
needs to be.
Implementations
impl<T: PSafe, A: MemPool> Pbox<T, A>
[src]
pub fn new(x: T, journal: &Journal<A>) -> Pbox<T, A>
[src]
Allocates memory on the persistent heap and then places x
into it.
This doesn't actually allocate if T
is zero-sized.
Examples
Heap::transaction(|j| { let five = Pbox::new(5, j); }).unwrap();
pub fn off(&self) -> u64
[src]
pub fn new_uninit(journal: &Journal<A>) -> Pbox<MaybeUninit<T>, A>
[src]
Constructs a new Pbox with uninitialized contents.
Examples
P::transaction(|j| { let mut five = Pbox::<u32>::new_uninit(j); let five = unsafe { // Deferred initialization: five.as_mut_ptr().write(5); five.assume_init() }; assert_eq!(*five, 5) }).unwrap()
pub fn new_zeroed(journal: &Journal<A>) -> Pbox<MaybeUninit<T>, A>
[src]
Constructs a new Pbox
with uninitialized contents, with the memory
being filled with 0
bytes.
See MaybeUninit::zeroed
for examples of correct and incorrect usage
of this method.
Examples
P::transaction(|j| { let zero = Pbox::<u32>::new_zeroed(j); let zero = unsafe { zero.assume_init() }; assert_eq!(*zero, 0) }).unwrap()
pub fn pin(x: T, journal: &Journal<A>) -> Pin<Pbox<T, A>>
[src]
Constructs a new Pin<Pbox<T, A>>
. If T
does not implement Unpin
, then
x
will be pinned in memory and unable to be moved.
impl<T: PSafe, A: MemPool> Pbox<MaybeUninit<T>, A>
[src]
pub unsafe fn assume_init(self) -> Pbox<T, A>
[src]
Converts to Pbox<T, A>
.
Safety
As with MaybeUninit::assume_init
,
it is up to the caller to guarantee that the value
really is in an initialized state.
Calling this when the content is not yet fully initialized
causes immediate undefined behavior.
impl<T: PSafe, A: MemPool> Pbox<T, A>
[src]
pub fn initialize(boxed: &Option<Pbox<T, A>>, value: T) -> Result<()>
[src]
Initializes boxed data with value
inplace if it is Null
This function should not be called from a transaction as it updates data without taking high-level logs. If transaction is unsuccessful, there is no way to recover data. However, it is safe to use it outside a transaction because it uses low-level logs to provide safety for a single update without drop. A dynamic check at the beginning makes sure of that.
Examples
use crndm::default::*; type P = BuddyAlloc; let root = P::open::<Option<Pbox<i32>>>("foo.pool", O_CF).unwrap(); Pbox::initialize(&*root, 25); let value = **root.as_ref().unwrap(); assert_eq!(value, 25);
impl<T: PSafe + ?Sized, A: MemPool> Pbox<T, A>
[src]
pub unsafe fn from_raw(raw: *mut T) -> Self
[src]
Constructs a box from a raw pointer.
After calling this function, the raw pointer is owned by the
resulting Pbox
. Specifically, the Pbox
destructor will call
the destructor of T
and free the allocated memory. For this
to be safe, the memory must have been allocated in accordance
with the memory layout used by Pbox
.
Safety
This function is unsafe because improper use may lead to memory problems. For example, a double-free may occur if the function is called twice on the same raw pointer.
pub fn into_raw(b: Pbox<T, A>) -> *mut T
[src]
Consumes the Pbox
, returning a wrapped raw pointer.
The pointer will be properly aligned and non-null.
After calling this function, the caller is responsible for the
memory previously managed by the Pbox
. In particular, the
caller should properly destroy T
and release the memory, taking
into account the [memory layout] used by Pbox
. The easiest way to
do this is to convert the raw pointer back into a Pbox
with the
Pbox::from_raw
function, allowing the Pbox
destructor to perform
the cleanup.
Note: this is an associated function, which means that you have
to call it as Pbox::into_raw(b)
instead of b.into_raw()
. This
is so that there is no conflict with a method on the inner type.
pub fn into_raw_non_null(b: Pbox<T, A>) -> NonNull<T>
[src]
Consumes the Pbox
, returning the wrapped pointer as NonNull<T>
.
After calling this function, the caller is responsible for the
memory previously managed by the Pbox
. In particular, the
caller should properly destroy T
and release the memory. The
easiest way to do so is to convert the NonNull<T>
pointer
into a raw pointer and back into a Pbox
with the Pbox::from_raw
function.
Note: this is an associated function, which means that you have
to call it as Pbox::into_raw_non_null(b)
instead of b.into_raw_non_null()
. This
is so that there is no conflict with a method on the inner type.
pub unsafe fn leak<'a>(b: Pbox<T, A>) -> &'a mut T where
T: 'a,
[src]
T: 'a,
Consumes and leaks the Pbox
, returning a mutable reference,
&'a mut T
. Note that the type T
must outlive the chosen lifetime
'a
. If the type has only static references, or none at all, then this
may be chosen to be 'static
.
This function is mainly useful for data that lives for the remainder of
the program's life. Dropping the returned reference will cause a memory
leak. If this is not acceptable, the reference should first be wrapped
with the Pbox::from_raw
function producing a Pbox
. This Pbox
can
then be dropped which will properly destroy T
and release the
allocated memory.
Note: this is an associated function, which means that you have
to call it as Pbox::leak(b)
instead of b.leak()
. This
is so that there is no conflict with a method on the inner type.
Safety
This function is considered unsafe in persistent memory programming because memory leak is permanent and undesirable.
Examples
Simple usage:
Heap::transaction(|j| unsafe { let x = Pbox::new(41, j); let static_ref: &'static mut usize = Pbox::leak(x); *static_ref += 1; assert_eq!(*static_ref, 42); }).unwrap();
pub fn into_pin(boxed: Pbox<T, A>) -> Pin<Pbox<T, A>> where
T: Sized,
[src]
T: Sized,
Converts a Pbox<T, A>
into a Pin<Pbox<T, A>>
This conversion does not allocate on the heap and happens in place.
This is also available via From
.
Trait Implementations
impl<T: PSafe + ?Sized, A: MemPool> AsRef<T> for Pbox<T, A>
[src]
impl<T: PSafe + Debug + ?Sized, A: MemPool> Debug for Pbox<T, A>
[src]
impl<T: PSafe + ?Sized, A: MemPool> Deref for Pbox<T, A>
[src]
impl<T: PSafe + ?Sized, A: MemPool> DerefMut for Pbox<T, A>
[src]
impl<T: PSafe + Display + ?Sized, A: MemPool> Display for Pbox<T, A>
[src]
impl<T: PSafe + ?Sized, A: MemPool> Drop for Pbox<T, A>
[src]
impl<T: PSafe + Eq + ?Sized, A: MemPool> Eq for Pbox<T, A>
[src]
impl<T: PSafe, A: MemPool> From<Pbox<T, A>> for Pin<Pbox<T, A>>
[src]
pub fn from(boxed: Pbox<T, A>) -> Self
[src]
Converts a Pbox<T, A>
into a Pin<Pbox<T, A>>
This conversion does not allocate on the heap and happens in place.
impl<T: PSafe + Hash + ?Sized, A: MemPool> Hash for Pbox<T, A>
[src]
pub fn hash<H: Hasher>(&self, state: &mut H)
[src]
pub fn hash_slice<H>(data: &[Self], state: &mut H) where
H: Hasher,
1.3.0[src]
H: Hasher,
impl<T: PSafe + Hasher + ?Sized, A: MemPool> Hasher for Pbox<T, A>
[src]
pub fn finish(&self) -> u64
[src]
pub fn write(&mut self, bytes: &[u8])
[src]
pub fn write_u8(&mut self, i: u8)
[src]
pub fn write_u16(&mut self, i: u16)
[src]
pub fn write_u32(&mut self, i: u32)
[src]
pub fn write_u64(&mut self, i: u64)
[src]
pub fn write_u128(&mut self, i: u128)
[src]
pub fn write_usize(&mut self, i: usize)
[src]
pub fn write_i8(&mut self, i: i8)
[src]
pub fn write_i16(&mut self, i: i16)
[src]
pub fn write_i32(&mut self, i: i32)
[src]
pub fn write_i64(&mut self, i: i64)
[src]
pub fn write_i128(&mut self, i: i128)
[src]
pub fn write_isize(&mut self, i: isize)
[src]
impl<T: PSafe + Ord + ?Sized, A: MemPool> Ord for Pbox<T, A>
[src]
pub fn cmp(&self, other: &Pbox<T, A>) -> Ordering
[src]
#[must_use]pub fn max(self, other: Self) -> Self
1.21.0[src]
#[must_use]pub fn min(self, other: Self) -> Self
1.21.0[src]
#[must_use]pub fn clamp(self, min: Self, max: Self) -> Self
1.50.0[src]
impl<T: PSafe + PClone<A> + ?Sized, A: MemPool> PClone<A> for Pbox<T, A>
[src]
pub default fn pclone(&self, journal: &Journal<A>) -> Pbox<T, A>
[src]
Returns a new box with a pclone()
of this box's contents.
Examples
use crndm::clone::PClone; Heap::transaction(|j| { let x = Pbox::new(5, j); let y = x.pclone(j); // The value is the same assert_eq!(x, y); // But they are unique objects assert_ne!(&*x as *const i32, &*y as *const i32); }).unwrap();
pub fn pclone_from(&mut self, source: &Self, journal: &Journal<A>)
[src]
impl<T: PSafe + PartialEq + ?Sized, A: MemPool> PartialEq<Pbox<T, A>> for Pbox<T, A>
[src]
impl<T: PSafe + PartialOrd + ?Sized, A: MemPool> PartialOrd<Pbox<T, A>> for Pbox<T, A>
[src]
pub fn partial_cmp(&self, other: &Pbox<T, A>) -> Option<Ordering>
[src]
pub fn lt(&self, other: &Pbox<T, A>) -> bool
[src]
pub fn le(&self, other: &Pbox<T, A>) -> bool
[src]
pub fn ge(&self, other: &Pbox<T, A>) -> bool
[src]
pub fn gt(&self, other: &Pbox<T, A>) -> bool
[src]
impl<T: Default + PSafe, A: MemPool> RootObj<A> for Pbox<T, A>
[src]
impl<T: RootObj<A> + PSafe, A: MemPool> RootObj<A> for Pbox<T, A>
[src]
impl<A: MemPool, T: ?Sized> !Send for Pbox<T, A>
[src]
impl<T: ?Sized, A: MemPool> !TxOutSafe for Pbox<T, A>
[src]
impl<T: PSafe + ?Sized, A: MemPool> Unpin for Pbox<T, A>
[src]
impl<A: MemPool, T: ?Sized> !VSafe for Pbox<T, A>
[src]
Auto Trait Implementations
impl<T: ?Sized, A> LooseTxInUnsafe for Pbox<T, A> where
A: LooseTxInUnsafe,
T: LooseTxInUnsafe,
[src]
A: LooseTxInUnsafe,
T: LooseTxInUnsafe,
impl<T: ?Sized, A> PSafe for Pbox<T, A>
[src]
impl<T: ?Sized, A> RefUnwindSafe for Pbox<T, A> where
A: RefUnwindSafe,
T: RefUnwindSafe,
[src]
A: RefUnwindSafe,
T: RefUnwindSafe,
impl<T, A> !Sync for Pbox<T, A>
[src]
impl<T: ?Sized, A> TxInSafe for Pbox<T, A> where
A: TxInSafe,
T: TxInSafe,
[src]
A: TxInSafe,
T: TxInSafe,
impl<T: ?Sized, A> UnwindSafe for Pbox<T, A> where
A: UnwindSafe,
T: UnwindSafe,
[src]
A: UnwindSafe,
T: UnwindSafe,
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
pub fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToString for T where
T: Display + ?Sized,
[src]
T: Display + ?Sized,
impl<T, A> ToString<A> for T where
A: MemPool,
T: Display + ?Sized,
[src]
A: MemPool,
T: Display + ?Sized,
pub default fn to_pstring(&Self, &Journal<A>) -> String<A>
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
pub fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
pub fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<V, T> VZip<V> for T where
V: MultiLane<T>,
V: MultiLane<T>,