[−][src]Trait pui_arena::version::Version
The versioning strategy
Slot Exhaustion
Arenas store a version alongside each slot they have. If a slot's version is
exhausted, then that slot will never be reused. For DefaultVersion
this will only happen after about 2 billion insertion/deletion pairs per slot,
so it shouldn't be an issue. However, for smaller version types like TinyVersion
each slot will exhaust after only 127 insertion/deletion pairs per slot.
You can avoid version exahustion by using Unversioned
, but this suffers from the
ABA problem.
ABA problem
Consider this sequence of operations:
use pui_arena::version::UnversionedFull; // insert 0 at index 0, arena = [(version: Unversioned::Full, Some(0))] let a: Key<usize, UnversionedFull> = arena.insert(0); // remove at index 0, arena = [(version: Unversioned::Empty, None)] arena.remove(a); // insert 10 at index 0, arena = [(version: Unversioned::Full, Some(10))] let b: Key<usize, UnversionedFull> = arena.insert(10); // get the value at index 0 assert_eq!(arena.get(a), None);
because arena
is using Unversioned
slots, even though key a
was removed from the
arena
, we can still access it! This is fundementally what the ABA problem is. Even
though a key was removed, the arena can't distinguish stale keys so it allows access
to the new values when it shouldn't.
Depending on your problem space, this may or may not be a problem you need to sove.
If it is a problem you need to solve, then you will need to deal with version exhaustion
in some way, because there are never going to be an infinite number of versions. pui-arena
handles this for you by "leaking" slots with exhausted versions. These slots will not
be reused, but will be deallocated once the Arena
drops.
Associated Types
Loading content...Associated Constants
Loading content...Required methods
pub unsafe fn mark_empty(self) -> Result<Self, Self>
[src]
Convert an full version to a empty version
returns Err
if there are no more versions
Safety
mark_empty
can only be called on a full version
pub unsafe fn mark_full(self) -> Self
[src]
pub fn is_exhausted(&self) -> bool
[src]
Check if the version is exhausted
pub fn is_full(self) -> bool
[src]
Check if the version is full
pub unsafe fn save(self) -> Self::Save
[src]
pub fn equals_saved(self, saved: Self::Save) -> bool
[src]
Check if the saved version matches the current version
In particular, this can only be true if the current version is full
and may not be true if there was a call to mark_empty
in since the
save was created.