Skip to main content

xi_rope/
spans.rs

1// Copyright 2016 The xi-editor Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! A module for representing spans (in an interval tree), useful for rich text
16//! annotations. It is parameterized over a data type, so can be used for
17//! storing different annotations.
18
19use std::fmt;
20use std::marker::PhantomData;
21use std::mem;
22
23use crate::delta::{Delta, DeltaElement, Transformer};
24use crate::interval::{Interval, IntervalBounds};
25use crate::tree::{Cursor, Leaf, Node, NodeInfo, TreeBuilder};
26
27const MIN_LEAF: usize = 32;
28const MAX_LEAF: usize = 64;
29
30pub type Spans<T> = Node<SpansInfo<T>>;
31
32#[derive(Clone)]
33pub struct Span<T: Clone> {
34    iv: Interval,
35    data: T,
36}
37
38#[derive(Clone)]
39pub struct SpansLeaf<T: Clone> {
40    len: usize, // measured in base units
41    spans: Vec<Span<T>>,
42}
43
44// It would be preferable to derive Default.
45// This would however require T to implement Default due to an issue in Rust.
46// See: https://github.com/rust-lang/rust/issues/26925
47impl<T: Clone> Default for SpansLeaf<T> {
48    fn default() -> Self {
49        SpansLeaf { len: 0, spans: vec![] }
50    }
51}
52
53#[derive(Clone)]
54pub struct SpansInfo<T> {
55    n_spans: usize,
56    iv: Interval,
57    phantom: PhantomData<T>,
58}
59
60impl<T: Clone> Leaf for SpansLeaf<T> {
61    fn len(&self) -> usize {
62        self.len
63    }
64
65    fn is_ok_child(&self) -> bool {
66        self.spans.len() >= MIN_LEAF
67    }
68
69    fn push_maybe_split(&mut self, other: &Self, iv: Interval) -> Option<Self> {
70        let iv_start = iv.start();
71        for span in &other.spans {
72            let span_iv = span.iv.intersect(iv).translate_neg(iv_start).translate(self.len);
73            if !span_iv.is_empty() {
74                self.spans.push(Span { iv: span_iv, data: span.data.clone() });
75            }
76        }
77        self.len += iv.size();
78
79        if self.spans.len() <= MAX_LEAF {
80            None
81        } else {
82            let splitpoint = self.spans.len() / 2; // number of spans
83            let splitpoint_units = self.spans[splitpoint].iv.start();
84            let mut new = self.spans.split_off(splitpoint);
85            for span in &mut new {
86                span.iv = span.iv.translate_neg(splitpoint_units);
87            }
88            let new_len = self.len - splitpoint_units;
89            self.len = splitpoint_units;
90            Some(SpansLeaf { len: new_len, spans: new })
91        }
92    }
93}
94
95impl<T: Clone> NodeInfo for SpansInfo<T> {
96    type L = SpansLeaf<T>;
97
98    fn accumulate(&mut self, other: &Self) {
99        self.n_spans += other.n_spans;
100        self.iv = self.iv.union(other.iv);
101    }
102
103    fn compute_info(l: &SpansLeaf<T>) -> Self {
104        let mut iv = Interval::new(0, 0); // should be Interval::default?
105        for span in &l.spans {
106            iv = iv.union(span.iv);
107        }
108        SpansInfo { n_spans: l.spans.len(), iv, phantom: PhantomData }
109    }
110}
111
112pub struct SpansBuilder<T: Clone> {
113    b: TreeBuilder<SpansInfo<T>>,
114    leaf: SpansLeaf<T>,
115    len: usize,
116    total_len: usize,
117}
118
119impl<T: Clone> SpansBuilder<T> {
120    pub fn new(total_len: usize) -> Self {
121        SpansBuilder { b: TreeBuilder::new(), leaf: SpansLeaf::default(), len: 0, total_len }
122    }
123
124    // Precondition: spans must be added in nondecreasing start order.
125    // Maybe take Span struct instead of separate iv, data args?
126    pub fn add_span<IV: IntervalBounds>(&mut self, iv: IV, data: T) {
127        let iv = iv.into_interval(self.total_len);
128        if self.leaf.spans.len() == MAX_LEAF {
129            let mut leaf = mem::replace(&mut self.leaf, SpansLeaf::default());
130            leaf.len = iv.start() - self.len;
131            self.len = iv.start();
132            self.b.push(Node::from_leaf(leaf));
133        }
134        self.leaf.spans.push(Span { iv: iv.translate_neg(self.len), data })
135    }
136
137    // Would make slightly more implementation sense to take total_len as an argument
138    // here, but that's not quite the usual builder pattern.
139    pub fn build(mut self) -> Spans<T> {
140        self.leaf.len = self.total_len - self.len;
141        self.b.push(Node::from_leaf(self.leaf));
142        self.b.build()
143    }
144}
145
146pub struct SpanIter<'a, T: 'a + Clone> {
147    cursor: Cursor<'a, SpansInfo<T>>,
148    ix: usize,
149}
150
151impl<T: Clone> Spans<T> {
152    /// Perform operational transformation on a spans object intended to be edited into
153    /// a sequence at the given offset.
154
155    // Note: this implementation is not efficient for very large Spans objects, as it
156    // traverses all spans linearly. A more sophisticated approach would be to traverse
157    // the tree, and only delve into subtrees that are transformed.
158    pub fn transform<N: NodeInfo>(
159        &self,
160        base_start: usize,
161        base_end: usize,
162        xform: &mut Transformer<N>,
163    ) -> Self {
164        // TODO: maybe should take base as an Interval and figure out "after" from that
165        let new_start = xform.transform(base_start, false);
166        let new_end = xform.transform(base_end, true);
167        let mut builder = SpansBuilder::new(new_end - new_start);
168        for (iv, data) in self.iter() {
169            let start = xform.transform(iv.start() + base_start, false) - new_start;
170            let end = xform.transform(iv.end() + base_start, false) - new_start;
171            if start < end {
172                let iv = Interval::new(start, end);
173                // TODO: could imagine using a move iterator and avoiding clone, but it's not easy.
174                builder.add_span(iv, data.clone());
175            }
176        }
177        builder.build()
178    }
179
180    /// Creates a new Spans instance by merging spans from `other` with `self`,
181    /// using a closure to transform values.
182    ///
183    /// New spans are created from non-overlapping regions of existing spans,
184    /// and by combining overlapping regions into new spans. In all cases,
185    /// new values are generated by calling a closure that transforms the
186    /// value of the existing span or spans.
187    ///
188    /// # Panics
189    ///
190    /// Panics if `self` and `other` have different lengths.
191    ///
192    pub fn merge<F, O>(&self, other: &Self, mut f: F) -> Spans<O>
193    where
194        F: FnMut(&T, Option<&T>) -> O,
195        O: Clone,
196    {
197        //TODO: confirm that this is sensible behaviour
198        assert_eq!(self.len(), other.len());
199        let mut sb = SpansBuilder::new(self.len());
200
201        // red/blue is just a better name than one/two or me/other
202        let mut iter_red = self.iter();
203        let mut iter_blue = other.iter();
204
205        let mut next_red = iter_red.next();
206        let mut next_blue = iter_blue.next();
207
208        loop {
209            // exit conditions:
210            if next_red.is_none() && next_blue.is_none() {
211                // all merged.
212                break;
213            } else if next_red.is_none() != next_blue.is_none() {
214                // one side is exhausted; append remaining items from other side.
215                let iter = if next_red.is_some() { iter_red } else { iter_blue };
216                // add this item
217                let (iv, val) = next_red.or(next_blue).unwrap();
218                sb.add_span(iv, f(val, None));
219
220                for (iv, val) in iter {
221                    sb.add_span(iv, f(val, None))
222                }
223                break;
224            }
225
226            // body:
227            let (mut red_iv, red_val) = next_red.unwrap();
228            let (mut blue_iv, blue_val) = next_blue.unwrap();
229
230            if red_iv.intersect(blue_iv).is_empty() {
231                // spans do not overlap. Add the leading span & advance that iter.
232                if red_iv.is_before(blue_iv.start()) {
233                    sb.add_span(red_iv, f(red_val, None));
234                    next_red = iter_red.next();
235                } else {
236                    sb.add_span(blue_iv, f(blue_val, None));
237                    next_blue = iter_blue.next();
238                }
239                continue;
240            }
241            assert!(!red_iv.intersect(blue_iv).is_empty());
242
243            // if these two spans do not share a start point, create a new span from
244            // the prefix of the leading span.
245            if red_iv.start() < blue_iv.start() {
246                let iv = red_iv.prefix(blue_iv);
247                sb.add_span(iv, f(red_val, None));
248                red_iv = red_iv.suffix(iv);
249            } else if blue_iv.start() < red_iv.start() {
250                let iv = blue_iv.prefix(red_iv);
251                sb.add_span(iv, f(blue_val, None));
252                blue_iv = blue_iv.suffix(iv);
253            }
254
255            assert!(red_iv.start() == blue_iv.start());
256            // create a new span by merging the overlapping regions.
257            let iv = red_iv.intersect(blue_iv);
258            assert!(!iv.is_empty());
259            sb.add_span(iv, f(red_val, Some(blue_val)));
260
261            // if an old span was consumed by this new span, advance
262            // else reuse remaining span (set next_red/blue) for the next loop iteration
263            red_iv = red_iv.suffix(iv);
264            blue_iv = blue_iv.suffix(iv);
265            assert!(red_iv.is_empty() || blue_iv.is_empty());
266
267            if red_iv.is_empty() {
268                next_red = iter_red.next();
269            } else {
270                next_red = Some((red_iv, red_val));
271            }
272
273            if blue_iv.is_empty() {
274                next_blue = iter_blue.next();
275            } else {
276                next_blue = Some((blue_iv, blue_val));
277            }
278        }
279        sb.build()
280    }
281
282    // possible future: an iterator that takes an interval, so results are the same as
283    // taking a subseq on the spans object. Would require specialized Cursor.
284    pub fn iter(&self) -> SpanIter<T> {
285        SpanIter { cursor: Cursor::new(self, 0), ix: 0 }
286    }
287
288    /// Applies a generic delta to `self`, inserting empty spans for any
289    /// added regions.
290    ///
291    /// This is intended to be used to keep spans up to date with a `Rope`
292    /// as edits occur.
293    pub fn apply_shape<M: NodeInfo>(&mut self, delta: &Delta<M>) {
294        let mut b = TreeBuilder::new();
295        for elem in &delta.els {
296            match *elem {
297                DeltaElement::Copy(beg, end) => b.push(self.subseq(Interval::new(beg, end))),
298                DeltaElement::Insert(ref n) => b.push(SpansBuilder::new(n.len()).build()),
299            }
300        }
301        *self = b.build();
302    }
303
304    // FIXME: Instead of iterating through all spans every time, another option would be to go
305    // leaf-by-leaf, and check each leaf for whether or not it has any items in the interval;
306    // if they don't we keep them unchanged, otherwise we do this operation, but only within the leaf.
307    //
308    /// Deletes all spans that intersect with `interval`.
309    pub fn delete_intersecting(&mut self, interval: Interval) {
310        let mut builder = SpansBuilder::new(self.len());
311        for (iv, data) in self.iter() {
312            // check if spans overlaps with interval
313            if iv.intersect(interval).is_empty() {
314                // keep the ones that are not overlapping
315                builder.add_span(iv, data.clone());
316            }
317        }
318        *self = builder.build();
319    }
320}
321
322impl<T: Clone + fmt::Debug> fmt::Debug for Spans<T> {
323    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
324        let strs =
325            self.iter().map(|(iv, val)| format!("{}: {:?}", iv, val)).collect::<Vec<String>>();
326        write!(f, "len: {}\nspans:\n\t{}", self.len(), &strs.join("\n\t"))
327    }
328}
329
330impl<'a, T: Clone> Iterator for SpanIter<'a, T> {
331    type Item = (Interval, &'a T);
332
333    fn next(&mut self) -> Option<(Interval, &'a T)> {
334        if let Some((leaf, start_pos)) = self.cursor.get_leaf() {
335            if leaf.spans.is_empty() {
336                return None;
337            }
338            let leaf_start = self.cursor.pos() - start_pos;
339            let span = &leaf.spans[self.ix];
340            self.ix += 1;
341            if self.ix == leaf.spans.len() {
342                let _ = self.cursor.next_leaf();
343                self.ix = 0;
344            }
345            return Some((span.iv.translate(leaf_start), &span.data));
346        }
347        None
348    }
349}
350
351#[cfg(test)]
352mod tests {
353    use super::*;
354    #[test]
355
356    fn test_merge() {
357        // merging 1 1 1 1 1 1 1 1 1 16
358        // with    2 2 4 4     8 8
359        // ==      3 3 5 5 1 1 9 9 1 16
360        let mut sb = SpansBuilder::new(10);
361        sb.add_span(Interval::new(0, 9), 1u32);
362        sb.add_span(Interval::new(9, 10), 16);
363        let red = sb.build();
364
365        let mut sb = SpansBuilder::new(10);
366        sb.add_span(Interval::new(0, 2), 2);
367        sb.add_span(Interval::new(2, 4), 4);
368        sb.add_span(Interval::new(6, 8), 8);
369        let blue = sb.build();
370        let merged = red.merge(&blue, |r, b| b.map(|b| b + r).unwrap_or(*r));
371
372        let mut merged_iter = merged.iter();
373        let (iv, val) = merged_iter.next().unwrap();
374        assert_eq!(iv, Interval::new(0, 2));
375        assert_eq!(*val, 3);
376
377        let (iv, val) = merged_iter.next().unwrap();
378        assert_eq!(iv, Interval::new(2, 4));
379        assert_eq!(*val, 5);
380
381        let (iv, val) = merged_iter.next().unwrap();
382        assert_eq!(iv, Interval::new(4, 6));
383        assert_eq!(*val, 1);
384
385        let (iv, val) = merged_iter.next().unwrap();
386        assert_eq!(iv, Interval::new(6, 8));
387        assert_eq!(*val, 9);
388
389        let (iv, val) = merged_iter.next().unwrap();
390        assert_eq!(iv, Interval::new(8, 9));
391        assert_eq!(*val, 1);
392
393        let (iv, val) = merged_iter.next().unwrap();
394        assert_eq!(iv, Interval::new(9, 10));
395        assert_eq!(*val, 16);
396
397        assert!(merged_iter.next().is_none());
398    }
399
400    #[test]
401    fn test_merge_2() {
402        // 1 1 1   4 4
403        //   2 2 2 2     8 9
404        let mut sb = SpansBuilder::new(9);
405        sb.add_span(Interval::new(0, 3), 1);
406        sb.add_span(Interval::new(4, 6), 4);
407        let blue = sb.build();
408
409        let mut sb = SpansBuilder::new(9);
410        sb.add_span(Interval::new(1, 5), 2);
411        sb.add_span(Interval::new(7, 8), 8);
412        sb.add_span(Interval::new(8, 9), 9);
413        let red = sb.build();
414
415        let merged = red.merge(&blue, |r, b| b.map(|b| b + r).unwrap_or(*r));
416
417        let mut merged_iter = merged.iter();
418        let (iv, val) = merged_iter.next().unwrap();
419        assert_eq!(iv, Interval::new(0, 1));
420        assert_eq!(*val, 1);
421
422        let (iv, val) = merged_iter.next().unwrap();
423        assert_eq!(iv, Interval::new(1, 3));
424        assert_eq!(*val, 3);
425
426        let (iv, val) = merged_iter.next().unwrap();
427        assert_eq!(iv, Interval::new(3, 4));
428        assert_eq!(*val, 2);
429
430        let (iv, val) = merged_iter.next().unwrap();
431        assert_eq!(iv, Interval::new(4, 5));
432        assert_eq!(*val, 6);
433
434        let (iv, val) = merged_iter.next().unwrap();
435        assert_eq!(iv, Interval::new(5, 6));
436        assert_eq!(*val, 4);
437
438        let (iv, val) = merged_iter.next().unwrap();
439        assert_eq!(iv, Interval::new(7, 8));
440        assert_eq!(*val, 8);
441
442        let (iv, val) = merged_iter.next().unwrap();
443        assert_eq!(iv, Interval::new(8, 9));
444        assert_eq!(*val, 9);
445
446        assert!(merged_iter.next().is_none());
447    }
448
449    #[test]
450    fn test_delete_intersecting() {
451        let mut sb = SpansBuilder::new(11);
452        sb.add_span(Interval::new(1, 2), 2);
453        sb.add_span(Interval::new(3, 5), 8);
454        sb.add_span(Interval::new(6, 8), 9);
455        sb.add_span(Interval::new(9, 10), 1);
456        sb.add_span(Interval::new(10, 11), 1);
457        let mut spans = sb.build();
458
459        spans.delete_intersecting(Interval::new(4, 7));
460        let mut deleted_iter = spans.iter();
461
462        let (iv, val) = deleted_iter.next().unwrap();
463        assert_eq!(iv, Interval::new(1, 2));
464        assert_eq!(*val, 2);
465
466        let (iv, val) = deleted_iter.next().unwrap();
467        assert_eq!(iv, Interval::new(9, 10));
468        assert_eq!(*val, 1);
469    }
470
471    #[test]
472    fn delete_intersecting_big_at_start() {
473        let mut sb = SpansBuilder::new(10);
474        sb.add_span(0..10, 0);
475
476        let mut spans = sb.build();
477        assert_eq!(spans.iter().count(), 1);
478
479        spans.delete_intersecting(Interval::new(1, 2));
480        assert_eq!(spans.iter().count(), 0);
481    }
482
483    #[test]
484    fn delete_intersecting_big_and_small() {
485        let mut sb = SpansBuilder::new(10);
486        sb.add_span(0..10, 0);
487        sb.add_span(3..10, 1);
488
489        let mut spans = sb.build();
490        assert_eq!(spans.iter().count(), 2);
491
492        spans.delete_intersecting(Interval::new(1, 2));
493        assert_eq!(spans.iter().count(), 1);
494    }
495
496    #[test]
497    fn delete_intersecting_empty() {
498        let mut sb = SpansBuilder::new(10);
499        sb.add_span(0..3, 0);
500        sb.add_span(9..10, 1);
501
502        eprintln!("--");
503        let mut spans = sb.build();
504        assert_eq!(spans.iter().count(), 2);
505
506        spans.delete_intersecting(Interval::new(5, 7));
507        assert_eq!(spans.iter().count(), 2);
508    }
509}