1use alloc::vec::Vec;
8
9use crate::builder::IntervalTreeBuilder;
10use crate::tree::IntervalTree;
11use crate::Interval;
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18pub struct IntervalId(u64);
19
20impl IntervalId {
21 #[inline]
23 #[must_use]
24 pub fn as_u64(self) -> u64 {
25 self.0
26 }
27}
28
29#[derive(Debug, Clone)]
31struct Entry<T, V> {
32 interval: Interval<T>,
33 value: V,
34 generation: u32,
35}
36
37#[derive(Debug, Clone)]
66pub struct IntervalSet<T, V> {
67 entries: Vec<Option<Entry<T, V>>>,
69 free_slots: Vec<usize>,
71 next_generation: u32,
73 count: usize,
75 cached_tree: Option<IntervalTree<T, usize>>,
77}
78
79impl<T, V> Default for IntervalSet<T, V> {
80 fn default() -> Self {
81 Self::new()
82 }
83}
84
85impl<T, V> IntervalSet<T, V> {
86 #[must_use]
88 pub fn new() -> Self {
89 Self {
90 entries: Vec::new(),
91 free_slots: Vec::new(),
92 next_generation: 0,
93 count: 0,
94 cached_tree: None,
95 }
96 }
97
98 #[must_use]
100 pub fn with_capacity(capacity: usize) -> Self {
101 Self {
102 entries: Vec::with_capacity(capacity),
103 free_slots: Vec::new(),
104 next_generation: 0,
105 count: 0,
106 cached_tree: None,
107 }
108 }
109
110 #[inline]
112 #[must_use]
113 pub fn len(&self) -> usize {
114 self.count
115 }
116
117 #[inline]
119 #[must_use]
120 pub fn is_empty(&self) -> bool {
121 self.count == 0
122 }
123
124 pub fn clear(&mut self) {
126 self.entries.clear();
127 self.free_slots.clear();
128 self.count = 0;
129 self.cached_tree = None;
130 }
131}
132
133impl<T: Ord + Copy, V> IntervalSet<T, V> {
134 pub fn insert<R: Into<Interval<T>>>(&mut self, range: R, value: V) -> IntervalId {
139 let interval = range.into();
140 let generation = self.next_generation;
141 self.next_generation = self.next_generation.wrapping_add(1);
142
143 let entry = Entry {
144 interval,
145 value,
146 generation,
147 };
148
149 let slot = if let Some(slot) = self.free_slots.pop() {
150 self.entries[slot] = Some(entry);
151 slot
152 } else {
153 let slot = self.entries.len();
154 self.entries.push(Some(entry));
155 slot
156 };
157
158 self.count += 1;
159 self.cached_tree = None; IntervalId(((generation as u64) << 32) | (slot as u64))
163 }
164
165 pub fn remove(&mut self, id: IntervalId) -> bool {
169 let slot = (id.0 & 0xFFFF_FFFF) as usize;
170 let generation = (id.0 >> 32) as u32;
171
172 if slot >= self.entries.len() {
173 return false;
174 }
175
176 if let Some(entry) = &self.entries[slot] {
177 if entry.generation == generation {
178 self.entries[slot] = None;
179 self.free_slots.push(slot);
180 self.count -= 1;
181 self.cached_tree = None; return true;
183 }
184 }
185
186 false
187 }
188
189 #[must_use]
191 pub fn get(&self, id: IntervalId) -> Option<&V> {
192 let slot = (id.0 & 0xFFFF_FFFF) as usize;
193 let generation = (id.0 >> 32) as u32;
194
195 self.entries.get(slot).and_then(|e| {
196 e.as_ref()
197 .filter(|entry| entry.generation == generation)
198 .map(|entry| &entry.value)
199 })
200 }
201
202 #[must_use]
204 pub fn get_interval(&self, id: IntervalId) -> Option<Interval<T>> {
205 let slot = (id.0 & 0xFFFF_FFFF) as usize;
206 let generation = (id.0 >> 32) as u32;
207
208 self.entries.get(slot).and_then(|e| {
209 e.as_ref()
210 .filter(|entry| entry.generation == generation)
211 .map(|entry| entry.interval)
212 })
213 }
214
215 fn ensure_tree(&mut self) {
217 if self.cached_tree.is_some() {
218 return;
219 }
220
221 let mut builder = IntervalTreeBuilder::with_capacity(self.count);
222
223 for (slot, entry) in self.entries.iter().enumerate() {
224 if let Some(e) = entry {
225 builder = builder.insert(e.interval, slot);
226 }
227 }
228
229 self.cached_tree = Some(builder.build());
230 }
231
232 pub fn query<R: Into<Interval<T>>>(
237 &mut self,
238 range: R,
239 ) -> impl Iterator<Item = (IntervalId, Interval<T>, &V)> {
240 self.ensure_tree();
241 let entries = &self.entries;
242 self.cached_tree
243 .as_ref()
244 .unwrap()
245 .query(range)
246 .filter_map(move |entry| {
247 let slot = *entry.value;
248 entries.get(slot).and_then(|e| {
249 e.as_ref().map(|ent| {
250 let id = IntervalId(((ent.generation as u64) << 32) | (slot as u64));
251 (id, ent.interval, &ent.value)
252 })
253 })
254 })
255 }
256
257 pub fn iter(&self) -> impl Iterator<Item = (IntervalId, Interval<T>, &V)> {
259 self.entries.iter().enumerate().filter_map(|(slot, entry)| {
260 entry.as_ref().map(|e| {
261 let id = IntervalId(((e.generation as u64) << 32) | (slot as u64));
262 (id, e.interval, &e.value)
263 })
264 })
265 }
266}
267
268#[cfg(test)]
269mod tests {
270 use super::*;
271
272 #[test]
273 fn insert_and_query() {
274 let mut set = IntervalSet::new();
275
276 let id1 = set.insert(0..10, "first");
277 let id2 = set.insert(5..15, "second");
278 let _id3 = set.insert(20..30, "third");
279
280 assert_eq!(set.len(), 3);
281
282 let results: Vec<_> = set.query(3..12).collect();
283 assert_eq!(results.len(), 2);
284
285 let ids: Vec<_> = results.iter().map(|(id, _, _)| *id).collect();
287 assert!(ids.contains(&id1) || ids.contains(&id2));
288
289 assert_eq!(set.get(id1), Some(&"first"));
290 assert_eq!(set.get(id2), Some(&"second"));
291 }
292
293 #[test]
294 fn remove_by_id() {
295 let mut set = IntervalSet::new();
296
297 let id1 = set.insert(0..10, "first");
298 let id2 = set.insert(5..15, "second");
299
300 assert!(set.remove(id1));
301 assert_eq!(set.len(), 1);
302 assert_eq!(set.get(id1), None);
303 assert_eq!(set.get(id2), Some(&"second"));
304
305 assert!(!set.remove(id1));
307 }
308
309 #[test]
310 fn slot_reuse() {
311 let mut set = IntervalSet::new();
312
313 let id1 = set.insert(0..10, "first");
314 set.remove(id1);
315
316 let id2 = set.insert(20..30, "second");
317
318 assert_eq!(set.get(id1), None);
320 assert_eq!(set.get(id2), Some(&"second"));
321 }
322
323 #[test]
324 fn iter_all() {
325 let mut set: IntervalSet<i32, &str> = IntervalSet::new();
326
327 set.insert(0..10, "a");
328 set.insert(5..15, "b");
329 set.insert(20..30, "c");
330
331 let items: Vec<_> = set.iter().collect();
332 assert_eq!(items.len(), 3);
333 }
334
335 #[test]
336 fn query_returns_ids() {
337 let mut set = IntervalSet::new();
338
339 let id1 = set.insert(0..10, "first");
340 let _id2 = set.insert(100..200, "second");
341
342 let results: Vec<_> = set.query(5..8).collect();
343 assert_eq!(results.len(), 1);
344
345 let (returned_id, interval, value) = &results[0];
346 assert_eq!(*returned_id, id1);
347 assert_eq!(interval.start, 0);
348 assert_eq!(interval.end, 10);
349 assert_eq!(*value, &"first");
350 }
351}