Skip to main content

Listpack

Struct Listpack 

Source
pub struct Listpack { /* private fields */ }
Expand description

A packed blob of elements.

Owns its bytes today. When the arena lands under it the bytes move there and this becomes a view, which is why nothing here hands out a Vec or takes one back.

Implementations§

Source§

impl Listpack

Source

pub fn new() -> Listpack

An empty blob, which is a header and a terminator and nothing else.

Source

pub fn from_bytes(bytes: &[u8]) -> Result<Listpack, Malformed>

Take bytes somebody else wrote, after checking them.

An RDB, a .yo file and a RESTORE all arrive this way, so the walk is not optional. A blob that does not check out is refused whole rather than read up to the bad entry, because half a collection is worse than none.

Source

pub fn as_bytes(&self) -> &[u8]

The bytes, ready to be written to a file or an RDB unchanged.

Source

pub fn len(&self) -> usize

How many elements.

The header answers this, which is why it is here and why it is kept right on every edit. A blob from elsewhere with an unknown count is walked instead, once, rather than being rejected.

Source

pub fn is_empty(&self) -> bool

Whether there is nothing in it, which for Redis means it does not exist.

Source

pub fn byte_len(&self) -> usize

What the blob costs, which is what it costs on disk too.

Source

pub fn iter(&self) -> Iter<'_>

Every element, front to back.

Source

pub fn get(&self, index: usize) -> Option<Entry<'_>>

The element at a position, counting from the front.

Linear, because the blob is linear. That is the whole design: at a hundred and twenty eight elements the walk is cheaper than the index that would have avoided it. From whichever end is nearer, though, because a list in this band holds eight kilobytes and that is four hundred odd entries rather than a hundred and twenty eight, and LINDEX key -1 on one of those should not read all of it.

Source

pub fn iter_at(&self, byte: usize) -> Iter<'_>

A forward walk that starts at a byte offset a previous walk reported.

The offset has to come from Iter::offset on a walk of this same blob, taken while nothing has moved the bytes since. A stream node uses it to resume a group read where the last one stopped instead of decoding the whole node again, and it checks the entry it lands on before believing it. An offset that is past the end gives an empty walk rather than nonsense, and one that lands in the middle of an entry gives whatever those bytes decode as, which is why the caller checks.

Source

pub fn iter_from(&self, index: usize) -> Iter<'_>

A forward walk that starts at index rather than at the front.

LRANGE key 300 320 on a packed list would otherwise decode three hundred entries and throw them away, which is what a skip on the walk does.

Source

pub fn iter_back(&self) -> RevIter<'_>

Every element, back to front.

The trailing length on each entry is what makes this cost the same per element as the forward walk. LPOS with a negative rank counts matches from the tail and stops when it has enough, so walking forward and keeping the answers would be the wrong shape as well as the wrong cost.

Source

pub fn get_back(&self, from_end: usize) -> Option<Entry<'_>>

The element at a position, counting from the back.

Reads the back length of the last entry and steps left, which is what the trailing length field is for and why a RPOP on a small list does not walk the whole blob.

Source

pub fn find(&self, needle: &[u8], step: usize) -> Option<usize>

Where an element is, or nothing.

step is what makes this work for a hash. A hash in this band is field, value, field, value, so a field lookup is a find with a step of two, which is the same trick Redis’s lpFind plays and the reason a hash does not need a second structure down here.

Source

pub fn find_parsed( &self, needle: &[u8], as_int: Option<i64>, step: usize, ) -> Option<usize>

The same walk with the needle already parsed.

Set algebra asks one member of one set about every other set, so the parse would otherwise happen once per question about the same bytes. It is also the only form that can answer about a member which was never text: an intset holds the number and the digits do not exist anywhere until somebody writes them.

Source

pub fn find_each( &self, needle: &[u8], as_int: Option<i64>, limit: usize, hit: &mut dyn FnMut(usize) -> bool, ) -> usize

Every place an element is, front to back, handed over as they are found.

limit is how many elements may be looked at with 0 meaning all of them, hit says whether to carry on, and what comes back is how many elements were looked at. The walk itself is scan_each below.

Source

pub fn find_each_back( &self, needle: &[u8], as_int: Option<i64>, limit: usize, hit: &mut dyn FnMut(usize) -> bool, ) -> usize

The same from the back, with indexes counted from the last element.

Source

pub fn push(&mut self, value: &[u8])

Add an element at the end.

Source

pub fn insert(&mut self, index: usize, value: &[u8])

Put an element in front of the one at index.

An index at or past the end appends, which is what a sorted insert wants when the new element sorts last and saves the caller a branch.

Source

pub fn replace(&mut self, index: usize, value: &[u8]) -> bool

Overwrite the element at index, keeping its position.

HSET on a field that is already there, and ZADD on a member whose score has changed but whose place has not.

Source

pub fn delete(&mut self, index: usize, count: usize) -> bool

Take out count elements starting at index.

HDEL takes two, a field and its value, and it has to take them as one edit or the blob is briefly a hash with an odd number of entries.

Trait Implementations§

Source§

impl Clone for Listpack

Source§

fn clone(&self) -> Listpack

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Listpack

Source§

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

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

impl Default for Listpack

Source§

fn default() -> Listpack

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

impl Eq for Listpack

Source§

impl PartialEq for Listpack

Source§

fn eq(&self, other: &Listpack) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Listpack

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. 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.