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: HeaderImplementations§
Source§impl ListObj
impl ListObj
Sourcepub const INLINE_MAX: usize = 7
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).
Sourcepub const INLINE_MIN: usize = 3
pub const INLINE_MIN: usize = 3
Inline capacity of a new empty (or one-element) list.
Sourcepub fn inline_cap_for(cap: usize) -> usize
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.
Sourcepub fn is_inline(&self) -> bool
pub fn is_inline(&self) -> bool
Whether the elements are currently stored in the object itself.
pub fn len(&self) -> usize
pub fn is_empty(&self) -> bool
Sourcepub fn get(&self, i: usize) -> Option<Value>
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.
Sourcepub fn get_local(&self, i: usize) -> Option<Value>
pub fn get_local(&self, i: usize) -> Option<Value>
As ListObj::get for a list owned by this thread or frozen, where nothing races.
Sourcepub fn try_to_vec(&self) -> RtResult<Vec<Value>>
pub fn try_to_vec(&self) -> RtResult<Vec<Value>>
As ListObj::to_vec, raising a MemoryError if the vector cannot be had.
pub fn capacity(&self) -> usize
Sourcepub unsafe fn try_push(&self, v: Value, access: Access) -> Result<(), Layout>
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.
Sourcepub unsafe fn try_replace(
&self,
items: &[Value],
access: Access,
) -> Result<(), Layout>
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.
Sourcepub unsafe fn try_modify<R>(
&self,
access: Access,
f: impl FnOnce(&mut Vec<Value>) -> R,
) -> Result<R, Layout>
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.