nodedb_spatial/rtree/
node.rs1use nodedb_types::BoundingBox;
6use serde::{Deserialize, Serialize};
7use zerompk::{FromMessagePack, ToMessagePack};
8
9pub const LEAF_CAPACITY: usize = 32;
10pub const INTERNAL_CAPACITY: usize = 16;
11pub const MIN_FILL_LEAF: usize = LEAF_CAPACITY * 2 / 5;
12pub const MIN_FILL_INTERNAL: usize = INTERNAL_CAPACITY * 2 / 5;
13pub const REINSERT_COUNT_LEAF: usize = LEAF_CAPACITY * 3 / 10;
14
15pub type EntryId = u64;
17
18#[derive(
20 Debug,
21 Clone,
22 Serialize,
23 Deserialize,
24 ToMessagePack,
25 FromMessagePack,
26 rkyv::Archive,
27 rkyv::Serialize,
28 rkyv::Deserialize,
29)]
30pub struct RTreeEntry {
31 pub id: EntryId,
32 pub bbox: BoundingBox,
33}
34
35#[derive(Debug, Clone)]
37pub(crate) struct ChildRef {
38 pub bbox: BoundingBox,
39 pub node_idx: usize,
40}
41
42#[derive(Debug, Clone)]
44pub(crate) enum NodeKind {
45 Internal { children: Vec<ChildRef> },
46 Leaf { entries: Vec<RTreeEntry> },
47}
48
49#[derive(Debug, Clone)]
50pub(crate) struct Node {
51 pub kind: NodeKind,
52 pub bbox: BoundingBox,
53 pub level: u32,
54}
55
56impl Node {
57 pub fn new_leaf() -> Self {
58 Self {
59 kind: NodeKind::Leaf {
60 entries: Vec::with_capacity(LEAF_CAPACITY),
61 },
62 bbox: BoundingBox::new(
63 f64::INFINITY,
64 f64::INFINITY,
65 f64::NEG_INFINITY,
66 f64::NEG_INFINITY,
67 ),
68 level: 0,
69 }
70 }
71
72 pub fn new_internal(level: u32) -> Self {
73 Self {
74 kind: NodeKind::Internal {
75 children: Vec::with_capacity(INTERNAL_CAPACITY),
76 },
77 bbox: BoundingBox::new(
78 f64::INFINITY,
79 f64::INFINITY,
80 f64::NEG_INFINITY,
81 f64::NEG_INFINITY,
82 ),
83 level,
84 }
85 }
86
87 pub fn is_leaf(&self) -> bool {
88 matches!(self.kind, NodeKind::Leaf { .. })
89 }
90
91 pub fn capacity(&self) -> usize {
92 if self.is_leaf() {
93 LEAF_CAPACITY
94 } else {
95 INTERNAL_CAPACITY
96 }
97 }
98
99 pub fn len(&self) -> usize {
100 match &self.kind {
101 NodeKind::Internal { children } => children.len(),
102 NodeKind::Leaf { entries } => entries.len(),
103 }
104 }
105
106 pub fn is_overflow(&self) -> bool {
107 self.len() > self.capacity()
108 }
109
110 pub fn min_fill(&self) -> usize {
111 if self.is_leaf() {
112 MIN_FILL_LEAF
113 } else {
114 MIN_FILL_INTERNAL
115 }
116 }
117
118 pub fn is_underflow(&self) -> bool {
119 self.len() < self.min_fill()
120 }
121
122 pub fn recompute_bbox(&mut self) {
123 match &self.kind {
124 NodeKind::Internal { children } => {
125 if children.is_empty() {
126 self.bbox = BoundingBox::new(0.0, 0.0, 0.0, 0.0);
127 return;
128 }
129 let mut bb = children[0].bbox;
130 for c in &children[1..] {
131 bb = bb.union(&c.bbox);
132 }
133 self.bbox = bb;
134 }
135 NodeKind::Leaf { entries } => {
136 if entries.is_empty() {
137 self.bbox = BoundingBox::new(0.0, 0.0, 0.0, 0.0);
138 return;
139 }
140 let mut bb = entries[0].bbox;
141 for e in &entries[1..] {
142 bb = bb.union(&e.bbox);
143 }
144 self.bbox = bb;
145 }
146 }
147 }
148}