nodedb_array/segment/mbr_index/
predicate.rs1use super::node::BBox;
12use crate::types::domain::DomainBound;
13
14pub fn lt_bound(a: &DomainBound, b: &DomainBound) -> bool {
16 a.partial_cmp(b)
17 .is_some_and(|o| o == std::cmp::Ordering::Less)
18}
19
20fn le_bound(a: &DomainBound, b: &DomainBound) -> bool {
21 a.partial_cmp(b)
22 .is_some_and(|o| o != std::cmp::Ordering::Greater)
23}
24
25#[derive(Debug, Clone, Default)]
28pub struct MbrQueryPredicate {
29 pub per_dim: Vec<DimPredicate>,
30}
31
32#[derive(Debug, Clone, Default)]
33pub struct DimPredicate {
34 pub lo: Option<DomainBound>,
35 pub hi: Option<DomainBound>,
36}
37
38impl MbrQueryPredicate {
39 pub fn new(per_dim: Vec<DimPredicate>) -> Self {
40 Self { per_dim }
41 }
42
43 pub fn intersects(&self, bbox: &BBox) -> bool {
51 for (i, dp) in self.per_dim.iter().enumerate() {
52 if i >= bbox.arity() {
53 break;
54 }
55 if let Some(lo) = &dp.lo
56 && lt_bound(&bbox.max[i], lo)
57 {
58 return false;
59 }
60 if let Some(hi) = &dp.hi
61 && lt_bound(hi, &bbox.min[i])
62 {
63 return false;
64 }
65 let _ = le_bound; }
69 true
70 }
71}
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76
77 fn b(min: i64, max: i64) -> BBox {
78 BBox {
79 min: vec![DomainBound::Int64(min)],
80 max: vec![DomainBound::Int64(max)],
81 }
82 }
83
84 fn pred(lo: Option<i64>, hi: Option<i64>) -> MbrQueryPredicate {
85 MbrQueryPredicate::new(vec![DimPredicate {
86 lo: lo.map(DomainBound::Int64),
87 hi: hi.map(DomainBound::Int64),
88 }])
89 }
90
91 #[test]
92 fn fully_inside_intersects() {
93 assert!(pred(Some(2), Some(8)).intersects(&b(0, 10)));
94 }
95
96 #[test]
97 fn fully_outside_left() {
98 assert!(!pred(Some(20), Some(30)).intersects(&b(0, 10)));
99 }
100
101 #[test]
102 fn fully_outside_right() {
103 assert!(!pred(Some(-10), Some(-5)).intersects(&b(0, 10)));
104 }
105
106 #[test]
107 fn touching_intersects() {
108 assert!(pred(Some(10), Some(20)).intersects(&b(0, 10)));
109 }
110
111 #[test]
112 fn unbounded_intersects() {
113 assert!(pred(None, None).intersects(&b(5, 7)));
114 }
115}