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::BreadthFirstis 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.