UniqueIdAllocatorAtomic

Struct UniqueIdAllocatorAtomic 

Source
pub struct UniqueIdAllocatorAtomic<T: IntegerIdCounter> { /* private fields */ }
Expand description

Allocates unique integer ids atomically, in a way safe to use from multiple threads.

§Thread Safety

This type makes the following guarantees about allocations:

  • Absent a call to Self::reset, each call to Self::alloc returns a new value. Consequently, if only a single allocator is used, all the ids will be unique.
  • All available ids will be used before an IdExhaustedError is returned. Equivalently, allocation will never skip over ids (although it may appear to from the perspective of a single thread).
  • Once an IdExhaustedError is returned, all future allocations will fail unless Self::reset is called. This is similar to the guarantees of Iterator::fuse.

This type only makes guarantees about atomicity, not about synchronization with other operations. In other words, without a core::sync::atomic::fence, there are no guarantees about the relative-ordering between this counter and other memory locations. It is not meant to be used as a synchronization primitive; It is only meant to allocate unique ids.

An incorrect implementation of IntegerId or IntegerIdCounter can break some or all of these guarantees, but will not be able to trigger undefined behavior.

Implementations§

Source§

impl<T: IntegerIdCounter> UniqueIdAllocatorAtomic<T>

Source

pub const fn new() -> Self

Create a new allocator, using T::START as the first id (usually zero).

Source

pub fn with_start(start: T) -> Self

Create a new allocator, using the specified value as the first id.

Use Self::with_start_const if you need a constant function.

Source

pub const fn with_start_const(start: T) -> Self
where T: NoUninit,

Create a new allocator, using the specified value as the first id.

In order to be usable from a const function, this requires that T implement the bytemuck::NoUninit trait and have the same size and representation as T::Int. If that does not happen, this method will fail to compile with a const panic.

§Safety

This function cannot cause undefined behavior.

Source

pub fn approx_max_used_id(&self) -> Option<T>

Estimate the maximum currently used id, or None if no ids have been allocated yet.

Unlike UniqueIdAllocator::max_used_id, this is only an approximation. This is because other threads may be concurrently allocating a new id.

Source

pub fn try_alloc(&self) -> Result<T, IdExhaustedError<T>>

Attempt to allocate a new id, returning an error if exhausted.

This operation is guaranteed to be atomic, and will never reuse ids unless Self::reset is called. However, it should not be used as a tool for synchronization. See type-level docs for more details.

§Errors

Once the number of allocated ids exceeds the range of the underlying IntegerIdCounter, then this function will return an error. This function will never skip over valid ids, so the error can only occur if all ids have ben used.

Source

pub fn alloc(&self) -> T

Attempt to allocate a new id, panicking if exhausted.

This operation is guaranteed to be atomic, and will never reuse ids unless Self::reset is called. However, it should not be used as a tool for synchronization. See type-level docs for more details.

§Panics

Panics if ids are exhausted, when Self::try_alloc would have returned an error.

Source

pub fn reset(&self)

Reset the allocator to a pristine state, beginning allocations all over again.

This is equivalent to running *allocator = UniqueIdAllocatorAtomic::new(), but is done atomically and does not require a &mut Self reference.

This may cause unexpected behavior if ids are expected to be monotonically increasing, or if the new ids conflict with ones still in use. To avoid this, keep the id allocator private.

There is no counterpart UniqueIdAllocator::set_next_id, because the ability to force the counter to jump forwards could prevent future optimizations.

Trait Implementations§

Source§

impl<T: Debug + IntegerIdCounter> Debug for UniqueIdAllocatorAtomic<T>
where T::Int: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: IntegerIdCounter> Default for UniqueIdAllocatorAtomic<T>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

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

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.