MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / score_triple

Function score_triple

nodedb/src/engine/graph/pattern/optimizer.rs:96–141  ·  view source on GitHub ↗

Score a triple for join ordering. Lower = more selective = better. Cost = label_edge_count * bound_variable_factor - If both src and dst are already bound: factor = 0.01 (point lookup) - If one endpoint is bound: factor = 0.1 (single-node expansion) - If neither is bound: factor = 1.0 (full scan)

(
    triple: &PatternTriple,
    csr: &CsrIndex,
    bound_vars: &std::collections::HashSet<String>,
)

Source from the content-addressed store, hash-verified

94/// - If one endpoint is bound: factor = 0.1 (single-node expansion)
95/// - If neither is bound: factor = 1.0 (full scan)
96fn score_triple(
97 triple: &PatternTriple,
98 csr: &CsrIndex,
99 bound_vars: &std::collections::HashSet<String>,
100) -> f64 {
101 // Base cost: label edge count (fewer = more selective).
102 let label_count = triple
103 .edge
104 .edge_type
105 .as_ref()
106 .map_or(csr.edge_count(), |label| csr.label_edge_count(label));
107
108 // If label has zero edges, this triple can't produce results — cheapest possible.
109 if label_count == 0 {
110 return 0.0;
111 }
112
113 let base_cost = label_count as f64;
114
115 // Bound variable factor.
116 let src_bound = triple
117 .src
118 .name
119 .as_ref()
120 .is_some_and(|n| bound_vars.contains(n));
121 let dst_bound = triple
122 .dst
123 .name
124 .as_ref()
125 .is_some_and(|n| bound_vars.contains(n));
126
127 let factor = match (src_bound, dst_bound) {
128 (true, true) => 0.01, // Both bound: point edge check.
129 (true, false) | (false, true) => 0.1, // One bound: neighborhood scan.
130 (false, false) => 1.0, // Neither bound: full label scan.
131 };
132
133 // Variable-length paths are more expensive — multiply by max_hops.
134 let hop_factor = if triple.edge.is_variable_length() {
135 triple.edge.max_hops as f64
136 } else {
137 1.0
138 };
139
140 base_cost * factor * hop_factor
141}
142
143#[cfg(test)]
144mod tests {

Callers 3

optimize_chainFunction · 0.85
score_bound_vs_unboundFunction · 0.85

Calls 5

label_edge_countMethod · 0.80
as_refMethod · 0.45
edge_countMethod · 0.45
containsMethod · 0.45
is_variable_lengthMethod · 0.45

Tested by 2

score_bound_vs_unboundFunction · 0.68