Skip to main content

ScanOrder

Enum ScanOrder 

Source
pub enum ScanOrder {
    BreadthFirst,
    DepthFirst,
}
Expand description

The order directories are visited in.

This changes when observations are produced, never which ones: both orders visit every entry exactly once and leave an identical index behind. It therefore stays out of ScanScope and cannot invalidate a cache, exactly like the worker count.

The choice only matters to a consumer that reads the index while the walk is still running, and there it matters a great deal.

§Strength of the guarantee

These are scheduling preferences, not strict orders, whenever more than one worker is running — which is the default.

The queue is ordered, but the claims are not. Workers take directories from the shared queue in the policy’s order; a worker that finishes early can enqueue its children and another worker can claim them while a slower worker still holds unfinished work from a shallower level. Nothing releases a level barrier, because a barrier would idle every fast worker at each level boundary and give back most of the parallel producer’s win.

So:

  • With threads: Some(1), ScanOrder::BreadthFirst is strict: no directory is read before one closer to the root.
  • With several workers it is shallow-first: shallow work is always preferred when a worker chooses, and deeper observations can still interleave.

That weaker property is what the browser use case actually needs — every top-level subtree starts filling early, so a mid-scan ranking is meaningful — and it is the property the tests pin. A caller that needs strict level order must ask for one worker and pay for it.

Variants§

§

BreadthFirst

Shallow directories before deep ones.

The default, because it is the order whose partial results mean something. Roll-ups are maintained per directory as the walk proceeds, so a consumer that looks mid-scan sees top-level totals grow together — bars fill, rankings converge — instead of one subtree finishing while its siblings read zero. Interrupting early leaves a usefully complete picture of the top of the tree.

Under several workers this is a preference rather than a guarantee; see the type-level note above.

Note that totals only grow while an additive walk is running. Monotonicity comes from the producer being additive, not from the order — the order decides which subtrees get to grow early.

§

DepthFirst

One subtree toward completion before starting the next.

Lower peak memory, since the frontier is bounded by depth rather than by the width of a level, and better locality within a subtree. The cost is that partial results are actively misleading: one child of the root approaches its final total while its siblings read zero, so anything ranking by size mid-scan ranks confidently and wrongly. Correct for a caller that only reads the finished index and wants the smallest footprint.

Under several workers this too is a preference: several subtrees will be in flight at once, one per worker.

Trait Implementations§

Source§

impl Clone for ScanOrder

Source§

fn clone(&self) -> Self

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 ScanOrder

Source§

impl Debug for ScanOrder

Source§

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

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

impl Default for ScanOrder

Source§

fn default() -> Self

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

impl Eq for ScanOrder

Source§

impl PartialEq for ScanOrder

Source§

fn eq(&self, other: &Self) -> 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 ScanOrder

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.