ranges_ext/
lib.rs

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