Skip to main content

ListObj

Struct ListObj 

Source
pub struct ListObj {
    pub header: Header,
    /* private fields */
}
Expand description

A list: header, length, a pointer to a backing array, and room for a few elements inline.

Reads never lock, even on shared lists. The length and buffer pointer are atomic words, and a reader bounds-checks against the buffer it loaded, so it sees some consistent-enough state and never reads out of bounds. A writer (the owner, or a thread holding a shared list’s lock) that outgrows the buffer copies it into a new one and swaps the pointer; the old buffer is retired to the collector, which frees it only once the world is stopped and no reader can hold it.

Small lists keep their elements in the object itself: inline is a WordBuf embedded at the end of the object (its slots follow the struct), and buf points at it. Readers do not tell the two cases apart; they load buf as always. A list that outgrows its inline slots moves to an out-of-line buffer exactly as above, and never moves back, so the inline slots are never written again. A racing reader that loaded the inline pointer before the move reads values the list held then, from memory that lives as long as the list does, so the inline buffer needs no retiring. It is never freed on its own: it goes with the object.

Fields§

§header: Header

Implementations§

Source§

impl ListObj

Source

pub const INLINE_MAX: usize = 7

Most elements a new list keeps inline (a 96-byte object). Odd, so the object fills its size class. Chosen by measurement (issue #104).

Source

pub const INLINE_MIN: usize = 3

Inline capacity of a new empty (or one-element) list.

Source

pub fn inline_cap_for(cap: usize) -> usize

The inline capacity of a new list that should have room for cap elements, or 0 if they belong out of line. Rounded up to odd: an even count would leave a word of the size-class slot unused.

Source

pub fn size_for(icap: usize) -> usize

The allocation size of a list with inline capacity icap.

Source

pub fn is_inline(&self) -> bool

Whether the elements are currently stored in the object itself.

Source

pub fn len(&self) -> usize

Source

pub fn is_empty(&self) -> bool

Source

pub fn get(&self, i: usize) -> Option<Value>

The item at i, if in bounds. Safe against concurrent writers; the caller must still have passed the ownership read check.

Source

pub fn get_local(&self, i: usize) -> Option<Value>

As ListObj::get for a list owned by this thread or frozen, where nothing races.

Source

pub fn to_vec(&self) -> Vec<Value>

A snapshot of the items.

Source

pub fn try_to_vec(&self) -> RtResult<Vec<Value>>

As ListObj::to_vec, raising a MemoryError if the vector cannot be had.

Source

pub fn capacity(&self) -> usize

Source

pub unsafe fn set(&self, i: usize, v: Value) -> bool

§Safety

See above.

Source

pub unsafe fn push(&self, v: Value, access: Access)

§Safety

See above.

Source

pub unsafe fn try_push(&self, v: Value, access: Access) -> Result<(), Layout>

As ListObj::push, but if the allocator refuses to grow the list, returns the refused layout and leaves the list as it was.

§Safety

See above.

Source

pub unsafe fn pop(&self) -> Option<Value>

§Safety

See above.

Source

pub unsafe fn replace(&self, items: &[Value], access: Access)

Replaces the contents with items, reusing the buffer when it is large enough.

§Safety

See above.

Source

pub unsafe fn try_replace( &self, items: &[Value], access: Access, ) -> Result<(), Layout>

As ListObj::replace, but if the allocator refuses a larger buffer, returns the refused layout and leaves the list as it was.

§Safety

See above.

Source

pub unsafe fn modify<R>( &self, access: Access, f: impl FnOnce(&mut Vec<Value>) -> R, ) -> R

Runs f on a copy of the items and writes the result back.

§Safety

See above.

Source

pub unsafe fn try_modify<R>( &self, access: Access, f: impl FnOnce(&mut Vec<Value>) -> R, ) -> Result<R, Layout>

As ListObj::modify, but if the allocator refuses a larger buffer for the result, returns the refused layout and leaves the list as it was.

§Safety

See above.

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> NativeData for T
where T: Any + Send + Sync,

Source§

fn as_any(&self) -> &(dyn Any + 'static)

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.