Rindle docs and package mapSkip to main content

Take

Struct Take 

Source
pub struct Take {
    pub input: NodeId,
    pub storage: StorageId,
    pub limit: u32,
    pub partition_key: Option<Vec<ColId>>,
    pub output: Cell<Option<OutEdge>>,
    pub sort: Sort,
    pub retain_empty_partitions: bool,
    /* private fields */
}
Expand description

Take: ordered, bounded top-N per partition, backed by a StorageId slot.

Fields§

§input: NodeId

Upstream input (the connection, a Skip, or — once EXISTS lands — a join).

§storage: StorageId

Handle into the Graph storage arena holding this op’s per-partition TakeState (under encode_state_key("take", …)) + the MAX_BOUND row.

§limit: u32

The LIMIT count. 0 ⇒ the operator yields nothing and stores no state.

§partition_key: Option<Vec<ColId>>

The partition columns (the correlation child field of a limited relationship), or None for a top-level limit (a single global partition).

§output: Cell<Option<OutEdge>>

The single downstream edge as a port-carrying OutEdge (like Skip/Join): Port::Single to a terminal sink, Port::JoinParent when this Take feeds a relationship join’s parent port (a limited relationship). Wired via Graph::set_output (Single) or Graph::set_out_edge (explicit port).

§sort: Sort

The input sort, resolved at build time (the connection’s completed, PK-including order). Take requires sorted input (take.ts:74); the comparator only ever reads these columns.

§retain_empty_partitions: bool

Keep a partition’s slot when it drains to empty (design 310, impl plan D4). A partitioned child Take deletes the slot, because its parent join’s constrained fetch re-hydrates it when the parent re-enters; a family root Take has no parent, so after such a delete the next Add for a still-bound value would find get_state == None and be dropped — a silent missing row for that binding. Set only by the family builder; the slot is then deleted by Take::evict_partition at unbind. The top-level unpartitioned branch already keeps size-0 state for the same reason; this flag extends that rule to root partitions.

Implementations§

Source§

impl Take

Source

pub fn new( input: NodeId, storage: StorageId, limit: u32, partition_key: Option<Vec<ColId>>, sort: Sort, ) -> Take

Source

pub fn with_retain_empty_partitions(self, on: bool) -> Take

Builder: keep drained-to-empty partition slots (see Take::retain_empty_partitions). The family root limiter sets this.

Source

pub fn fetch<'g>( &'g self, g: &'g Graph, req: &FetchRequest, ) -> Box<dyn Iterator<Item = Node<'g>> + 'g>

Lazy pull (take.ts:93). Two regimes:

  1. No partition key, or the request constraint matches the partition key: bound by that single partition’s TakeState (hydrating it on first sight).
  2. Partitioned but the constraint is absent / on a different key (nested subqueries): bound by MAX_BOUND, re-checking each row against its own partition’s bound.
Source

pub fn evict_partition(&self, g: &Graph, constraint: &Constraint)

Delete the per-partition slot identified by constraint (the parent→child correlation key), if this Take is partitioned and the constraint covers its partition key. Called by the relationship join when a parent leaves a bounded parent view (a parent Remove on Port::JoinParent): the child partition that parent hydrated is no longer referenced by any result row, but — unlike the drain-to-empty case in push_remove — its child rows are still live in the window, so nothing else ever deletes the slot. Without this, a partitioned child Take accumulates one zombie slot per distinct parent that ever floated through the bounded view (e.g. every page that hit the wiki demo’s “latest” board as the last_ts ordering churns), leaking operator state proportional to the retention window rather than the (bounded) view.

Safe — and symmetric with the drain-time delete — because a partitioned Take is re-hydrated from source by the parent join’s constrained fetch when its parent re-enters (Take::fetch’s no-state → initial_fetch), and a push to an un-hydrated partition is already dropped (get_state == None). The caller only invokes this when the parent correlation key is unique (the parent’s primary key), so the evicted slot belongs to exactly the one parent that left. No-op for an unpartitioned (top-level) Take or a constraint that does not cover the partition key.

Source

pub fn push<'g>(&'g self, g: &'g Graph, change: Change<'g>)

Eager push (take.ts:247). Edit routes to Take::push_edit; otherwise look up the partition’s state (drop the change if it was never hydrated) and dispatch Add / Remove / Child. Forwards on the edge’s own port so a limited relationship can feed a parent join.

Auto Trait Implementations§

§

impl !Freeze for Take

§

impl !RefUnwindSafe for Take

§

impl Send for Take

§

impl !Sync for Take

§

impl Unpin for Take

§

impl UnsafeUnpin for Take

§

impl UnwindSafe for Take

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.