Skip to main content

Cursor

Struct Cursor 

Source
pub struct Cursor(/* private fields */);
Expand description

Where a scan stopped, as the client sees it.

Opaque to the client, and deliberately so, but not opaque in here: it is a partition count, a partition, and a row index, packed the way 08 §4 names them.

 63    52 51    40 39                                   0
+--------+--------+--------------------------------------+
|   P    |  part  |               idx + 1                |
+--------+--------+--------------------------------------+

Zero is both the start and the end, which is Redis’s convention and is unambiguous here because a real cursor always names a partition count and a partition count is never zero.

An idx + 1 of zero is not a row, it means the top of that partition, whatever its length turns out to be. A resume needs to be able to say that without knowing how long the partition is, because Cursor::rebase moves a cursor into a partition it has never looked at.

Implementations§

Source§

impl Cursor

Source

pub const START: Cursor

Start at the beginning, which for a downward walk is the top.

Source

pub const END: Cursor

Nothing left. The same value as Cursor::START, which is what the protocol says and what every Redis client already loops on.

Source

pub const fn from_raw(raw: u64) -> Cursor

A cursor as the client sent it back.

Source

pub const fn raw(self) -> u64

The number to put on the wire.

Source

pub const fn is_end(self) -> bool

Whether the scan is over.

Source

pub const fn at(parts: u32, part: u32, idx: u64) -> Cursor

Resume at a row.

parts and part are clamped rather than rejected. A client can send any number back and Redis answers all of them, so a cursor that names a partition that does not exist has to mean something sane rather than be an error.

Source

pub const fn top(parts: u32, part: u32) -> Cursor

Resume at the top of a partition, without saying how long it is.

Source

pub const fn parts(self) -> u32

How many partitions the collection had when this was issued.

One for a cursor that has not been anywhere yet, which is also the truth for every collection below the partitioned band.

Source

pub const fn part(self) -> u32

Which partition it stopped in.

Source

pub const fn idx(self) -> Option<u64>

The next row to read, or None for the top of the partition.

Source

pub const fn rebase(self, parts_now: u32) -> Cursor

Move a cursor into the layout the collection has now.

Growing from P to some larger power of two splits every partition and moves nothing between the halves, because a member’s partition is the low bits of its hash and growing only reads more of them. So an old partition part becomes the new partitions whose low log2(P) bits are part, and every new partition whose low bits are above part has already been walked in full.

Resuming at the top of the highest new partition with those low bits covers all of the work that is left, and walking down from there also passes back over some partitions that were already done. That is duplicate work and duplicates are allowed. What it never does is skip one, and it never restarts the whole scan either, which is the other easy answer and the one that turns a growth into a full second pass.

The row index is dropped rather than carried across. A split redistributes the rows, so an index into the old partition’s array names a different member in the new one, and resuming at the top of the partition it stopped in is the only thing that can be said honestly.

Shrinking is the other direction and is not something the size ladder does under a live scan, so a cursor from a larger layout is answered by starting the current one at the top. A repeat is allowed. A miss is not.

Trait Implementations§

Source§

impl Clone for Cursor

Source§

fn clone(&self) -> Cursor

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 Copy for Cursor

Source§

impl Debug for Cursor

Source§

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

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

impl Default for Cursor

Source§

fn default() -> Cursor

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

impl Eq for Cursor

Source§

impl Hash for Cursor

Source§

fn hash<__H>(&self, state: &mut __H)
where __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl Ord for Cursor

Source§

fn cmp(&self, other: &Cursor) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 (const: unstable) · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 (const: unstable) · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 (const: unstable) · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

fn clamp_to<R>(self, range: R) -> Self
where Self: Sized, R: ClampBounds<Self>,

🔬This is a nightly-only experimental API. (clamp_to)
Restrict a value to a certain range. Read more
Source§

impl PartialEq for Cursor

Source§

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

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

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

Inequality operator !=. Read more
Source§

impl PartialOrd for Cursor

Source§

fn partial_cmp(&self, other: &Cursor) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 (const: unstable) · Source§

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

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 (const: unstable) · Source§

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

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 (const: unstable) · Source§

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

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 (const: unstable) · Source§

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

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl StructuralPartialEq for Cursor

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.