1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//! The check that lets a running query be stopped.
use ;
use Chunk;
use crateOperator;
use crateSchema;
/// An operator that asks whether the query should stop before it produces anything.
///
/// [`build`](crate::build) wraps every node in one of these, rather than putting the check in the
/// operators that can loop for a long time. Two reasons, and the second is the important one. It is
/// one line in one place instead of a decision per operator, and a decision per operator is a
/// decision somebody gets wrong when they add the twentieth one. And "every operator checks before
/// it produces a chunk" is a sentence that can be read and believed, where "these six check" is a
/// claim that has to be re-audited every time an operator is added or a loop is moved.
///
/// The cost is an atomic load and an indirect call per chunk per level of the tree. A chunk is 1024
/// rows and the cheapest thing any operator does to one is measured in microseconds, so this is
/// somewhere under a thousandth of that, and it buys a query that stops when it is asked to. That
/// is the trade `spec/engine/10-scheduler.md` section 10.9 asks for in as many words: every
/// operator checks a cancellation flag at chunk granularity, because once per thousand rows is
/// cheap and once per row is not.
///
/// What this cannot see is work an operator does inside one call to `next`. Pulling from a child is
/// not that, because the child is wrapped too, so an operator that reads its whole input is checked
/// all the way through the reading. An operator that then loops over what it read is, and [`Join`]
/// is the one that does: the nested loop runs to the end inside the first `next`, and a hundred
/// thousand left rows against thirty thousand right ones is a minute with nothing looking at the
/// token. So that loop holds the token as well and checks it once per left row. The rule is still
/// the one above, with a sentence after it: every operator is checked between its chunks, and an
/// operator whose own loop can outlive a chunk checks inside it.
///
/// [`Join`]: crate::join::Join
pub