hawdb_executor/
retrieval_report.rs1use hawdb_plan_cypher::PhysicalOperatorId;
7
8#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
11pub struct TextSeedSourceReport {
12 pub generation: Option<u64>,
13 pub source_commit_epoch: Option<u64>,
14 pub corpus_documents: Option<usize>,
15 pub matching_documents: Option<usize>,
16 pub postings_visited: Option<u64>,
17 pub bytes_read: Option<u64>,
18 pub document_bytes_read: Option<u64>,
19}
20
21#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
22pub struct TextSeedExecutionReport {
23 pub operator_id: Option<PhysicalOperatorId>,
24 pub complete_requested: bool,
25 pub executed: bool,
26 pub source_exhausted: bool,
27 pub candidate_limit: usize,
28 pub candidate_count: usize,
30 pub retained_result_bytes: usize,
31 pub source: Option<TextSeedSourceReport>,
32}
33
34impl TextSeedExecutionReport {
35 pub fn status(&self) -> &'static str {
36 if !self.executed {
37 "skipped"
38 } else if !self.complete_requested {
39 "window"
40 } else if self.source_exhausted {
41 "complete"
42 } else {
43 "incomplete"
44 }
45 }
46}
47
48#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
49pub struct GroupedEvidenceExecutionReport {
50 pub operator_id: Option<PhysicalOperatorId>,
51 pub executed: bool,
52 pub input_exhausted: bool,
54 pub input_rows: usize,
55 pub borrowed_group_key_rows: usize,
57 pub groups_considered: usize,
58 pub retained_evidence: usize,
59 pub output_groups: usize,
60 pub peak_state_bytes: usize,
61 pub spilled_bytes: u64,
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67 use crate::observer::{grouped_evidence_report_value, text_seed_execution_report_value};
68 use hawdb_core::Value;
69
70 #[test]
71 fn coverage_status_and_value_encoding_preserve_unknown_source_evidence() {
72 let mut report = TextSeedExecutionReport {
73 complete_requested: true,
74 operator_id: Some(PhysicalOperatorId::from_ordinal(4)),
75 ..Default::default()
76 };
77 assert_eq!(report.status(), "skipped");
78 report.executed = true;
79 assert_eq!(report.status(), "incomplete");
80 report.source_exhausted = true;
81 assert_eq!(report.status(), "complete");
82 report.source = Some(TextSeedSourceReport {
83 generation: Some(19),
84 postings_visited: Some(32),
85 ..Default::default()
86 });
87 let Value::Map(encoded) = text_seed_execution_report_value(&report) else {
88 panic!()
89 };
90 assert_eq!(encoded["operator_id"], Value::Int(4));
91 assert_eq!(encoded["status"], Value::String("complete".into()));
92 let Value::Map(source) = &encoded["source"] else {
93 panic!()
94 };
95 assert_eq!(source["generation"], Value::Int(19));
96 assert_eq!(source["source_commit_epoch"], Value::Null);
97 assert_eq!(source["bytes_read"], Value::Null);
98 report.complete_requested = false;
99 assert_eq!(report.status(), "window");
100 let Value::Map(grouped) =
101 grouped_evidence_report_value(&GroupedEvidenceExecutionReport::default())
102 else {
103 panic!()
104 };
105 assert_eq!(grouped["executed"], Value::Bool(false));
106 assert_eq!(grouped["input_exhausted"], Value::Bool(false));
107 }
108}