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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//! Reachability: the two-pass traversal that separates live objects from dead.
//!
//! Two plain passes encode the relationship policy without any special-cased
//! machinery (the policy itself is documented in [`super`]):
//!
//! 1. **Strong pass** — from the roots (report bindings and roles), over every
//! edge *except* relationship endpoints and the inactive-relationship
//! edges. Containment fires: a used column keeps its table alive, a used
//! table keeps its partitions and active relationships alive.
//! 2. **Weak pass** — extends the strong set over every edge *except*
//! containment and the inactive-relationship edges. A live table pulls in
//! its relationships and both their key columns, but a key column that is
//! only alive this way can no longer keep its own table alive — so a table
//! referenced by nothing but a relationship is still reported unused. An
//! inactive relationship joins only through a live `USERELATIONSHIP`
//! reference (an ordinary Dax edge); its table references never confer
//! liveness, so an unactivated one is a finding.
//!
//! A consumer annotation therefore never lies: for any unused object, every
//! referencing object is either itself unused, live only through a
//! relationship endpoint (its `also_unused` flag is `false`), or the table of
//! an inactive relationship the relationship cannot keep alive.
use HashSet;
use ;
/// The liveness verdict for one graph: the set of live objects.
pub
/// One object reachability never reached — a `scan` finding.
/// One referencing object behind an [`UnusedObject`].