ranges_ext/
lib.rs

1#![no_std]
2
3extern crate alloc;
4
5use alloc::vec::Vec;
6use core::cmp::{max, min};
7use core::ops::Range;
8
9#[cfg(test)]
10extern crate std;
11
12/// 原始区间与 metadata 的配对。
13#[derive(Clone, Debug, PartialEq, Eq)]
14pub struct OriginalRange<T, M> {
15    pub range: Range<T>,
16    pub meta: M,
17}
18
19/// 合并后的区间元素:包含合并后的 range 和所有原始区间列表。
20#[derive(Clone)]
21pub struct MergedRange<T, M> {
22    /// 合并后的区间范围
23    pub merged: Range<T>,
24    /// 该合并区间包含的所有原始区间及其 metadata
25    pub originals: Vec<OriginalRange<T, M>>,
26}
27
28impl<T, M> core::fmt::Debug for MergedRange<T, M>
29where
30    T: core::fmt::Debug,
31    M: core::fmt::Debug,
32{
33    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
34        f.debug_struct("MergedRange")
35            .field(
36                "merged",
37                &format_args!("[{:?}..{:?})", self.merged.start, self.merged.end),
38            )
39            .field("originals", &OriginalsList(&self.originals))
40            .finish()
41    }
42}
43
44/// 辅助结构,用于格式化原始区间列表
45struct OriginalsList<'a, T, M>(&'a [OriginalRange<T, M>]);
46
47impl<T, M> core::fmt::Debug for OriginalsList<'_, T, M>
48where
49    T: core::fmt::Debug,
50    M: core::fmt::Debug,
51{
52    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
53        let mut list = f.debug_list();
54        for orig in self.0 {
55            list.entry(&format_args!(
56                "[{:?}..{:?}) → {:?}",
57                orig.range.start, orig.range.end, orig.meta
58            ));
59        }
60        list.finish()
61    }
62}
63
64impl<T, M> core::fmt::Display for MergedRange<T, M>
65where
66    T: core::fmt::Display,
67{
68    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
69        write!(f, "[{}..{})", self.merged.start, self.merged.end)
70    }
71}
72
73impl<T, M> core::fmt::LowerHex for MergedRange<T, M>
74where
75    T: core::fmt::LowerHex,
76{
77    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
78        if f.alternate() {
79            write!(f, "[{:#x}..{:#x})", self.merged.start, self.merged.end)
80        } else {
81            write!(f, "[{:x}..{:x})", self.merged.start, self.merged.end)
82        }
83    }
84}
85
86impl<T, M> core::fmt::UpperHex for MergedRange<T, M>
87where
88    T: core::fmt::UpperHex,
89{
90    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
91        if f.alternate() {
92            write!(f, "[{:#X}..{:#X})", self.merged.start, self.merged.end)
93        } else {
94            write!(f, "[{:X}..{:X})", self.merged.start, self.merged.end)
95        }
96    }
97}
98
99impl<T, M> core::fmt::Binary for MergedRange<T, M>
100where
101    T: core::fmt::Binary,
102{
103    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
104        if f.alternate() {
105            write!(f, "[{:#b}..{:#b})", self.merged.start, self.merged.end)
106        } else {
107            write!(f, "[{:b}..{:b})", self.merged.start, self.merged.end)
108        }
109    }
110}
111
112impl<T, M> core::fmt::Octal for MergedRange<T, M>
113where
114    T: core::fmt::Octal,
115{
116    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
117        if f.alternate() {
118            write!(f, "[{:#o}..{:#o})", self.merged.start, self.merged.end)
119        } else {
120            write!(f, "[{:o}..{:o})", self.merged.start, self.merged.end)
121        }
122    }
123}
124
125/// 一个「区间集合」数据结构:维护一组**有序、互不重叠**的半开区间 `[start, end)`。
126///
127/// - 插入时会把重叠/相邻的区间自动合并。
128/// - 每个合并后的区间会保留其包含的所有原始区间及 metadata。
129/// - 删除一个区间时,会从集合里移除交集;必要时把已有区间拆成左右两段。
130/// - 删除时会同步移除完全被删除的原始区间。
131///
132/// 约定:空区间(`start >= end`)会被忽略。
133#[derive(Clone, Debug)]
134pub struct RangeSet<T, M = ()>
135where
136    T: Ord + Copy,
137{
138    elements: Vec<MergedRange<T, M>>,
139}
140
141impl<T, M> Default for RangeSet<T, M>
142where
143    T: Ord + Copy,
144{
145    fn default() -> Self {
146        Self {
147            elements: Vec::new(),
148        }
149    }
150}
151
152impl<T, M> RangeSet<T, M>
153where
154    T: Ord + Copy,
155{
156    /// 创建空集合。
157    pub fn new() -> Self {
158        Self::default()
159    }
160
161    /// 返回内部元素的切片(每个元素包含合并后的 range 和原始列表)。
162    #[inline]
163    pub fn elements(&self) -> &[MergedRange<T, M>] {
164        &self.elements
165    }
166
167    /// 返回归一化后的区间切片(仅 range,已排序、已合并、互不重叠)。
168    pub fn as_slice(&self) -> Vec<Range<T>> {
169        self.elements.iter().map(|e| e.merged.clone()).collect()
170    }
171
172    /// 返回归一化后的区间迭代器(零拷贝)。
173    #[inline]
174    pub fn iter(&self) -> impl Iterator<Item = &Range<T>> {
175        self.elements.iter().map(|e| &e.merged)
176    }
177
178    #[inline]
179    pub fn is_empty(&self) -> bool {
180        self.elements.is_empty()
181    }
182
183    #[inline]
184    pub fn len(&self) -> usize {
185        self.elements.len()
186    }
187
188    pub fn clear(&mut self) {
189        self.elements.clear();
190    }
191
192    /// 添加一个区间及其 metadata;会把与其重叠或相邻的区间合并。
193    pub fn add(&mut self, range: Range<T>, meta: M)
194    where
195        M: PartialEq,
196    {
197        if range.start >= range.end {
198            return;
199        }
200
201        let original = OriginalRange {
202            range: range.clone(),
203            meta,
204        };
205
206        if self.elements.is_empty() {
207            self.elements.push(MergedRange {
208                merged: range,
209                originals: alloc::vec![original],
210            });
211            return;
212        }
213
214        // 二分查找插入位置:第一个 start >= range.start 的位置
215        let insert_at = self
216            .elements
217            .binary_search_by(|e| {
218                if e.merged.start < range.start {
219                    core::cmp::Ordering::Less
220                } else {
221                    core::cmp::Ordering::Greater
222                }
223            })
224            .unwrap_or_else(|pos| pos);
225
226        let mut merged_range = range;
227        let mut merged_originals = alloc::vec![original];
228
229        // 向左合并:若左侧区间与 range 重叠/相邻(end >= start)
230        let mut insert_at = insert_at;
231        while insert_at > 0 {
232            let left = &self.elements[insert_at - 1];
233            if left.merged.end < merged_range.start {
234                break;
235            }
236            merged_range.start = min(merged_range.start, left.merged.start);
237            merged_range.end = max(merged_range.end, left.merged.end);
238            let left_elem = self.elements.remove(insert_at - 1);
239            merged_originals.reserve(left_elem.originals.len());
240            merged_originals.extend(left_elem.originals);
241            insert_at -= 1;
242        }
243
244        // 向右合并:若右侧区间与 range 重叠/相邻(start <= end)
245        while insert_at < self.elements.len() {
246            let right = &self.elements[insert_at];
247            if right.merged.start > merged_range.end {
248                break;
249            }
250            merged_range.start = min(merged_range.start, right.merged.start);
251            merged_range.end = max(merged_range.end, right.merged.end);
252            let right_elem = self.elements.remove(insert_at);
253            merged_originals.reserve(right_elem.originals.len());
254            merged_originals.extend(right_elem.originals);
255        }
256
257        // 合并原始区间:对于 metadata 相等且相邻/重叠的原始区间进行合并
258        merged_originals = Self::merge_originals(merged_originals);
259
260        self.elements.insert(
261            insert_at,
262            MergedRange {
263                merged: merged_range,
264                originals: merged_originals,
265            },
266        );
267    }
268
269    /// 合并原始区间列表:对于 metadata 相等且相邻/重叠的原始区间进行合并
270    fn merge_originals(mut originals: Vec<OriginalRange<T, M>>) -> Vec<OriginalRange<T, M>>
271    where
272        M: PartialEq,
273    {
274        if originals.len() <= 1 {
275            return originals;
276        }
277
278        // 按区间起点排序(使用不稳定排序提升性能)
279        originals.sort_unstable_by(|a, b| a.range.start.cmp(&b.range.start));
280
281        let mut result = Vec::with_capacity(originals.len());
282        let mut iter = originals.into_iter();
283        let mut current = iter.next().unwrap();
284
285        for next in iter {
286            // 如果 metadata 相等且区间相邻或重叠,则合并
287            if current.meta == next.meta && current.range.end >= next.range.start {
288                current.range.end = max(current.range.end, next.range.end);
289            } else {
290                result.push(current);
291                current = next;
292            }
293        }
294        result.push(current);
295
296        result
297    }
298
299    /// 查询某个值是否落在任意一个区间中。
300    #[inline]
301    pub fn contains(&self, value: T) -> bool {
302        // 二分查找:找到可能包含 value 的区间
303        self.elements
304            .binary_search_by(|e| {
305                if e.merged.end <= value {
306                    core::cmp::Ordering::Less
307                } else if e.merged.start > value {
308                    core::cmp::Ordering::Greater
309                } else {
310                    core::cmp::Ordering::Equal
311                }
312            })
313            .is_ok()
314    }
315
316    /// 删除一个区间:从集合中移除与其相交的部分。
317    ///
318    /// 若被删除区间位于某个已有区间内部,会导致该已有区间被拆分为两段。
319    /// 同时会移除完全被删除的原始区间。
320    pub fn remove_range(&mut self, range: Range<T>)
321    where
322        M: Clone,
323    {
324        if range.start >= range.end || self.elements.is_empty() {
325            return;
326        }
327
328        let mut out: Vec<MergedRange<T, M>> = Vec::with_capacity(self.elements.len() + 1);
329        for elem in self.elements.drain(..) {
330            // 无交集
331            if elem.merged.end <= range.start || elem.merged.start >= range.end {
332                out.push(elem);
333                continue;
334            }
335
336            // 过滤原始区间:移除完全被删除范围包含的原始区间
337            let filtered_originals: Vec<_> = elem
338                .originals
339                .into_iter()
340                .filter(|orig| {
341                    // 如果原始区间完全在删除范围内,则丢弃
342                    !(range.start <= orig.range.start && orig.range.end <= range.end)
343                })
344                .collect();
345
346            // 如果所有原始区间都被删除,跳过该元素
347            if filtered_originals.is_empty() {
348                continue;
349            }
350
351            let has_left = elem.merged.start < range.start;
352            let has_right = elem.merged.end > range.end;
353
354            match (has_left, has_right) {
355                (true, true) => {
356                    // 需要分裂成两段,左右两边都需要克隆
357                    let left = elem.merged.start..min(elem.merged.end, range.start);
358                    if left.start < left.end {
359                        out.push(MergedRange {
360                            merged: left,
361                            originals: filtered_originals.clone(),
362                        });
363                    }
364                    let right = max(elem.merged.start, range.end)..elem.merged.end;
365                    if right.start < right.end {
366                        out.push(MergedRange {
367                            merged: right,
368                            originals: filtered_originals,
369                        });
370                    }
371                }
372                (true, false) => {
373                    // 只有左半段
374                    let left = elem.merged.start..min(elem.merged.end, range.start);
375                    if left.start < left.end {
376                        out.push(MergedRange {
377                            merged: left,
378                            originals: filtered_originals,
379                        });
380                    }
381                }
382                (false, true) => {
383                    // 只有右半段
384                    let right = max(elem.merged.start, range.end)..elem.merged.end;
385                    if right.start < right.end {
386                        out.push(MergedRange {
387                            merged: right,
388                            originals: filtered_originals,
389                        });
390                    }
391                }
392                (false, false) => {
393                    // 不应该到达这里,因为上面已经检查了无交集的情况
394                }
395            }
396        }
397        self.elements = out;
398    }
399}
400
401impl<T> RangeSet<T, ()>
402where
403    T: Ord + Copy,
404{
405    /// 添加一个区间(不带 metadata)。
406    pub fn add_range(&mut self, range: Range<T>) {
407        self.add(range, ());
408    }
409
410    /// 批量添加多个区间(不带 metadata)。
411    pub fn extend<I>(&mut self, ranges: I)
412    where
413        I: IntoIterator<Item = Range<T>>,
414    {
415        for r in ranges {
416            self.add_range(r);
417        }
418    }
419}