ranges_ext/
lib.rs

1#![no_std]
2
3#[cfg(feature = "alloc")]
4extern crate alloc;
5
6use core::{
7    cmp::{max, min},
8    fmt::Debug,
9    marker::PhantomData,
10    ops::{Deref, Range, RangeBounds},
11};
12
13pub type RangeSetHeapless<T, const C: usize = 128> = RangeSet<T, heapless::Vec<T, C>>;
14#[cfg(feature = "alloc")]
15pub type RangeSetAlloc<T> = RangeSet<T, alloc::vec::Vec<T>>;
16
17/// RangeSet 错误类型
18#[derive(Clone, Debug, PartialEq, Eq, thiserror::Error)]
19pub enum RangeError<T>
20where
21    T: RangeInfo,
22{
23    /// 容量不足错误
24    #[error("RangeSet capacity exceeded")]
25    Capacity,
26    /// 区间冲突错误:尝试覆盖不可覆盖的区间
27    #[error("Range conflict: new {new:?} conflicts with existing non-overwritable {existing:?}")]
28    Conflict {
29        /// 新添加的区间
30        new: T,
31        /// 已存在的冲突区间
32        existing: T,
33    },
34}
35
36pub trait RangeInfo: Debug + Clone + Sized {
37    type Kind: Debug + Eq + Clone;
38    type Type: Ord + Copy;
39    fn range(&self) -> Range<Self::Type>;
40    fn kind(&self) -> Self::Kind;
41    fn overwritable(&self) -> bool;
42    fn clone_with_range(&self, range: Range<Self::Type>) -> Self;
43}
44
45pub trait VecOp<T>: Default + Deref<Target = [T]> {
46    fn push_back(&mut self, item: T) -> Result<(), T>;
47    fn clear(&mut self);
48    fn insert(&mut self, index: usize, item: T) -> Result<(), T>;
49    fn remove(&mut self, index: usize) -> T;
50    fn drain<R>(&mut self, range: R) -> impl Iterator<Item = T>
51    where
52        R: RangeBounds<usize>;
53}
54
55/// 一个「区间集合」数据结构:维护一组**有序、互不重叠**的半开区间 `[start, end)`。
56///
57/// - 插入时会把重叠/相邻且 kind 相等的区间自动合并。
58/// - 删除一个区间时,会从集合里移除交集;必要时把已有区间拆成左右两段。
59///
60/// 约定:空区间(`start >= end`)会被忽略。
61#[derive(Clone, Debug)]
62pub struct RangeSet<T, V>
63where
64    T: RangeInfo,
65    V: VecOp<T>,
66{
67    elements: V,
68    _marker: PhantomData<T>,
69}
70
71impl<T, V> Default for RangeSet<T, V>
72where
73    T: RangeInfo,
74    V: VecOp<T>,
75{
76    fn default() -> Self {
77        Self::new(V::default())
78    }
79}
80
81impl<T, V> RangeSet<T, V>
82where
83    T: RangeInfo,
84    V: VecOp<T>,
85{
86    /// 创建空集合。
87    pub const fn new(v: V) -> Self {
88        Self {
89            elements: v,
90            _marker: PhantomData,
91        }
92    }
93
94    /// 检查两个区间是否有交集
95    #[inline]
96    fn ranges_overlap<T1: Ord + Copy>(r1: &Range<T1>, r2: &Range<T1>) -> bool {
97        !(r1.end <= r2.start || r1.start >= r2.end)
98    }
99
100    /// 分割区间:将原区间按分割范围分割成不重叠的部分
101    ///
102    /// 返回分割后的区间列表(最多2个区间)
103    fn split_range(elem: &T, split_range: &Range<T::Type>) -> [Option<T>; 2] {
104        let elem_range = elem.range();
105        let has_left = elem_range.start < split_range.start;
106        let has_right = elem_range.end > split_range.end;
107
108        match (has_left, has_right) {
109            (true, true) => {
110                // 分裂成两段
111                let left = elem_range.start..split_range.start;
112                let right = split_range.end..elem_range.end;
113                [
114                    if left.start < left.end {
115                        Some(elem.clone_with_range(left))
116                    } else {
117                        None
118                    },
119                    if right.start < right.end {
120                        Some(elem.clone_with_range(right))
121                    } else {
122                        None
123                    },
124                ]
125            }
126            (true, false) => {
127                // 只保留左半段
128                let left = elem_range.start..min(elem_range.end, split_range.start);
129                [
130                    if left.start < left.end {
131                        Some(elem.clone_with_range(left))
132                    } else {
133                        None
134                    },
135                    None,
136                ]
137            }
138            (false, true) => {
139                // 只保留右半段
140                let right = max(elem_range.start, split_range.end)..elem_range.end;
141                [
142                    None,
143                    if right.start < right.end {
144                        Some(elem.clone_with_range(right))
145                    } else {
146                        None
147                    },
148                ]
149            }
150            (false, false) => {
151                // 完全被覆盖,不保留
152                [None, None]
153            }
154        }
155    }
156
157    /// 返回内部区间的切片(已排序、已合并、互不重叠)。
158    #[inline]
159    pub fn as_slice(&self) -> &[T] {
160        &self.elements
161    }
162
163    /// 返回区间迭代器(零拷贝)。
164    #[inline]
165    pub fn iter(&self) -> impl Iterator<Item = &T> {
166        self.elements.iter()
167    }
168
169    #[inline]
170    pub fn is_empty(&self) -> bool {
171        self.elements.is_empty()
172    }
173
174    #[inline]
175    pub fn len(&self) -> usize {
176        self.elements.len()
177    }
178
179    pub fn clear(&mut self) {
180        self.elements.clear();
181    }
182
183    fn push_back(out: &mut V, elem: T) -> Result<(), RangeError<T>> {
184        out.push_back(elem).map_err(|_| RangeError::Capacity)
185    }
186
187    /// 添加一个区间;会把与其重叠或相邻且 kind 相等的区间自动合并。
188    /// 对于 kind 不同的重叠区间:
189    /// - 如果旧区间可覆盖,则用新区间覆盖交集部分
190    /// - 如果旧区间不可覆盖,则返回冲突错误
191    ///
192    /// # Errors
193    ///
194    /// - 如果容量不足,返回 `RangeSetError::Capacity`。
195    /// - 如果与不可覆盖的区间冲突,返回 `RangeSetError::Conflict`。
196    pub fn add(&mut self, new_info: T) -> Result<(), RangeError<T>> {
197        if new_info.range().start >= new_info.range().end {
198            return Ok(());
199        }
200
201        for elem in self.iter() {
202            // 如果没有交集,跳过
203            if !Self::ranges_overlap(&elem.range(), &new_info.range()) {
204                continue;
205            }
206
207            // 如果 kind 相同,跳过(稍后处理合并)
208            if elem.kind() == new_info.kind() {
209                continue;
210            }
211
212            // kind 不同且有交集:检查是否可覆盖
213            if !elem.overwritable() {
214                // 不可覆盖,返回冲突错误
215                return Err(RangeError::Conflict {
216                    new: new_info,
217                    existing: elem.clone(),
218                });
219            }
220        }
221
222        // 所有冲突都可以覆盖,现在开始处理
223        let mut out = V::default();
224
225        for elem in self.elements.drain(..) {
226            // 如果没有交集,保留
227            if !Self::ranges_overlap(&elem.range(), &new_info.range()) {
228                Self::push_back(&mut out, elem)?;
229                continue;
230            }
231
232            // 如果 kind 相同,稍后处理合并
233            if elem.kind() == new_info.kind() {
234                Self::push_back(&mut out, elem)?;
235                continue;
236            }
237
238            // kind 不同且有交集:分割原区间(已经确认可覆盖)
239            let split_parts = Self::split_range(&elem, &new_info.range());
240            for part in split_parts.iter().flatten() {
241                Self::push_back(&mut out, part.clone())?;
242            }
243        }
244
245        self.elements = out;
246
247        // 现在插入新区间,并与同 kind 的区间合并
248        if self.elements.is_empty() {
249            Self::push_back(&mut self.elements, new_info.clone())?;
250            return Ok(());
251        }
252
253        // 二分查找插入位置
254        let insert_at = self
255            .elements
256            .binary_search_by(|e| {
257                if e.range().start < new_info.range().start {
258                    core::cmp::Ordering::Less
259                } else {
260                    core::cmp::Ordering::Greater
261                }
262            })
263            .unwrap_or_else(|pos| pos);
264
265        let mut merged_range = new_info.range().clone();
266        let mut insert_at = insert_at;
267
268        // 向左合并:若左侧区间与 range 重叠/相邻且 kind 相等
269        while insert_at > 0 {
270            let left = &self.elements[insert_at - 1];
271            if left.range().end < merged_range.start || left.kind() != new_info.kind() {
272                break;
273            }
274            merged_range.start = min(merged_range.start, left.range().start);
275            merged_range.end = max(merged_range.end, left.range().end);
276            self.elements.remove(insert_at - 1);
277            insert_at -= 1;
278        }
279
280        // 向右合并:若右侧区间与 range 重叠/相邻且 kind 相等
281        while insert_at < self.elements.len() {
282            let right = &self.elements[insert_at];
283            if right.range().start > merged_range.end || right.kind() != new_info.kind() {
284                break;
285            }
286            merged_range.start = min(merged_range.start, right.range().start);
287            merged_range.end = max(merged_range.end, right.range().end);
288            self.elements.remove(insert_at);
289        }
290
291        self.elements
292            .insert(insert_at, new_info.clone_with_range(merged_range))
293            .map_err(|_| RangeError::Capacity)?;
294        Ok(())
295    }
296
297    /// 查询某个值是否落在任意一个区间中。
298    #[inline]
299    pub fn contains(&self, value: T::Type) -> bool {
300        // 二分查找:找到可能包含 value 的区间
301        self.elements
302            .binary_search_by(|e| {
303                if e.range().end <= value {
304                    core::cmp::Ordering::Less
305                } else if e.range().start > value {
306                    core::cmp::Ordering::Greater
307                } else {
308                    core::cmp::Ordering::Equal
309                }
310            })
311            .is_ok()
312    }
313
314    /// 删除一个区间:从集合中移除与其相交的部分。
315    ///
316    /// 若被删除区间位于某个已有区间内部,会导致该已有区间被拆分为两段(保留原有 kind)。
317    ///
318    /// # Errors
319    ///
320    /// 如果容量不足(删除操作导致区间分裂,新区间数量超过容量),返回 `RangeSetError::Capacity`。
321    pub fn remove(&mut self, range: Range<T::Type>) -> Result<(), RangeError<T>> {
322        if range.start >= range.end || self.elements.is_empty() {
323            return Ok(());
324        }
325
326        let mut out = V::default();
327        for elem in self.elements.drain(..) {
328            // 无交集
329            if !Self::ranges_overlap(&elem.range(), &range) {
330                Self::push_back(&mut out, elem)?;
331                continue;
332            }
333
334            // 有交集,需要分割
335            let split_parts = Self::split_range(&elem, &range);
336            for part in split_parts.iter().flatten() {
337                Self::push_back(&mut out, part.clone())?;
338            }
339        }
340        self.elements = out;
341        Ok(())
342    }
343
344    /// 批量添加多个区间。
345    ///
346    /// # Errors
347    ///
348    /// 如果容量不足,返回 `RangeSetError::Capacity`。
349    pub fn extend<I>(&mut self, ranges: I) -> Result<(), RangeError<T>>
350    where
351        I: IntoIterator<Item = T>,
352    {
353        for v in ranges {
354            self.add(v)?;
355        }
356        Ok(())
357    }
358}
359
360impl<T, const C: usize> VecOp<T> for heapless::Vec<T, C> {
361    fn push_back(&mut self, item: T) -> Result<(), T> {
362        self.push(item)
363    }
364
365    fn clear(&mut self) {
366        self.clear();
367    }
368
369    fn insert(&mut self, index: usize, item: T) -> Result<(), T> {
370        self.insert(index, item)
371    }
372
373    fn remove(&mut self, index: usize) -> T {
374        self.remove(index)
375    }
376
377    fn drain<R>(&mut self, range: R) -> impl Iterator<Item = T>
378    where
379        R: RangeBounds<usize>,
380    {
381        self.drain(range)
382    }
383}
384
385#[cfg(feature = "alloc")]
386impl<T> VecOp<T> for alloc::vec::Vec<T> {
387    fn push_back(&mut self, item: T) -> Result<(), T> {
388        self.push(item);
389        Ok(())
390    }
391
392    fn clear(&mut self) {
393        self.clear();
394    }
395
396    fn insert(&mut self, index: usize, item: T) -> Result<(), T> {
397        self.insert(index, item);
398        Ok(())
399    }
400
401    fn remove(&mut self, index: usize) -> T {
402        self.remove(index)
403    }
404
405    fn drain<R>(&mut self, range: R) -> impl Iterator<Item = T>
406    where
407        R: RangeBounds<usize>,
408    {
409        self.drain(range)
410    }
411}