ranges_ext/
lib.rs

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