Skip to main content

xi_rope/
tree.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 general b-tree structure suitable for ropes and the like.
16
17use std::cmp::min;
18use std::marker::PhantomData;
19use std::sync::Arc;
20
21use crate::interval::{Interval, IntervalBounds};
22
23const MIN_CHILDREN: usize = 4;
24const MAX_CHILDREN: usize = 8;
25
26pub trait NodeInfo: Clone {
27    /// The type of the leaf.
28    ///
29    /// A given `NodeInfo` is for exactly one type of leaf. That is why
30    /// the leaf type is an associated type rather than a type parameter.
31    type L: Leaf;
32
33    /// An operator that combines info from two subtrees. It is intended
34    /// (but not strictly enforced) that this operator be associative and
35    /// obey an identity property. In mathematical terms, the accumulate
36    /// method is the operation of a monoid.
37    fn accumulate(&mut self, other: &Self);
38
39    /// A mapping from a leaf into the info type. It is intended (but
40    /// not strictly enforced) that applying the accumulate method to
41    /// the info derived from two leaves gives the same result as
42    /// deriving the info from the concatenation of the two leaves. In
43    /// mathematical terms, the compute_info method is a monoid
44    /// homomorphism.
45    fn compute_info(_: &Self::L) -> Self;
46
47    /// The identity of the monoid. Need not be implemented because it
48    /// can be computed from the leaf default.
49    ///
50    /// This is here to demonstrate that this is a monoid.
51    fn identity() -> Self {
52        Self::compute_info(&Self::L::default())
53    }
54
55    /// The interval covered by the first `len` base units of this node. The
56    /// default impl is sufficient for most types, but interval trees may need
57    /// to override it.
58    fn interval(&self, len: usize) -> Interval {
59        Interval::new(0, len)
60    }
61}
62
63/// A trait indicating the default metric of a NodeInfo.
64///
65/// Adds quality of life functions to
66/// Node\<N\>, where N is a DefaultMetric.
67/// For example, [Node\<DefaultMetric\>.count](struct.Node.html#method.count).
68pub trait DefaultMetric: NodeInfo {
69    type DefaultMetric: Metric<Self>;
70}
71
72/// A trait for the leaves of trees of type [Node](struct.Node.html).
73///
74/// Two leafs can be concatenated using `push_maybe_split`.
75pub trait Leaf: Sized + Clone + Default {
76    /// Measurement of leaf in base units.
77    /// A 'base unit' refers to the smallest discrete unit
78    /// by which a given concrete type can be indexed.
79    /// Concretely, for Rust's String type the base unit is the byte.
80    fn len(&self) -> usize;
81
82    /// Generally a minimum size requirement for leaves.
83    fn is_ok_child(&self) -> bool;
84
85    /// Combine the part `other` denoted by the `Interval` `iv` into `self`,
86    /// optionly splitting off a new `Leaf` if `self` would have become too big.
87    /// Returns either `None` if no splitting was needed, or `Some(rest)` if
88    /// `rest` was split off.
89    ///
90    /// Interval is in "base units".  Generally implements a maximum size.
91    ///
92    /// # Invariants:
93    /// - If one or the other input is empty, then no split.
94    /// - If either input satisfies `is_ok_child`, then, on return, `self`
95    ///   satisfies this, as does the optional split.
96    fn push_maybe_split(&mut self, other: &Self, iv: Interval) -> Option<Self>;
97
98    /// Same meaning as push_maybe_split starting from an empty
99    /// leaf, but maybe can be implemented more efficiently?
100    ///
101    // TODO: remove if it doesn't pull its weight
102    fn subseq(&self, iv: Interval) -> Self {
103        let mut result = Self::default();
104        if result.push_maybe_split(self, iv).is_some() {
105            panic!("unexpected split");
106        }
107        result
108    }
109}
110
111/// A b-tree node storing leaves at the bottom, and with info
112/// retained at each node. It is implemented with atomic reference counting
113/// and copy-on-write semantics, so an immutable clone is a very cheap
114/// operation, and nodes can be shared across threads. Even so, it is
115/// designed to be updated in place, with efficiency similar to a mutable
116/// data structure, using uniqueness of reference count to detect when
117/// this operation is safe.
118///
119/// When the leaf is a string, this is a rope data structure (a persistent
120/// rope in functional programming jargon). However, it is not restricted
121/// to strings, and it is expected to be the basis for a number of data
122/// structures useful for text processing.
123#[derive(Clone)]
124pub struct Node<N: NodeInfo>(Arc<NodeBody<N>>);
125
126#[derive(Clone)]
127struct NodeBody<N: NodeInfo> {
128    height: usize,
129    len: usize,
130    info: N,
131    val: NodeVal<N>,
132}
133
134#[derive(Clone)]
135enum NodeVal<N: NodeInfo> {
136    Leaf(N::L),
137    Internal(Vec<Node<N>>),
138}
139
140// also consider making Metric a newtype for usize, so type system can
141// help separate metrics
142
143/// A trait for quickly processing attributes of a
144/// [NodeInfo](struct.NodeInfo.html).
145///
146/// For the conceptual background see the
147/// [blog post, Rope science, part 2: metrics](https://github.com/google/xi-editor/blob/master/docs/docs/rope_science_02.md).
148pub trait Metric<N: NodeInfo> {
149    /// Return the size of the
150    /// [NodeInfo::L](trait.NodeInfo.html#associatedtype.L), as measured by this
151    /// metric.
152    ///
153    /// The usize argument is the total size/length of the node, in base units.
154    ///
155    /// # Examples
156    /// For the [LinesMetric](../rope/struct.LinesMetric.html), this gives the number of
157    /// lines in string contained in the leaf. For the
158    /// [BaseMetric](../rope/struct.BaseMetric.html), this gives the size of the string
159    /// in uft8 code units, that is, bytes.
160    ///
161    fn measure(info: &N, len: usize) -> usize;
162
163    /// Returns the smallest offset, in base units, for an offset in measured units.
164    ///
165    /// # Invariants:
166    ///
167    /// - `from_base_units(to_base_units(x)) == x` is True for valid `x`
168    fn to_base_units(l: &N::L, in_measured_units: usize) -> usize;
169
170    /// Returns the smallest offset in measured units corresponding to an offset in base units.
171    ///
172    /// # Invariants:
173    ///
174    /// - `from_base_units(to_base_units(x)) == x` is True for valid `x`
175    fn from_base_units(l: &N::L, in_base_units: usize) -> usize;
176
177    /// Return whether the offset in base units is a boundary of this metric.
178    /// If a boundary is at end of a leaf then this method must return true.
179    /// However, a boundary at the beginning of a leaf is optional
180    /// (the previous leaf will be queried).
181    fn is_boundary(l: &N::L, offset: usize) -> bool;
182
183    /// Returns the index of the boundary directly preceding offset,
184    /// or None if no such boundary exists. Input and result are in base units.
185    fn prev(l: &N::L, offset: usize) -> Option<usize>;
186
187    /// Returns the index of the first boundary for which index > offset,
188    /// or None if no such boundary exists. Input and result are in base units.
189    fn next(l: &N::L, offset: usize) -> Option<usize>;
190
191    /// Returns true if the measured units in this metric can span multiple
192    /// leaves.  As an example, in a metric that measures lines in a rope, a
193    /// line may start in one leaf and end in another; however in a metric
194    /// measuring bytes, storage of a single byte cannot extend across leaves.
195    fn can_fragment() -> bool;
196}
197
198impl<N: NodeInfo> Node<N> {
199    pub fn from_leaf(l: N::L) -> Node<N> {
200        let len = l.len();
201        let info = N::compute_info(&l);
202        Node(Arc::new(NodeBody { height: 0, len, info, val: NodeVal::Leaf(l) }))
203    }
204
205    fn from_nodes(nodes: Vec<Node<N>>) -> Node<N> {
206        let height = nodes[0].0.height + 1;
207        let mut len = nodes[0].0.len;
208        let mut info = nodes[0].0.info.clone();
209        for child in &nodes[1..] {
210            len += child.0.len;
211            info.accumulate(&child.0.info);
212        }
213        Node(Arc::new(NodeBody { height, len, info, val: NodeVal::Internal(nodes) }))
214    }
215
216    pub fn len(&self) -> usize {
217        self.0.len
218    }
219
220    pub fn is_empty(&self) -> bool {
221        self.len() == 0
222    }
223
224    fn height(&self) -> usize {
225        self.0.height
226    }
227
228    fn is_leaf(&self) -> bool {
229        self.0.height == 0
230    }
231
232    fn interval(&self) -> Interval {
233        self.0.info.interval(self.0.len)
234    }
235
236    fn get_children(&self) -> &[Node<N>] {
237        if let NodeVal::Internal(ref v) = self.0.val {
238            v
239        } else {
240            panic!("get_children called on leaf node");
241        }
242    }
243
244    fn get_leaf(&self) -> &N::L {
245        if let NodeVal::Leaf(ref l) = self.0.val {
246            l
247        } else {
248            panic!("get_leaf called on internal node");
249        }
250    }
251
252    fn is_ok_child(&self) -> bool {
253        match self.0.val {
254            NodeVal::Leaf(ref l) => l.is_ok_child(),
255            NodeVal::Internal(ref nodes) => (nodes.len() >= MIN_CHILDREN),
256        }
257    }
258
259    fn merge_nodes(children1: &[Node<N>], children2: &[Node<N>]) -> Node<N> {
260        let n_children = children1.len() + children2.len();
261        if n_children <= MAX_CHILDREN {
262            Node::from_nodes([children1, children2].concat())
263        } else {
264            // Note: this leans left. Splitting at midpoint is also an option
265            let splitpoint = min(MAX_CHILDREN, n_children - MIN_CHILDREN);
266            let mut iter = children1.iter().chain(children2.iter()).cloned();
267            let left = iter.by_ref().take(splitpoint).collect();
268            let right = iter.collect();
269            let parent_nodes = vec![Node::from_nodes(left), Node::from_nodes(right)];
270            Node::from_nodes(parent_nodes)
271        }
272    }
273
274    fn merge_leaves(mut rope1: Node<N>, rope2: Node<N>) -> Node<N> {
275        debug_assert!(rope1.is_leaf() && rope2.is_leaf());
276
277        let both_ok = rope1.get_leaf().is_ok_child() && rope2.get_leaf().is_ok_child();
278        if both_ok {
279            return Node::from_nodes(vec![rope1, rope2]);
280        }
281        match {
282            let node1 = Arc::make_mut(&mut rope1.0);
283            let leaf2 = rope2.get_leaf();
284            if let NodeVal::Leaf(ref mut leaf1) = node1.val {
285                let leaf2_iv = Interval::new(0, leaf2.len());
286                let new = leaf1.push_maybe_split(leaf2, leaf2_iv);
287                node1.len = leaf1.len();
288                node1.info = N::compute_info(leaf1);
289                new
290            } else {
291                panic!("merge_leaves called on non-leaf");
292            }
293        } {
294            Some(new) => Node::from_nodes(vec![rope1, Node::from_leaf(new)]),
295            None => rope1,
296        }
297    }
298
299    pub fn concat(rope1: Node<N>, rope2: Node<N>) -> Node<N> {
300        use std::cmp::Ordering;
301
302        let h1 = rope1.height();
303        let h2 = rope2.height();
304
305        match h1.cmp(&h2) {
306            Ordering::Less => {
307                let children2 = rope2.get_children();
308                if h1 == h2 - 1 && rope1.is_ok_child() {
309                    return Node::merge_nodes(&[rope1], children2);
310                }
311                let newrope = Node::concat(rope1, children2[0].clone());
312                if newrope.height() == h2 - 1 {
313                    Node::merge_nodes(&[newrope], &children2[1..])
314                } else {
315                    Node::merge_nodes(newrope.get_children(), &children2[1..])
316                }
317            }
318            Ordering::Equal => {
319                if rope1.is_ok_child() && rope2.is_ok_child() {
320                    return Node::from_nodes(vec![rope1, rope2]);
321                }
322                if h1 == 0 {
323                    return Node::merge_leaves(rope1, rope2);
324                }
325                Node::merge_nodes(rope1.get_children(), rope2.get_children())
326            }
327            Ordering::Greater => {
328                let children1 = rope1.get_children();
329                if h2 == h1 - 1 && rope2.is_ok_child() {
330                    return Node::merge_nodes(children1, &[rope2]);
331                }
332                let lastix = children1.len() - 1;
333                let newrope = Node::concat(children1[lastix].clone(), rope2);
334                if newrope.height() == h1 - 1 {
335                    Node::merge_nodes(&children1[..lastix], &[newrope])
336                } else {
337                    Node::merge_nodes(&children1[..lastix], newrope.get_children())
338                }
339            }
340        }
341    }
342
343    pub fn measure<M: Metric<N>>(&self) -> usize {
344        M::measure(&self.0.info, self.0.len)
345    }
346
347    pub(crate) fn push_subseq(&self, b: &mut TreeBuilder<N>, iv: Interval) {
348        if iv.is_empty() {
349            return;
350        }
351        if iv == self.interval() {
352            b.push(self.clone());
353            return;
354        }
355        match self.0.val {
356            NodeVal::Leaf(ref l) => {
357                b.push_leaf_slice(l, iv);
358            }
359            NodeVal::Internal(ref v) => {
360                let mut offset = 0;
361                for child in v {
362                    if iv.is_before(offset) {
363                        break;
364                    }
365                    let child_iv = child.interval();
366                    // easier just to use signed ints?
367                    let rec_iv = iv.intersect(child_iv.translate(offset)).translate_neg(offset);
368                    child.push_subseq(b, rec_iv);
369                    offset += child.len();
370                }
371                return;
372            }
373        }
374    }
375
376    pub fn subseq<T: IntervalBounds>(&self, iv: T) -> Node<N> {
377        let iv = iv.into_interval(self.len());
378        let mut b = TreeBuilder::new();
379        self.push_subseq(&mut b, iv);
380        b.build()
381    }
382
383    pub fn edit<T, IV>(&mut self, iv: IV, new: T)
384    where
385        T: Into<Node<N>>,
386        IV: IntervalBounds,
387    {
388        let mut b = TreeBuilder::new();
389        let iv = iv.into_interval(self.len());
390        let self_iv = self.interval();
391        self.push_subseq(&mut b, self_iv.prefix(iv));
392        b.push(new.into());
393        self.push_subseq(&mut b, self_iv.suffix(iv));
394        *self = b.build();
395    }
396
397    // doesn't deal with endpoint, handle that specially if you need it
398    pub fn convert_metrics<M1: Metric<N>, M2: Metric<N>>(&self, mut m1: usize) -> usize {
399        if m1 == 0 {
400            return 0;
401        }
402        // If M1 can fragment, then we must land on the leaf containing
403        // the m1 boundary. Otherwise, we can land on the beginning of
404        // the leaf immediately following the M1 boundary, which may be
405        // more efficient.
406        let m1_fudge = if M1::can_fragment() { 1 } else { 0 };
407        let mut m2 = 0;
408        let mut node = self;
409        while node.height() > 0 {
410            for child in node.get_children() {
411                let child_m1 = child.measure::<M1>();
412                if m1 < child_m1 + m1_fudge {
413                    node = child;
414                    break;
415                }
416                m2 += child.measure::<M2>();
417                m1 -= child_m1;
418            }
419        }
420        let l = node.get_leaf();
421        let base = M1::to_base_units(l, m1);
422        m2 + M2::from_base_units(l, base)
423    }
424}
425
426impl<N: DefaultMetric> Node<N> {
427    /// Measures the length of the text bounded by ``DefaultMetric::measure(offset)`` with another metric.
428    ///
429    /// # Examples
430    /// ```
431    /// use crate::xi_rope::{Rope, LinesMetric};
432    ///
433    /// // the default metric of Rope is BaseMetric (aka number of bytes)
434    /// let my_rope = Rope::from("first line \n second line \n");
435    ///
436    /// // count the number of lines in my_rope
437    /// let num_lines = my_rope.count::<LinesMetric>(my_rope.len());
438    /// assert_eq!(2, num_lines);
439    /// ```
440    pub fn count<M: Metric<N>>(&self, offset: usize) -> usize {
441        self.convert_metrics::<N::DefaultMetric, M>(offset)
442    }
443
444    /// Measures the length of the text bounded by ``M::measure(offset)`` with the default metric.
445    ///
446    /// # Examples
447    /// ```
448    /// use crate::xi_rope::{Rope, LinesMetric};
449    ///
450    /// // the default metric of Rope is BaseMetric (aka number of bytes)
451    /// let my_rope = Rope::from("first line \n second line \n");
452    ///
453    /// // get the byte offset of the line at index 1
454    /// let byte_offset = my_rope.count_base_units::<LinesMetric>(1);
455    /// assert_eq!(12, byte_offset);
456    /// ```
457    pub fn count_base_units<M: Metric<N>>(&self, offset: usize) -> usize {
458        self.convert_metrics::<M, N::DefaultMetric>(offset)
459    }
460}
461
462impl<N: NodeInfo> Default for Node<N> {
463    fn default() -> Node<N> {
464        Node::from_leaf(N::L::default())
465    }
466}
467
468pub struct TreeBuilder<N: NodeInfo>(Option<Node<N>>);
469
470impl<N: NodeInfo> TreeBuilder<N> {
471    pub fn new() -> TreeBuilder<N> {
472        TreeBuilder(None)
473    }
474
475    /// Push a node on the accumulating tree by concatenating it.
476    ///
477    /// This method is O(log n), where `n` is the amount of nodes already in the accumulating tree.
478    /// The worst case happens when all nodes having exactly MAX_CHILDREN children
479    /// and the node being pushed is a leaf or equivalently has height 1.
480    /// Then `log n` nodes have to be created before the leaf can be added, to keep all leaves on the same height.
481    pub fn push(&mut self, n: Node<N>) {
482        match self.0.take() {
483            None => self.0 = Some(n),
484            Some(buf) => self.0 = Some(Node::concat(buf, n)),
485        }
486    }
487
488    /// Add leaves to accumulating tree.
489    ///
490    /// Creates a stack of node lists, where all the nodes in a list have uniform node height.
491    /// The stack is height sorted in ascending order.
492    /// The length of any list in the stack is at most MAX_CHILDREN -1.
493    ///
494    /// Example of this kind of stack if MAX_CHILDREN = 3:
495    /// let n_i be some node of height i. Let the front of the array represent the top of the stack.
496    /// `[[n_1, n_1], [n_2], [n_3, n_3]]`
497    ///
498    /// The nodes in the stack are pushed on the accumulating tree one by one in the end.
499    pub fn push_leaves(&mut self, leaves: Vec<N::L>) {
500        let mut stack: Vec<Vec<Node<N>>> = Vec::new();
501        for leaf in leaves {
502            let mut new = Node::from_leaf(leaf);
503            loop {
504                if stack.last().map_or(true, |r| r[0].height() != new.height()) {
505                    stack.push(Vec::new());
506                }
507                stack.last_mut().unwrap().push(new);
508                if stack.last().unwrap().len() < MAX_CHILDREN {
509                    break;
510                }
511                new = Node::from_nodes(stack.pop().unwrap())
512            }
513        }
514        for v in stack {
515            for r in v {
516                self.push(r)
517            }
518        }
519    }
520
521    pub fn push_leaf(&mut self, l: N::L) {
522        self.push(Node::from_leaf(l))
523    }
524
525    pub fn push_leaf_slice(&mut self, l: &N::L, iv: Interval) {
526        self.push(Node::from_leaf(l.subseq(iv)))
527    }
528
529    pub fn build(self) -> Node<N> {
530        match self.0 {
531            Some(r) => r,
532            None => Node::from_leaf(N::L::default()),
533        }
534    }
535}
536
537const CURSOR_CACHE_SIZE: usize = 4;
538
539/// A data structure for traversing boundaries in a tree.
540///
541/// It is designed to be efficient both for random access and for iteration. The
542/// cursor itself is agnostic to which [`Metric`] is used to determine boundaries, but
543/// the methods to find boundaries are parametrized on the [`Metric`].
544///
545/// A cursor can be valid or invalid. It is always valid when created or after
546/// [`set`](#method.set) is called, and becomes invalid after [`prev`](#method.prev)
547/// or [`next`](#method.next) fails to find a boundary.
548///
549/// [`Metric`]: struct.Metric.html
550pub struct Cursor<'a, N: 'a + NodeInfo> {
551    /// The tree being traversed by this cursor.
552    root: &'a Node<N>,
553    /// The current position of the cursor.
554    ///
555    /// It is always less than or equal to the tree length.
556    position: usize,
557    /// The cache holds the tail of the path from the root to the current leaf.
558    ///
559    /// Each entry is a reference to the parent node and the index of the child. It
560    /// is stored bottom-up; `cache[0]` is the parent of the leaf and the index of
561    /// the leaf within that parent.
562    ///
563    /// The main motivation for this being a fixed-size array is to keep the cursor
564    /// an allocation-free data structure.
565    cache: [Option<(&'a Node<N>, usize)>; CURSOR_CACHE_SIZE],
566    /// The leaf containing the current position, when the cursor is valid.
567    ///
568    /// The position is only at the end of the leaf when it is at the end of the tree.
569    leaf: Option<&'a N::L>,
570    /// The offset of `leaf` within the tree.
571    offset_of_leaf: usize,
572}
573
574impl<'a, N: NodeInfo> Cursor<'a, N> {
575    /// Create a new cursor at the given position.
576    pub fn new(n: &'a Node<N>, position: usize) -> Cursor<'a, N> {
577        let mut result = Cursor {
578            root: n,
579            position,
580            cache: [None; CURSOR_CACHE_SIZE],
581            leaf: None,
582            offset_of_leaf: 0,
583        };
584        result.descend();
585        result
586    }
587
588    /// The length of the tree.
589    pub fn total_len(&self) -> usize {
590        self.root.len()
591    }
592
593    /// Return a reference to the root node of the tree.
594    pub fn root(&self) -> &'a Node<N> {
595        self.root
596    }
597
598    /// Get the current leaf of the cursor.
599    ///
600    /// If the cursor is valid, returns the leaf containing the current position,
601    /// and the offset of the current position within the leaf. That offset is equal
602    /// to the leaf length only at the end, otherwise it is less than the leaf length.
603    pub fn get_leaf(&self) -> Option<(&'a N::L, usize)> {
604        self.leaf.map(|l| (l, self.position - self.offset_of_leaf))
605    }
606
607    /// Set the position of the cursor.
608    ///
609    /// The cursor is valid after this call.
610    ///
611    /// Precondition: `position` is less than or equal to the length of the tree.
612    pub fn set(&mut self, position: usize) {
613        self.position = position;
614        if let Some(l) = self.leaf {
615            if self.position >= self.offset_of_leaf && self.position < self.offset_of_leaf + l.len()
616            {
617                return;
618            }
619        }
620        // TODO: walk up tree to find leaf if nearby
621        self.descend();
622    }
623
624    /// Get the position of the cursor.
625    pub fn pos(&self) -> usize {
626        self.position
627    }
628
629    /// Determine whether the current position is a boundary.
630    ///
631    /// Note: the beginning and end of the tree may or may not be boundaries, depending on the
632    /// metric. If the metric is not `can_fragment`, then they always are.
633    pub fn is_boundary<M: Metric<N>>(&mut self) -> bool {
634        if self.leaf.is_none() {
635            // not at a valid position
636            return false;
637        }
638        if self.position == self.offset_of_leaf && !M::can_fragment() {
639            return true;
640        }
641        if self.position == 0 || self.position > self.offset_of_leaf {
642            return M::is_boundary(self.leaf.unwrap(), self.position - self.offset_of_leaf);
643        }
644        // tricky case, at beginning of leaf, need to query end of previous
645        // leaf; TODO: would be nice if we could do it another way that didn't
646        // make the method &mut self.
647        let l = self.prev_leaf().unwrap().0;
648        let result = M::is_boundary(l, l.len());
649        let _ = self.next_leaf();
650        result
651    }
652
653    /// Moves the cursor to the previous boundary.
654    ///
655    /// When there is no previous boundary, returns `None` and the cursor becomes invalid.
656    ///
657    /// Return value: the position of the boundary, if it exists.
658    pub fn prev<M: Metric<N>>(&mut self) -> Option<(usize)> {
659        if self.position == 0 || self.leaf.is_none() {
660            self.leaf = None;
661            return None;
662        }
663        let orig_pos = self.position;
664        let offset_in_leaf = orig_pos - self.offset_of_leaf;
665        if offset_in_leaf > 0 {
666            let l = self.leaf.unwrap();
667            if let Some(offset_in_leaf) = M::prev(l, offset_in_leaf) {
668                self.position = self.offset_of_leaf + offset_in_leaf;
669                return Some(self.position);
670            }
671        }
672
673        // not in same leaf, need to scan backwards
674        self.prev_leaf()?;
675        if let Some(offset) = self.last_inside_leaf::<M>(orig_pos) {
676            return Some(offset);
677        }
678
679        // Not found in previous leaf, find using measurement.
680        let measure = self.measure_leaf::<M>(self.position);
681        if measure == 0 {
682            self.leaf = None;
683            self.position = 0;
684            return None;
685        }
686        self.descend_metric::<M>(measure);
687        self.last_inside_leaf::<M>(orig_pos)
688    }
689
690    /// Moves the cursor to the next boundary.
691    ///
692    /// When there is no next boundary, returns `None` and the cursor becomes invalid.
693    ///
694    /// Return value: the position of the boundary, if it exists.
695    pub fn next<M: Metric<N>>(&mut self) -> Option<(usize)> {
696        if self.position >= self.root.len() || self.leaf.is_none() {
697            self.leaf = None;
698            return None;
699        }
700
701        if let Some(offset) = self.next_inside_leaf::<M>() {
702            return Some(offset);
703        }
704
705        self.next_leaf()?;
706        if let Some(offset) = self.next_inside_leaf::<M>() {
707            return Some(offset);
708        }
709
710        // Leaf is 0-measure (otherwise would have already succeeded).
711        let measure = self.measure_leaf::<M>(self.position);
712        self.descend_metric::<M>(measure + 1);
713        if let Some(offset) = self.next_inside_leaf::<M>() {
714            return Some(offset);
715        }
716
717        // Not found, properly invalidate cursor.
718        self.position = self.root.len();
719        self.leaf = None;
720        None
721    }
722
723    /// Returns the current position if it is a boundary in this [`Metric`],
724    /// else behaves like [`next`](#method.next).
725    ///
726    /// [`Metric`]: struct.Metric.html
727    pub fn at_or_next<M: Metric<N>>(&mut self) -> Option<usize> {
728        if self.is_boundary::<M>() {
729            Some(self.pos())
730        } else {
731            self.next::<M>()
732        }
733    }
734
735    /// Returns the current position if it is a boundary in this [`Metric`],
736    /// else behaves like [`prev`](#method.prev).
737    ///
738    /// [`Metric`]: struct.Metric.html
739    pub fn at_or_prev<M: Metric<N>>(&mut self) -> Option<usize> {
740        if self.is_boundary::<M>() {
741            Some(self.pos())
742        } else {
743            self.prev::<M>()
744        }
745    }
746
747    /// Returns an iterator with this cursor over the given [`Metric`].
748    ///
749    /// # Examples:
750    ///
751    /// ```
752    /// # use xi_rope::{Cursor, LinesMetric, Rope};
753    /// #
754    /// let text: Rope = "one line\ntwo line\nred line\nblue".into();
755    /// let mut cursor = Cursor::new(&text, 0);
756    /// let line_offsets = cursor.iter::<LinesMetric>().collect::<Vec<_>>();
757    /// assert_eq!(line_offsets, vec![9, 18, 27]);
758    ///
759    /// ```
760    /// [`Metric`]: struct.Metric.html
761    pub fn iter<'c, M: Metric<N>>(&'c mut self) -> CursorIter<'c, 'a, N, M> {
762        CursorIter { cursor: self, _metric: PhantomData }
763    }
764
765    /// Tries to find the last boundary in the leaf the cursor is currently in.
766    ///
767    /// If the last boundary is at the end of the leaf, it is only counted if
768    /// it is less than `orig_pos`.
769    #[inline]
770    fn last_inside_leaf<M: Metric<N>>(&mut self, orig_pos: usize) -> Option<usize> {
771        let l = self.leaf.expect("inconsistent, shouldn't get here");
772        let len = l.len();
773        if self.offset_of_leaf + len < orig_pos && M::is_boundary(l, len) {
774            let _ = self.next_leaf();
775            return Some(self.position);
776        }
777        let offset_in_leaf = M::prev(l, len)?;
778        self.position = self.offset_of_leaf + offset_in_leaf;
779        Some(self.position)
780    }
781
782    /// Tries to find the next boundary in the leaf the cursor is currently in.
783    #[inline]
784    fn next_inside_leaf<M: Metric<N>>(&mut self) -> Option<usize> {
785        let l = self.leaf.expect("inconsistent, shouldn't get here");
786        let offset_in_leaf = self.position - self.offset_of_leaf;
787        let offset_in_leaf = M::next(l, offset_in_leaf)?;
788        if offset_in_leaf == l.len() && self.offset_of_leaf + offset_in_leaf != self.root.len() {
789            let _ = self.next_leaf();
790        } else {
791            self.position = self.offset_of_leaf + offset_in_leaf;
792        }
793        Some(self.position)
794    }
795
796    /// Move to beginning of next leaf.
797    ///
798    /// Return value: same as [`get_leaf`](#method.get_leaf).
799    pub fn next_leaf(&mut self) -> Option<(&'a N::L, usize)> {
800        let leaf = self.leaf?;
801        self.position = self.offset_of_leaf + leaf.len();
802        for i in 0..CURSOR_CACHE_SIZE {
803            if self.cache[i].is_none() {
804                // this probably can't happen
805                self.leaf = None;
806                return None;
807            }
808            let (node, j) = self.cache[i].unwrap();
809            if j + 1 < node.get_children().len() {
810                self.cache[i] = Some((node, j + 1));
811                let mut node_down = &node.get_children()[j + 1];
812                for k in (0..i).rev() {
813                    self.cache[k] = Some((node_down, 0));
814                    node_down = &node_down.get_children()[0];
815                }
816                self.leaf = Some(node_down.get_leaf());
817                self.offset_of_leaf = self.position;
818                return self.get_leaf();
819            }
820        }
821        if self.offset_of_leaf + self.leaf.unwrap().len() == self.root.len() {
822            self.leaf = None;
823            return None;
824        }
825        self.descend();
826        self.get_leaf()
827    }
828
829    /// Move to beginning of previous leaf.
830    ///
831    /// Return value: same as [`get_leaf`](#method.get_leaf).
832    pub fn prev_leaf(&mut self) -> Option<(&'a N::L, usize)> {
833        if self.offset_of_leaf == 0 {
834            self.leaf = None;
835            self.position = 0;
836            return None;
837        }
838        for i in 0..CURSOR_CACHE_SIZE {
839            if self.cache[i].is_none() {
840                // this probably can't happen
841                self.leaf = None;
842                return None;
843            }
844            let (node, j) = self.cache[i].unwrap();
845            if j > 0 {
846                self.cache[i] = Some((node, j - 1));
847                let mut node_down = &node.get_children()[j - 1];
848                for k in (0..i).rev() {
849                    let last_ix = node_down.get_children().len() - 1;
850                    self.cache[k] = Some((node_down, last_ix));
851                    node_down = &node_down.get_children()[last_ix];
852                }
853                let leaf = node_down.get_leaf();
854                self.leaf = Some(leaf);
855                self.offset_of_leaf -= leaf.len();
856                self.position = self.offset_of_leaf;
857                return self.get_leaf();
858            }
859        }
860        self.position = self.offset_of_leaf - 1;
861        self.descend();
862        self.position = self.offset_of_leaf;
863        self.get_leaf()
864    }
865
866    /// Go to the leaf containing the current position.
867    ///
868    /// Sets `leaf` to the leaf containing `position`, and updates `cache` and
869    /// `offset_of_leaf` to be consistent.
870    fn descend(&mut self) {
871        let mut node = self.root;
872        let mut offset = 0;
873        while node.height() > 0 {
874            let children = node.get_children();
875            let mut i = 0;
876            loop {
877                if i + 1 == children.len() {
878                    break;
879                }
880                let nextoff = offset + children[i].len();
881                if nextoff > self.position {
882                    break;
883                }
884                offset = nextoff;
885                i += 1;
886            }
887            let cache_ix = node.height() - 1;
888            if cache_ix < CURSOR_CACHE_SIZE {
889                self.cache[cache_ix] = Some((node, i));
890            }
891            node = &children[i];
892        }
893        self.leaf = Some(node.get_leaf());
894        self.offset_of_leaf = offset;
895    }
896
897    /// Returns the measure at the beginning of the leaf containing `pos`.
898    ///
899    /// This method is O(log n) no matter the current cursor state.
900    fn measure_leaf<M: Metric<N>>(&self, mut pos: usize) -> usize {
901        let mut node = self.root;
902        let mut metric = 0;
903        while node.height() > 0 {
904            for child in node.get_children() {
905                let len = child.len();
906                if pos < len {
907                    node = child;
908                    break;
909                }
910                pos -= len;
911                metric += child.measure::<M>();
912            }
913        }
914        metric
915    }
916
917    /// Find the leaf having the given measure.
918    ///
919    /// This function sets `self.position` to the beginning of the leaf
920    /// containing the smallest offset with the given metric, and also updates
921    /// state as if [`descend`](#method.descend) was called.
922    ///
923    /// If `measure` is greater than the measure of the whole tree, then moves
924    /// to the last node.
925    fn descend_metric<M: Metric<N>>(&mut self, mut measure: usize) {
926        let mut node = self.root;
927        let mut offset = 0;
928        while node.height() > 0 {
929            let children = node.get_children();
930            let mut i = 0;
931            loop {
932                if i + 1 == children.len() {
933                    break;
934                }
935                let child = &children[i];
936                let child_m = child.measure::<M>();
937                if child_m >= measure {
938                    break;
939                }
940                offset += child.len();
941                measure -= child_m;
942                i += 1;
943            }
944            let cache_ix = node.height() - 1;
945            if cache_ix < CURSOR_CACHE_SIZE {
946                self.cache[cache_ix] = Some((node, i));
947            }
948            node = &children[i];
949        }
950        self.leaf = Some(node.get_leaf());
951        self.position = offset;
952        self.offset_of_leaf = offset;
953    }
954}
955
956/// An iterator generated by a [`Cursor`], for some [`Metric`].
957///
958/// [`Cursor`]: struct.Cursor.html
959/// [`Metric`]: struct.Metric.html
960pub struct CursorIter<'c, 'a: 'c, N: 'a + NodeInfo, M: 'a + Metric<N>> {
961    cursor: &'c mut Cursor<'a, N>,
962    _metric: PhantomData<&'a M>,
963}
964
965impl<'c, 'a, N: NodeInfo, M: Metric<N>> Iterator for CursorIter<'c, 'a, N, M> {
966    type Item = usize;
967
968    fn next(&mut self) -> Option<usize> {
969        self.cursor.next::<M>()
970    }
971}
972
973impl<'c, 'a, N: NodeInfo, M: Metric<N>> CursorIter<'c, 'a, N, M> {
974    /// Returns the current position of the underlying [`Cursor`].
975    ///
976    /// [`Cursor`]: struct.Cursor.html
977    pub fn pos(&self) -> usize {
978        self.cursor.pos()
979    }
980}
981
982#[cfg(test)]
983mod test {
984    use super::*;
985    use crate::rope::*;
986
987    fn build_triangle(n: u32) -> String {
988        let mut s = String::new();
989        let mut line = String::new();
990        for _ in 0..n {
991            s += &line;
992            s += "\n";
993            line += "a";
994        }
995        s
996    }
997
998    #[test]
999    fn eq_rope_with_stack() {
1000        let n = 2_000;
1001        let s = build_triangle(n);
1002        let mut builder_default = TreeBuilder::new();
1003        let mut builder_stacked = TreeBuilder::new();
1004        builder_default.push_str(&s);
1005        builder_stacked.push_str_stacked(&s);
1006        let tree_default = builder_default.build();
1007        let tree_stacked = builder_stacked.build();
1008        assert_eq!(tree_default, tree_stacked);
1009    }
1010
1011    #[test]
1012    fn cursor_next_triangle() {
1013        let n = 2_000;
1014        let text = Rope::from(build_triangle(n));
1015
1016        let mut cursor = Cursor::new(&text, 0);
1017        let mut prev_offset = cursor.pos();
1018        for i in 1..(n + 1) as usize {
1019            let offset = cursor.next::<LinesMetric>().expect("arrived at the end too soon");
1020            assert_eq!(offset - prev_offset, i);
1021            prev_offset = offset;
1022        }
1023        assert_eq!(cursor.next::<LinesMetric>(), None);
1024    }
1025
1026    #[test]
1027    fn node_is_empty() {
1028        let text = Rope::from(String::new());
1029        assert_eq!(text.is_empty(), true);
1030    }
1031
1032    #[test]
1033    fn cursor_next_empty() {
1034        let text = Rope::from(String::new());
1035        let mut cursor = Cursor::new(&text, 0);
1036        assert_eq!(cursor.next::<LinesMetric>(), None);
1037        assert_eq!(cursor.pos(), 0);
1038    }
1039
1040    #[test]
1041    fn cursor_iter() {
1042        let text: Rope = build_triangle(50).into();
1043        let mut cursor = Cursor::new(&text, 0);
1044        let mut manual = Vec::new();
1045        while let Some(nxt) = cursor.next::<LinesMetric>() {
1046            manual.push(nxt);
1047        }
1048
1049        cursor.set(0);
1050        let auto = cursor.iter::<LinesMetric>().collect::<Vec<_>>();
1051        assert_eq!(manual, auto);
1052    }
1053
1054    #[test]
1055    fn cursor_next_misc() {
1056        cursor_next_for("toto");
1057        cursor_next_for("toto\n");
1058        cursor_next_for("toto\ntata");
1059        cursor_next_for("歴史\n科学的");
1060        cursor_next_for("\n歴史\n科学的\n");
1061        cursor_next_for(&build_triangle(100));
1062    }
1063
1064    fn cursor_next_for(s: &str) {
1065        let r = Rope::from(s.to_owned());
1066        for i in 0..r.len() {
1067            let mut c = Cursor::new(&r, i);
1068            let it = c.next::<LinesMetric>();
1069            let pos = c.pos();
1070            assert!(s.as_bytes()[i..pos - 1].iter().all(|c| *c != b'\n'), "missed linebreak");
1071            if pos < s.len() {
1072                assert!(it.is_some(), "must be Some(_)");
1073                assert!(s.as_bytes()[pos - 1] == b'\n', "not a linebreak");
1074            } else {
1075                if s.as_bytes()[s.len() - 1] == b'\n' {
1076                    assert!(it.is_some(), "must be Some(_)");
1077                } else {
1078                    assert!(it.is_none());
1079                    assert!(c.get_leaf().is_none());
1080                }
1081            }
1082        }
1083    }
1084
1085    #[test]
1086    fn cursor_prev_misc() {
1087        cursor_prev_for("toto");
1088        cursor_prev_for("a\na\n");
1089        cursor_prev_for("toto\n");
1090        cursor_prev_for("toto\ntata");
1091        cursor_prev_for("歴史\n科学的");
1092        cursor_prev_for("\n歴史\n科学的\n");
1093        cursor_prev_for(&build_triangle(100));
1094    }
1095
1096    fn cursor_prev_for(s: &str) {
1097        let r = Rope::from(s.to_owned());
1098        for i in 0..r.len() {
1099            let mut c = Cursor::new(&r, i);
1100            let it = c.prev::<LinesMetric>();
1101            let pos = c.pos();
1102
1103            //Should countain at most one linebreak
1104            assert!(
1105                s.as_bytes()[pos..i].iter().filter(|c| **c == b'\n').count() <= 1,
1106                "missed linebreak"
1107            );
1108
1109            if i == 0 && s.as_bytes()[i] == b'\n' {
1110                assert_eq!(pos, 0);
1111            }
1112
1113            if pos > 0 {
1114                assert!(it.is_some(), "must be Some(_)");
1115                assert!(s.as_bytes()[pos - 1] == b'\n', "not a linebreak");
1116            }
1117        }
1118    }
1119
1120    #[test]
1121    fn at_or_next() {
1122        let text: Rope = "this\nis\nalil\nstring".into();
1123        let mut cursor = Cursor::new(&text, 0);
1124        assert_eq!(cursor.at_or_next::<LinesMetric>(), Some(5));
1125        assert_eq!(cursor.at_or_next::<LinesMetric>(), Some(5));
1126        cursor.set(1);
1127        assert_eq!(cursor.at_or_next::<LinesMetric>(), Some(5));
1128        assert_eq!(cursor.at_or_prev::<LinesMetric>(), Some(5));
1129        cursor.set(6);
1130        assert_eq!(cursor.at_or_prev::<LinesMetric>(), Some(5));
1131        cursor.set(6);
1132        assert_eq!(cursor.at_or_next::<LinesMetric>(), Some(8));
1133        assert_eq!(cursor.at_or_next::<LinesMetric>(), Some(8));
1134    }
1135
1136    #[test]
1137    fn next_zero_measure_large() {
1138        let mut text = Rope::from("a");
1139        for _ in 0..24 {
1140            text = Node::concat(text.clone(), text);
1141            let mut cursor = Cursor::new(&text, 0);
1142            assert_eq!(cursor.next::<LinesMetric>(), None);
1143            // Test that cursor is properly invalidated and at end of text.
1144            assert_eq!(cursor.get_leaf(), None);
1145            assert_eq!(cursor.pos(), text.len());
1146
1147            cursor.set(text.len());
1148            assert_eq!(cursor.prev::<LinesMetric>(), None);
1149            // Test that cursor is properly invalidated and at beginning of text.
1150            assert_eq!(cursor.get_leaf(), None);
1151            assert_eq!(cursor.pos(), 0);
1152        }
1153    }
1154
1155    #[test]
1156    fn prev_line_large() {
1157        let s: String = format!("{}{}", "\n", build_triangle(1000));
1158        let rope = Rope::from(s);
1159        let mut expected_pos = rope.len();
1160        let mut cursor = Cursor::new(&rope, rope.len());
1161
1162        for i in (1..1001).rev() {
1163            expected_pos = expected_pos - i;
1164            assert_eq!(expected_pos, cursor.prev::<LinesMetric>().unwrap());
1165        }
1166
1167        assert_eq!(None, cursor.prev::<LinesMetric>());
1168    }
1169
1170    #[test]
1171    fn prev_line_small() {
1172        let empty_rope = Rope::from("\n");
1173        let mut cursor = Cursor::new(&empty_rope, empty_rope.len());
1174        assert_eq!(None, cursor.prev::<LinesMetric>());
1175
1176        let rope = Rope::from("\n\n\n\n\n\n\n\n\n\n");
1177        cursor = Cursor::new(&rope, rope.len());
1178        let mut expected_pos = rope.len();
1179        for _ in (1..10).rev() {
1180            expected_pos -= 1;
1181            assert_eq!(expected_pos, cursor.prev::<LinesMetric>().unwrap());
1182        }
1183
1184        assert_eq!(None, cursor.prev::<LinesMetric>());
1185    }
1186}