├── .gitignore ├── .rustfmt.toml ├── .travis.yml ├── .vscode └── settings.json ├── Cargo.toml ├── LICENSE ├── README.md ├── benches └── criterion.rs ├── scripts └── coverage └── src ├── digit.rs ├── iter.rs ├── lib.rs ├── measure.rs ├── monoid.rs ├── node.rs ├── reference.rs ├── test ├── mod.rs ├── quickcheck.rs └── simple.rs └── tree.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | -------------------------------------------------------------------------------- /.rustfmt.toml: -------------------------------------------------------------------------------- 1 | tab_spaces = 4 -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | cache: cargo 3 | 4 | rust: 5 | - stable 6 | - beta 7 | - nightly 8 | 9 | matrix: 10 | allow_failures: 11 | - rust: nightly 12 | 13 | sudo: required 14 | services: 15 | - docker 16 | 17 | after_success: | 18 | # coverage 19 | if [[ "$TRAVIS_RUST_VERSION" == stable ]]; then 20 | docker run --security-opt seccomp=unconfined -v "$PWD:/volume" xd009642/tarpaulin \ 21 | cargo tarpaulin --ciserver travis-ci --coveralls $TRAVIS_JOB_ID 22 | fi 23 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "fingertree", 4 | "fingertrees" 5 | ] 6 | } -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fingertrees" 3 | version = "0.2.11" 4 | authors = ["Pavel Aslanov "] 5 | description = "Immutable persisten finger trees" 6 | license = "MIT" 7 | readme = "README.md" 8 | repository = "https://github.com/aslpavel/fingertree-rs" 9 | categories = ["data-structures"] 10 | keywords = ["immutable", "persistent", "data-structures"] 11 | edition = "2021" 12 | 13 | [badges] 14 | travis-ci = { repository = "aslpavel/fingertree-rs" } 15 | coveralls = { repository = "aslpavel/fingertree-rs" } 16 | 17 | [dependencies] 18 | 19 | [dev-dependencies] 20 | criterion = { version = "^0.5", features = ["html_reports"] } 21 | quickcheck = "^1.0" 22 | 23 | [lib] 24 | bench = false 25 | 26 | [[bench]] 27 | name = "criterion" 28 | harness = false 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Pavel Aslanov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FingerTree 2 | [![Build Status](https://travis-ci.org/aslpavel/fingertree-rs.svg?branch=master)](https://travis-ci.org/aslpavel/fingertree-rs) 3 | [![Coverage Status](https://coveralls.io/repos/github/aslpavel/fingertree-rs/badge.svg?branch=master)](https://coveralls.io/github/aslpavel/fingertree-rs?branch=master) 4 | [![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) 5 | [![Crate](https://img.shields.io/crates/v/fingertrees.svg)](https://crates.io/crates/fingertrees) 6 | [![API Docs](https://docs.rs/fingertrees/badge.svg)](https://docs.rs/fingertrees) 7 | 8 | Finger trees is a functional representation of persistent sequences 9 | supporting access to the ends in amortized constant time, and concatenation 10 | and splitting in time logarithmic in the size of the smaller piece. It also 11 | has `split` operation defined in general 12 | form, which can be used to implement sequence, priority queue, search tree, 13 | priority search queue and more data structures. 14 | 15 | ## Links: 16 | - Original paper: [Finger Trees: A Simple General-purpose Data Structure](http://www.staff.city.ac.uk/~ross/papers/FingerTree.html) 17 | - Wikipedia article: [FingerTree](https://en.wikipedia.org/wiki/Finger_tree) 18 | 19 | ## Notes: 20 | - This implementation does not use non-regular recursive types as implementation 21 | described in the paper. As rust's monomorphization does not play well with such types. 22 | - Implementation abstracts over reference counted types `Rc/Arc`. Using type family trick. 23 | - Uses strict spine in implementation. 24 | - Iterator returns cloned value, and in general this implementation assumes that value 25 | stored in a tree is cheaply clonable, if it is not you can always put it in a `Rc/Arc` or 26 | anything else. 27 | 28 | ## Examples: 29 | ```rust 30 | use std::iter::FromIterator; 31 | use fingertrees::measure::Size; 32 | use fingertrees::monoid::Sum; 33 | use fingertrees::{FingerTree, Measured, RcRefs}; 34 | 35 | // construct `Rc` based finger tree with `Size` measure 36 | let ft: FingerTree = vec!["one", "two", "three", "four", "five"] 37 | .into_iter() 38 | .map(Size) 39 | .collect(); 40 | assert_eq!(ft.measure(), Sum(5)); 41 | 42 | // split with predicate 43 | let (left, right) = ft.split(|measure| *measure > Sum(2)); 44 | assert_eq!(left.measure(), Sum(2)); 45 | assert_eq!(Vec::from_iter(&left), vec![Size("one"), Size("two")]); 46 | assert_eq!(right.measure(), Sum(3)); 47 | assert_eq!(Vec::from_iter(&right), vec![Size("three"), Size("four"), Size("five")]); 48 | 49 | // concatenate 50 | assert_eq!(ft, left + right); 51 | 52 | // push values 53 | assert_eq!( 54 | ft.push_left(Size("left")).push_right(Size("right")), 55 | vec!["left", "one", "two", "three", "four", "five", "right"] 56 | .into_iter() 57 | .map(Size) 58 | .collect(), 59 | ); 60 | ``` 61 | 62 | -------------------------------------------------------------------------------- /benches/criterion.rs: -------------------------------------------------------------------------------- 1 | use criterion::{criterion_group, criterion_main, Bencher, BenchmarkId, Criterion, Throughput}; 2 | use fingertrees::measure::Size; 3 | use fingertrees::{rc, ArcRefs, FingerTree, Measured, RcRefs, Refs}; 4 | use std::collections::HashMap; 5 | 6 | const KB: usize = 1024; 7 | const SPLIT_1024: &[usize] = &[211, 384, 557, 730, 903]; 8 | 9 | fn ft_from(c: &mut Criterion) { 10 | let mut group = c.benchmark_group("from"); 11 | for size in [KB, 2 * KB, 4 * KB, 16 * KB] { 12 | let vals: Vec<_> = (0..size).map(Size).collect(); 13 | group.throughput(Throughput::Elements(size as u64)); 14 | group.bench_with_input(BenchmarkId::new("iter", size), &vals, |b, vals| { 15 | b.iter(|| vals.iter().cloned().collect::>()) 16 | }); 17 | group.bench_with_input(BenchmarkId::new("slice", size), &vals, |b, vals| { 18 | b.iter(|| rc::FingerTree::from(vals.as_slice())) 19 | }); 20 | } 21 | group.finish(); 22 | } 23 | 24 | fn ft_split(c: &mut Criterion) { 25 | let ft: rc::FingerTree<_> = (0..1024).map(Size).collect(); 26 | 27 | let mut group = c.benchmark_group("split"); 28 | for position in SPLIT_1024 { 29 | group.bench_with_input( 30 | BenchmarkId::new("position", position), 31 | position, 32 | |b, position| b.iter(|| ft.split(|m| **m > *position)), 33 | ); 34 | } 35 | group.finish(); 36 | } 37 | 38 | fn ft_split_left(c: &mut Criterion) { 39 | let ft: rc::FingerTree<_> = (0..1024).map(Size).collect(); 40 | 41 | let mut group = c.benchmark_group("split_left"); 42 | for position in SPLIT_1024 { 43 | group.bench_with_input( 44 | BenchmarkId::new("position", position), 45 | position, 46 | |b, position| b.iter(|| ft.split_left(|m| **m > *position)), 47 | ); 48 | } 49 | group.finish(); 50 | } 51 | 52 | fn ft_split_right(c: &mut Criterion) { 53 | let ft: rc::FingerTree<_> = (0..1024).map(Size).collect(); 54 | 55 | let mut group = c.benchmark_group("split_right"); 56 | for position in SPLIT_1024 { 57 | group.bench_with_input( 58 | BenchmarkId::new("position", position), 59 | position, 60 | |b, position| b.iter(|| ft.split_right(|m| **m > *position)), 61 | ); 62 | } 63 | group.finish(); 64 | } 65 | 66 | fn ft_concat(c: &mut Criterion) { 67 | let ft: rc::FingerTree<_> = (0..1024).map(Size).collect(); 68 | let ft_split: HashMap<_, _> = SPLIT_1024 69 | .iter() 70 | .map(|size| (size, ft.split(|m| **m > *size))) 71 | .collect(); 72 | 73 | let mut group = c.benchmark_group("concat"); 74 | for (position, (left, right)) in ft_split { 75 | group.bench_with_input( 76 | BenchmarkId::new("position", position), 77 | &(left, right), 78 | |b, (left, right)| b.iter(|| left.concat(right)), 79 | ); 80 | } 81 | group.finish(); 82 | } 83 | 84 | /// Iterator based destructuring FingerTree with `view` 85 | struct ViewIter 86 | where 87 | R: Refs, 88 | V: Measured, 89 | { 90 | tail: FingerTree, 91 | } 92 | 93 | impl ViewIter 94 | where 95 | R: Refs, 96 | V: Measured, 97 | { 98 | fn new(tail: &FingerTree) -> Self { 99 | ViewIter { tail: tail.clone() } 100 | } 101 | } 102 | 103 | impl Iterator for ViewIter 104 | where 105 | R: Refs, 106 | V: Measured, 107 | { 108 | type Item = V; 109 | 110 | fn next(&mut self) -> Option { 111 | let (head, tail) = self.tail.view_left()?; 112 | self.tail = tail; 113 | Some(head) 114 | } 115 | } 116 | 117 | fn ft_iter(c: &mut Criterion) { 118 | let len = 65536; 119 | let ft: rc::FingerTree<_> = (0..len).map(Size).collect(); 120 | let mut group = c.benchmark_group("iterator"); 121 | group.bench_with_input(BenchmarkId::new("stack", len), &ft, |b, ft| { 122 | b.iter(|| ft.iter().count()) 123 | }); 124 | group.bench_with_input(BenchmarkId::new("view", len), &ft, |b, ft| { 125 | b.iter(|| ViewIter::new(ft).count()) 126 | }); 127 | group.finish(); 128 | } 129 | 130 | fn ft_arc_vs_rc(c: &mut Criterion) { 131 | fn split_concat(b: &mut Bencher, size_split: &(usize, usize)) 132 | where 133 | R: Refs>, 134 | { 135 | let (size, split) = size_split; 136 | let ft: FingerTree = (0..*size).map(Size).collect(); 137 | b.iter(|| { 138 | let (left, right) = ft.split(|m| **m > *split); 139 | left.concat(&right) 140 | }) 141 | } 142 | let size_split = (16384, 10923); 143 | let mut group = c.benchmark_group("split+concat"); 144 | group.bench_with_input( 145 | BenchmarkId::new("arc", size_split.0), 146 | &size_split, 147 | split_concat::, 148 | ); 149 | group.bench_with_input( 150 | BenchmarkId::new("rc", size_split.0), 151 | &size_split, 152 | split_concat::, 153 | ); 154 | group.finish(); 155 | } 156 | 157 | criterion_group! { 158 | benches, 159 | ft_arc_vs_rc, 160 | ft_concat, 161 | ft_from, 162 | ft_iter, 163 | ft_split, 164 | ft_split_left, 165 | ft_split_right, 166 | } 167 | 168 | criterion_main!(benches); 169 | -------------------------------------------------------------------------------- /scripts/coverage: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | docker run --security-opt seccomp=unconfined -v "$PWD:/volume" xd009642/tarpaulin cargo tarpaulin "${@}" -------------------------------------------------------------------------------- /src/digit.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Add; 2 | 3 | use crate::measure::Measured; 4 | use crate::monoid::Monoid; 5 | use crate::node::{Node, NodeInner}; 6 | use crate::reference::Refs; 7 | 8 | #[derive(Clone)] 9 | pub enum Digit { 10 | One([V; 1]), 11 | Two([V; 2]), 12 | Three([V; 3]), 13 | Four([V; 4]), 14 | } 15 | 16 | impl Digit 17 | where 18 | V: Measured, 19 | { 20 | pub(crate) fn split(&self, mut measure: V::Measure, pred: &mut F) -> (&[V], &V, &[V]) 21 | where 22 | F: FnMut(&V::Measure) -> bool, 23 | { 24 | let slice = self.as_ref(); 25 | if slice.len() == 1 { 26 | (&[], &slice[0], &[]) 27 | } else { 28 | let slice = self.as_ref(); 29 | for (index, item) in slice.iter().enumerate() { 30 | measure = measure.join(&item.measure()); 31 | if pred(&measure) { 32 | return (&slice[..index], &slice[index], &slice[index + 1..]); 33 | } 34 | } 35 | let index = slice.len() - 1; 36 | (&slice[..index], &slice[index], &[]) 37 | } 38 | } 39 | 40 | pub(crate) fn find(&self, mut measure: V::Measure, pred: &mut F) -> (V::Measure, &V) 41 | where 42 | F: FnMut(&V::Measure) -> bool, 43 | { 44 | let last = self.as_ref().len() - 1; 45 | for (index, value) in self.as_ref().iter().enumerate() { 46 | let next_measure = measure.join(&value.measure()); 47 | if pred(&next_measure) || index == last { 48 | return (measure, value); 49 | } 50 | measure = next_measure; 51 | } 52 | unreachable!() 53 | } 54 | } 55 | 56 | impl<'a, V, R> Add for &'a Digit 57 | where 58 | V: Clone, 59 | R: AsRef<[V]>, 60 | { 61 | type Output = Digit; 62 | 63 | fn add(self, other: R) -> Self::Output { 64 | match (self.as_ref(), other.as_ref()) { 65 | (_, []) => self.clone(), 66 | ([v0], [v1]) => Digit::Two([v0.clone(), v1.clone()]), 67 | ([v0], [v1, v2]) => Digit::Three([v0.clone(), v1.clone(), v2.clone()]), 68 | ([v0], [v1, v2, v3]) => Digit::Four([v0.clone(), v1.clone(), v2.clone(), v3.clone()]), 69 | ([v0, v1], [v2]) => Digit::Three([v0.clone(), v1.clone(), v2.clone()]), 70 | ([v0, v1], [v2, v3]) => Digit::Four([v0.clone(), v1.clone(), v2.clone(), v3.clone()]), 71 | ([v0, v1, v2], [v3]) => Digit::Four([v0.clone(), v1.clone(), v2.clone(), v3.clone()]), 72 | _ => panic!( 73 | "impossible to create digit of size: {}", 74 | self.as_ref().len() + other.as_ref().len(), 75 | ), 76 | } 77 | } 78 | } 79 | 80 | impl Measured for Digit { 81 | type Measure = V::Measure; 82 | 83 | fn measure(&self) -> Self::Measure { 84 | self.as_ref() 85 | .iter() 86 | .fold(Self::Measure::unit(), |measure, val| { 87 | measure.join(&val.measure()) 88 | }) 89 | } 90 | } 91 | 92 | impl AsRef<[V]> for Digit { 93 | fn as_ref(&self) -> &[V] { 94 | match self { 95 | Digit::One(v) => v, 96 | Digit::Two(v) => v, 97 | Digit::Three(v) => v, 98 | Digit::Four(v) => v, 99 | } 100 | } 101 | } 102 | 103 | impl<'a, V> From<&'a [V]> for Digit 104 | where 105 | V: Clone, 106 | { 107 | fn from(slice: &'a [V]) -> Digit { 108 | match slice { 109 | [v0] => Digit::One([v0.clone()]), 110 | [v0, v1] => Digit::Two([v0.clone(), v1.clone()]), 111 | [v0, v1, v2] => Digit::Three([v0.clone(), v1.clone(), v2.clone()]), 112 | [v0, v1, v2, v3] => Digit::Four([v0.clone(), v1.clone(), v2.clone(), v3.clone()]), 113 | _ => panic!("immposible to create digit from of size: {}", slice.len()), 114 | } 115 | } 116 | } 117 | 118 | impl<'a, R, V: Measured> From<&'a Node> for Digit> 119 | where 120 | R: Refs, 121 | V: Measured, 122 | { 123 | fn from(node: &'a Node) -> Digit> { 124 | match node.as_ref() { 125 | NodeInner::Leaf(..) => Digit::One([node.clone()]), 126 | NodeInner::Node2 { left, right, .. } => Digit::Two([left.clone(), right.clone()]), 127 | NodeInner::Node3 { 128 | left, 129 | middle, 130 | right, 131 | .. 132 | } => Digit::Three([left.clone(), middle.clone(), right.clone()]), 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/iter.rs: -------------------------------------------------------------------------------- 1 | use std::collections::VecDeque; 2 | use std::iter::FusedIterator; 3 | 4 | use super::FingerTree; 5 | use crate::measure::Measured; 6 | use crate::node::{Node, NodeInner}; 7 | use crate::reference::Refs; 8 | use crate::tree::Tree; 9 | 10 | enum IterFrame 11 | where 12 | R: Refs, 13 | V: Measured, 14 | { 15 | Node(Node), 16 | Tree(Tree), 17 | } 18 | 19 | impl<'a, R, V> From<&'a Node> for IterFrame 20 | where 21 | R: Refs, 22 | V: Measured, 23 | { 24 | fn from(node: &'a Node) -> Self { 25 | IterFrame::Node(node.clone()) 26 | } 27 | } 28 | 29 | impl<'a, R, V> From<&'a Tree> for IterFrame 30 | where 31 | R: Refs, 32 | V: Measured, 33 | { 34 | fn from(tree: &'a Tree) -> Self { 35 | IterFrame::Tree(tree.clone()) 36 | } 37 | } 38 | 39 | pub struct Iter 40 | where 41 | R: Refs, 42 | V: Measured, 43 | { 44 | frames: VecDeque>, 45 | } 46 | 47 | impl Iter 48 | where 49 | R: Refs, 50 | V: Measured, 51 | { 52 | pub(crate) fn new(ft: &FingerTree) -> Self { 53 | let mut frames = VecDeque::new(); 54 | frames.push_back(IterFrame::Tree(ft.rec.clone())); 55 | Iter { frames } 56 | } 57 | 58 | fn push_back>>(&mut self, frame: F) { 59 | self.frames.push_back(frame.into()) 60 | } 61 | 62 | fn push_front>>(&mut self, frame: F) { 63 | self.frames.push_front(frame.into()) 64 | } 65 | } 66 | 67 | impl FusedIterator for Iter 68 | where 69 | R: Refs, 70 | V: Measured, 71 | { 72 | } 73 | 74 | impl Iterator for Iter 75 | where 76 | R: Refs, 77 | V: Measured, 78 | { 79 | type Item = V; 80 | 81 | fn next(&mut self) -> Option { 82 | loop { 83 | match self.frames.pop_back()? { 84 | IterFrame::Node(node) => match node.as_ref() { 85 | NodeInner::Leaf(value) => return Some(value.clone()), 86 | NodeInner::Node2 { left, right, .. } => { 87 | self.push_back(right); 88 | self.push_back(left); 89 | continue; 90 | } 91 | NodeInner::Node3 { 92 | left, 93 | middle, 94 | right, 95 | .. 96 | } => { 97 | self.push_back(right); 98 | self.push_back(middle); 99 | self.push_back(left); 100 | continue; 101 | } 102 | }, 103 | IterFrame::Tree(tree) => match tree { 104 | Tree::Empty => continue, 105 | Tree::Single(node) => { 106 | self.push_back(&node); 107 | continue; 108 | } 109 | Tree::Deep(deep) => { 110 | for node in deep.right.as_ref().iter().rev() { 111 | self.push_back(node); 112 | } 113 | self.push_back(&deep.spine); 114 | for node in deep.left.as_ref().iter().rev() { 115 | self.push_back(node); 116 | } 117 | continue; 118 | } 119 | }, 120 | } 121 | } 122 | } 123 | } 124 | 125 | impl DoubleEndedIterator for Iter 126 | where 127 | R: Refs, 128 | V: Measured, 129 | { 130 | fn next_back(&mut self) -> Option { 131 | loop { 132 | match self.frames.pop_front()? { 133 | IterFrame::Node(node) => match node.as_ref() { 134 | NodeInner::Leaf(value) => return Some(value.clone()), 135 | NodeInner::Node2 { left, right, .. } => { 136 | self.push_front(left); 137 | self.push_front(right); 138 | continue; 139 | } 140 | NodeInner::Node3 { 141 | left, 142 | middle, 143 | right, 144 | .. 145 | } => { 146 | self.push_front(left); 147 | self.push_front(middle); 148 | self.push_front(right); 149 | continue; 150 | } 151 | }, 152 | IterFrame::Tree(tree) => match tree { 153 | Tree::Empty => continue, 154 | Tree::Single(node) => { 155 | self.push_front(&node); 156 | continue; 157 | } 158 | Tree::Deep(deep) => { 159 | for node in deep.left.as_ref() { 160 | self.push_front(node); 161 | } 162 | self.push_front(&deep.spine); 163 | for node in deep.right.as_ref() { 164 | self.push_front(node); 165 | } 166 | continue; 167 | } 168 | }, 169 | } 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Finger Trees 2 | //! [![Build Status](https://travis-ci.org/aslpavel/fingertree-rs.svg?branch=master)](https://travis-ci.org/aslpavel/fingertree-rs) 3 | //! [![Coverage Status](https://coveralls.io/repos/github/aslpavel/fingertree-rs/badge.svg?branch=master)](https://coveralls.io/github/aslpavel/fingertree-rs?branch=master) 4 | //! 5 | //! Finger trees is a functional representation of persistent sequences 6 | //! supporting access to the ends in amortized constant time, and concatenation 7 | //! and splitting in time logarithmic in the size of the smaller piece. It also 8 | //! has [`split`](struct.FingerTree.html#method.split) operation defined in general 9 | //! form, which can be used to implement sequence, priority queue, search tree, 10 | //! priority search queue and more data structures. 11 | //! 12 | //! ## Links: 13 | //! - Original paper: [Finger Trees: A Simple General-purpose Data Structure](http://www.staff.city.ac.uk/~ross/papers/FingerTree.html) 14 | //! - Wikipedia article: [FingerTree](https://en.wikipedia.org/wiki/Finger_tree) 15 | //! 16 | //! ## Notes: 17 | //! - This implementation does not use non-regular recursive types as implementation 18 | //! described in the paper. As rust's monomorphization does not play well with such types. 19 | //! - Implementation abstracts over reference counted types `Rc/Arc`. Using type family trick. 20 | //! - Uses strict spine in implementation. 21 | //! - Iterator returns cloned value, and in general this implementation assumes that value 22 | //! stored in a tree is cheaply clonable, if it is not you can always put it in a `Rc/Arc` or 23 | //! anything else. 24 | //! 25 | //! ## Examples: 26 | //! ```rust 27 | //! # use std::iter::FromIterator; 28 | //! use fingertrees::measure::Size; 29 | //! use fingertrees::monoid::Sum; 30 | //! use fingertrees::{FingerTree, Measured, RcRefs}; 31 | //! 32 | //! // construct `Rc` based finger tree with `Size` measure 33 | //! let ft: FingerTree = vec!["one", "two", "three", "four", "five"] 34 | //! .into_iter() 35 | //! .map(Size) 36 | //! .collect(); 37 | //! assert_eq!(ft.measure(), Sum(5)); 38 | //! 39 | //! // split with predicate 40 | //! let (left, right) = ft.split(|measure| *measure > Sum(2)); 41 | //! assert_eq!(left.measure(), Sum(2)); 42 | //! assert_eq!(Vec::from_iter(&left), vec![Size("one"), Size("two")]); 43 | //! assert_eq!(right.measure(), Sum(3)); 44 | //! assert_eq!(Vec::from_iter(&right), vec![Size("three"), Size("four"), Size("five")]); 45 | //! 46 | //! // concatenate 47 | //! assert_eq!(ft, left + right); 48 | //! 49 | //! // push values 50 | //! assert_eq!( 51 | //! ft.push_left(Size("left")).push_right(Size("right")), 52 | //! vec!["left", "one", "two", "three", "four", "five", "right"] 53 | //! .into_iter() 54 | //! .map(Size) 55 | //! .collect(), 56 | //! ); 57 | //! ``` 58 | #![deny(missing_docs)] 59 | #![deny(warnings)] 60 | 61 | mod digit; 62 | mod iter; 63 | pub mod measure; 64 | pub mod monoid; 65 | mod node; 66 | mod reference; 67 | mod tree; 68 | 69 | #[cfg(test)] 70 | mod test; 71 | 72 | pub use crate::measure::Measured; 73 | pub use crate::monoid::Monoid; 74 | pub use crate::node::NodeInner; 75 | pub use crate::reference::{ArcRefs, RcRefs, Ref, Refs}; 76 | pub use crate::tree::TreeInner; 77 | 78 | pub mod rc { 79 | //! `Rc` based implementation of `FingerTree` 80 | 81 | /// FingerTree based on `Rc` references 82 | pub type FingerTree = super::FingerTree; 83 | } 84 | 85 | pub mod sync { 86 | //! `Arc` based implementation of `FingerTree` 87 | 88 | /// FingerTree based on `Arc` references 89 | /// 90 | /// This implementation becomes `{Send|Sync}` if `V: Send + Sync, V::Measure: Send + Sync` 91 | pub type FingerTree = super::FingerTree; 92 | } 93 | 94 | use std::fmt; 95 | use std::iter::FromIterator; 96 | use std::ops::Add; 97 | 98 | use crate::iter::Iter; 99 | use crate::node::Node; 100 | use crate::tree::Tree; 101 | 102 | /// FingerTree implementation 103 | /// 104 | /// FingerTree is parametrized by two type parameters 105 | /// - `R` - type family trick which determines type of references used in 106 | /// implementation. This crate implements [`ArcRefs`](enum.ArcRefs.html) which is based 107 | /// on `Arc` atomic reference counter, and [`RcRefs`](enum.RcRefs.html) which is based 108 | /// on `Rc`. 109 | /// - `V` - value type which must be measurable and cheaply clonable. 110 | pub struct FingerTree 111 | where 112 | R: Refs, 113 | V: Measured, 114 | { 115 | pub(crate) rec: Tree, 116 | } 117 | 118 | impl Clone for FingerTree 119 | where 120 | R: Refs, 121 | V: Measured, 122 | { 123 | fn clone(&self) -> Self { 124 | FingerTree { 125 | rec: self.rec.clone(), 126 | } 127 | } 128 | } 129 | 130 | impl FingerTree 131 | where 132 | R: Refs, 133 | V: Measured, 134 | { 135 | /// Constructs a new, empty `FingerTree` 136 | /// 137 | /// Complexity: `O(1)` 138 | pub fn new() -> Self { 139 | FingerTree { rec: Tree::empty() } 140 | } 141 | 142 | /// Returns `true` if finger tree is empty 143 | /// 144 | /// Complexity: `O(1)` 145 | pub fn is_empty(&self) -> bool { 146 | matches!(self.rec, Tree::Empty) 147 | } 148 | 149 | /// Creates new tree with value prepended to the left side of the tree 150 | /// 151 | /// Amortized complexity: `O(1)` 152 | pub fn push_left(&self, value: V) -> Self { 153 | FingerTree { 154 | rec: self.rec.push_left(Node::leaf(value)), 155 | } 156 | } 157 | 158 | /// Creates new tree with value prepended to the right side of the tree 159 | /// 160 | /// Amortized complexity: `O(1)` 161 | pub fn push_right(&self, value: V) -> Self { 162 | FingerTree { 163 | rec: self.rec.push_right(Node::leaf(value)), 164 | } 165 | } 166 | 167 | /// Destructure tree into a tuple with first element of it containing first 168 | /// element from the left side of the tree, and second element contains tree 169 | /// with reset of the elements 170 | /// 171 | /// Amortized complexity: `O(1)` 172 | pub fn view_left(&self) -> Option<(V, Self)> { 173 | let (head, tail) = self.rec.view_left()?; 174 | match head.as_ref() { 175 | NodeInner::Leaf(value) => Some((value.clone(), FingerTree { rec: tail })), 176 | _ => unreachable!("not leaf returned from top level of the finger-tree"), 177 | } 178 | } 179 | 180 | /// Destructure tree into a tuple with first element of it containing first 181 | /// element from the right side of the tree, and second element contains tree 182 | /// with reset of the elements 183 | /// 184 | /// Amortized complexity: `O(1)` 185 | pub fn view_right(&self) -> Option<(V, Self)> { 186 | let (head, tail) = self.rec.view_right()?; 187 | match head.as_ref() { 188 | NodeInner::Leaf(value) => Some((value.clone(), FingerTree { rec: tail })), 189 | _ => unreachable!("not leaf returned from top level of the finger-tree"), 190 | } 191 | } 192 | 193 | /// Destructure tree into two three, using provided predicate. 194 | /// 195 | /// Predicate must be monotonic function accepting accumulated measure of elements 196 | /// and changing its value from `false` to `true`. This function basically behave 197 | /// as if we would iterate all elements from left to right, and accumulating measure 198 | /// of all iterated elements, calling predicate on this accumulated value and once 199 | /// its value flips from `false` to `true` we stop iteration and form two trees 200 | /// from already iterated elements and the rest of the elements. 201 | /// 202 | /// Complexity: `O(ln(N))` 203 | pub fn split(&self, mut pred: F) -> (FingerTree, FingerTree) 204 | where 205 | F: FnMut(&V::Measure) -> bool, 206 | { 207 | if self.is_empty() { 208 | (Self::new(), Self::new()) 209 | } else if pred(&self.measure()) { 210 | let (l, x, r) = self.rec.split(V::Measure::unit(), &mut pred); 211 | ( 212 | FingerTree { rec: l }, 213 | FingerTree { 214 | rec: r.push_left(x), 215 | }, 216 | ) 217 | } else { 218 | (self.clone(), Self::new()) 219 | } 220 | } 221 | 222 | /// partial logic from `.split(...)` with only **left** part returned 223 | pub fn split_left(&self, mut pred: F) -> FingerTree 224 | where 225 | F: FnMut(&V::Measure) -> bool, 226 | { 227 | if self.is_empty() { 228 | Self::new() 229 | } else if pred(&self.measure()) { 230 | let (l, _x) = self.rec.split_left(V::Measure::unit(), &mut pred); 231 | FingerTree { rec: l } 232 | } else { 233 | self.clone() 234 | } 235 | } 236 | 237 | /// partial logic from `.split(...)` with only **right** part returned 238 | pub fn split_right(&self, mut pred: F) -> FingerTree 239 | where 240 | F: FnMut(&V::Measure) -> bool, 241 | { 242 | if self.is_empty() { 243 | Self::new() 244 | } else if pred(&self.measure()) { 245 | let (_m, x, r) = self.rec.split_right(V::Measure::unit(), &mut pred); 246 | 247 | FingerTree { 248 | rec: r.push_left(x), 249 | } 250 | } else { 251 | Self::new() 252 | } 253 | } 254 | 255 | /// Find element for which predicate function `pred` flips from `false` to `true` 256 | pub fn find(&self, mut pred: F) -> Option<&V> 257 | where 258 | F: FnMut(&V::Measure) -> bool, 259 | { 260 | if self.is_empty() || !pred(&self.measure()) { 261 | None 262 | } else { 263 | Some(self.rec.find(V::Measure::unit(), &mut pred)) 264 | } 265 | } 266 | 267 | /// Construct new finger tree which is concatenation of `self` and `other` 268 | /// 269 | /// Complexity: `O(ln(N))` 270 | pub fn concat(&self, other: &Self) -> Self { 271 | FingerTree { 272 | rec: Tree::concat(&self.rec, &mut ::std::iter::empty(), &other.rec), 273 | } 274 | } 275 | 276 | /// Double ended iterator visiting all elements of the tree from left to right 277 | pub fn iter(&self) -> Iter { 278 | Iter::new(self) 279 | } 280 | } 281 | 282 | impl Measured for FingerTree 283 | where 284 | R: Refs, 285 | V: Measured, 286 | { 287 | type Measure = V::Measure; 288 | 289 | fn measure(&self) -> Self::Measure { 290 | self.rec.measure() 291 | } 292 | } 293 | 294 | impl<'a, 'b, R, V> Add<&'b FingerTree> for &'a FingerTree 295 | where 296 | R: Refs, 297 | V: Measured, 298 | { 299 | type Output = FingerTree; 300 | 301 | fn add(self, other: &'b FingerTree) -> Self::Output { 302 | self.concat(other) 303 | } 304 | } 305 | 306 | impl Add> for FingerTree 307 | where 308 | R: Refs, 309 | V: Measured, 310 | { 311 | type Output = FingerTree; 312 | 313 | fn add(self, other: Self) -> Self::Output { 314 | self.concat(&other) 315 | } 316 | } 317 | 318 | impl PartialEq for FingerTree 319 | where 320 | R: Refs, 321 | V: Measured + PartialEq, 322 | { 323 | fn eq(&self, other: &FingerTree) -> bool { 324 | self.iter().zip(other).all(|(a, b)| a == b) 325 | } 326 | } 327 | 328 | impl Eq for FingerTree 329 | where 330 | R: Refs, 331 | V: Measured + Eq, 332 | { 333 | } 334 | 335 | impl<'a, R, V> IntoIterator for &'a FingerTree 336 | where 337 | R: Refs, 338 | V: Measured, 339 | { 340 | type Item = V; 341 | type IntoIter = Iter; 342 | 343 | fn into_iter(self) -> Self::IntoIter { 344 | self.iter() 345 | } 346 | } 347 | 348 | impl IntoIterator for FingerTree 349 | where 350 | R: Refs, 351 | V: Measured, 352 | { 353 | type Item = V; 354 | type IntoIter = Iter; 355 | 356 | fn into_iter(self) -> Self::IntoIter { 357 | self.iter() 358 | } 359 | } 360 | 361 | impl FromIterator for FingerTree 362 | where 363 | R: Refs, 364 | V: Measured, 365 | { 366 | fn from_iter>(iter: I) -> Self { 367 | iter.into_iter() 368 | .fold(FingerTree::new(), |ft, item| ft.push_right(item)) 369 | } 370 | } 371 | 372 | impl<'a, R, V> From<&'a [V]> for FingerTree 373 | where 374 | R: Refs, 375 | V: Measured, 376 | { 377 | fn from(vals: &'a [V]) -> Self { 378 | let mut nodes: Vec<_> = vals.iter().map(|val| Node::leaf(val.clone())).collect(); 379 | Self { 380 | rec: tree::build(nodes.as_mut()), 381 | } 382 | } 383 | } 384 | 385 | impl fmt::Debug for FingerTree 386 | where 387 | R: Refs, 388 | V: Measured + fmt::Debug, 389 | { 390 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 391 | write!(f, "FingerTree")?; 392 | f.debug_list().entries(self.iter()).finish() 393 | } 394 | } 395 | 396 | impl Default for FingerTree 397 | where 398 | R: Refs, 399 | V: Measured, 400 | { 401 | fn default() -> Self { 402 | FingerTree::new() 403 | } 404 | } 405 | -------------------------------------------------------------------------------- /src/measure.rs: -------------------------------------------------------------------------------- 1 | //! [`Measured`](measure/trait.Measured.html) trait and implementations 2 | use std::fmt; 3 | use std::ops::Deref; 4 | 5 | use crate::monoid::{Monoid, Sum}; 6 | 7 | /// Measured definition 8 | /// 9 | /// Type implementing `Measured` are basically stating that they have associated 10 | /// monoidal measure with them. And both type itself and measure must be 11 | /// **cheaply clonable**, otherwise you can just wrap them in `Arc|Rc` 12 | pub trait Measured: Clone { 13 | /// Measure type 14 | type Measure: Monoid + Clone; 15 | 16 | /// Associated measure with given value 17 | fn measure(&self) -> Self::Measure; 18 | } 19 | 20 | // impl Measured for T 21 | // where 22 | // T: Deref, 23 | // T::Target: Measured, 24 | // { 25 | // type Measure = ::Measure; 26 | 27 | // fn measure(&self) -> Self::Measure { 28 | // (*self).measure() 29 | // } 30 | // } 31 | 32 | /// 33 | #[derive(Clone, PartialEq, Eq)] 34 | pub struct Size(pub T); 35 | 36 | impl fmt::Debug for Size 37 | where 38 | T: fmt::Debug, 39 | { 40 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 41 | self.0.fmt(f) 42 | } 43 | } 44 | 45 | impl Measured for Size 46 | where 47 | T: Clone, 48 | { 49 | type Measure = Sum; 50 | 51 | fn measure(&self) -> Self::Measure { 52 | Sum(1) 53 | } 54 | } 55 | 56 | impl Deref for Size { 57 | type Target = T; 58 | 59 | fn deref(&self) -> &Self::Target { 60 | &self.0 61 | } 62 | } 63 | 64 | impl Measured for &[T] { 65 | type Measure = T::Measure; 66 | 67 | fn measure(&self) -> Self::Measure { 68 | self.iter() 69 | .fold(T::Measure::unit(), |acc, val| acc.join(&val.measure())) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/monoid.rs: -------------------------------------------------------------------------------- 1 | //! [`Monoid`](monoid/trait.Monoid.html) trait and implementations 2 | use std::ops::{Add, Deref}; 3 | 4 | /// Monoid definition 5 | /// 6 | /// Monoid is a tuple of `(S, O, I)` where: 7 | /// - `S` - set of elements 8 | /// - `O` - binary operation on S `S x S -> S`, here called `join` 9 | /// - `I` - identity element of this monoid, here called `unit` 10 | /// 11 | /// Every monoid implementation should satisfy following laws: 12 | /// - **associativity**: `a + (b + c) == (a + b) + c` 13 | /// - **identity element**: `unit + a == a + unit == a` 14 | pub trait Monoid { 15 | /// `unit` or `identity` element of monoid 16 | fn unit() -> Self; 17 | /// `join` operation of `Monoid` 18 | fn join(&self, other: &Self) -> Self; 19 | } 20 | 21 | // impl Monoid for (A, B) 22 | // where 23 | // A: Monoid, 24 | // B: Monoid, 25 | // { 26 | // fn unit() -> Self { 27 | // (A::unit(), B::unit()) 28 | // } 29 | 30 | // fn join(&self, other: &Self) -> Self { 31 | // (self.0.join(&other.0), self.1.join(&other.1)) 32 | // } 33 | // } 34 | 35 | /// Monoid formed by `Add::add` operation and `Default::default()` identity element 36 | #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] 37 | pub struct Sum(pub T); 38 | 39 | impl Monoid for Sum 40 | where 41 | for<'a> &'a T: Add, 42 | T: Default, 43 | { 44 | fn unit() -> Self { 45 | Sum(T::default()) 46 | } 47 | 48 | fn join(&self, other: &Self) -> Self { 49 | Sum(&self.0 + &other.0) 50 | } 51 | } 52 | 53 | impl Deref for Sum { 54 | type Target = T; 55 | 56 | #[inline] 57 | fn deref(&self) -> &Self::Target { 58 | &self.0 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/node.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | 3 | use crate::measure::Measured; 4 | use crate::monoid::Monoid; 5 | use crate::reference::{Ref, Refs}; 6 | 7 | /// Only visible to define custom [`Refs`](trait.Refs.html) 8 | pub enum NodeInner 9 | where 10 | R: Refs, 11 | V: Measured, 12 | { 13 | #[doc(hidden)] 14 | Leaf(V), 15 | #[doc(hidden)] 16 | Node2 { 17 | measure: V::Measure, 18 | left: Node, 19 | right: Node, 20 | }, 21 | #[doc(hidden)] 22 | Node3 { 23 | measure: V::Measure, 24 | left: Node, 25 | middle: Node, 26 | right: Node, 27 | }, 28 | } 29 | 30 | pub struct Node 31 | where 32 | R: Refs, 33 | V: Measured, 34 | { 35 | inner: R::Node, 36 | } 37 | 38 | impl Node 39 | where 40 | R: Refs, 41 | V: Measured, 42 | { 43 | pub(crate) fn leaf(value: V) -> Self { 44 | Node { 45 | inner: R::Node::new(NodeInner::Leaf(value)), 46 | } 47 | } 48 | 49 | pub(crate) fn node2(left: Self, right: Self) -> Self { 50 | let measure = left.measure().join(&right.measure()); 51 | Node { 52 | inner: R::Node::new(NodeInner::Node2 { 53 | measure, 54 | left, 55 | right, 56 | }), 57 | } 58 | } 59 | 60 | pub(crate) fn node3(left: Self, middle: Self, right: Self) -> Self { 61 | let measure = left 62 | .measure() 63 | .join(&middle.measure()) 64 | .join(&right.measure()); 65 | Node { 66 | inner: R::Node::new(NodeInner::Node3 { 67 | measure, 68 | left, 69 | middle, 70 | right, 71 | }), 72 | } 73 | } 74 | 75 | pub(crate) fn find(&self, measure: V::Measure, pred: &mut F) -> &V 76 | where 77 | F: FnMut(&V::Measure) -> bool, 78 | { 79 | match self.as_ref() { 80 | NodeInner::Leaf(leaf) => leaf, 81 | NodeInner::Node2 { left, right, .. } => { 82 | let left_measure = measure.join(&left.measure()); 83 | if pred(&left_measure) { 84 | left.find(measure, pred) 85 | } else { 86 | right.find(left_measure, pred) 87 | } 88 | } 89 | NodeInner::Node3 { 90 | left, 91 | middle, 92 | right, 93 | .. 94 | } => { 95 | let left_measure = measure.join(&left.measure()); 96 | if pred(&left_measure) { 97 | return left.find(measure, pred); 98 | } 99 | let middle_measure = left_measure.join(&middle.measure()); 100 | if pred(&middle_measure) { 101 | return middle.find(left_measure, pred); 102 | } 103 | right.find(middle_measure, pred) 104 | } 105 | } 106 | } 107 | 108 | /// Lift iterator of nodes into iterator of nodes, which are one level deeper 109 | /// 110 | /// NOTE: will panic on the iterator with less than two elements 111 | pub(crate) fn lift(iter: I) -> LiftNodesIter 112 | where 113 | I: IntoIterator>, 114 | { 115 | LiftNodesIter::new(iter.into_iter()) 116 | } 117 | } 118 | 119 | impl Clone for Node 120 | where 121 | R: Refs, 122 | V: Measured, 123 | { 124 | fn clone(&self) -> Self { 125 | Node { 126 | inner: self.inner.clone(), 127 | } 128 | } 129 | } 130 | 131 | impl Measured for Node 132 | where 133 | R: Refs, 134 | V: Measured, 135 | { 136 | type Measure = V::Measure; 137 | 138 | fn measure(&self) -> Self::Measure { 139 | match self.as_ref() { 140 | NodeInner::Leaf(value) => value.measure(), 141 | NodeInner::Node2 { measure, .. } => measure.clone(), 142 | NodeInner::Node3 { measure, .. } => measure.clone(), 143 | } 144 | } 145 | } 146 | 147 | impl AsRef> for Node 148 | where 149 | R: Refs, 150 | V: Measured, 151 | { 152 | fn as_ref(&self) -> &NodeInner { 153 | &self.inner 154 | } 155 | } 156 | 157 | // Iterator decorator which takes iterator of `Nodes` and make them one level deeper (lift) 158 | // by combining adjacent nodes. What we want is essentially 159 | // ``` 160 | // nodes :: [a] -> [Node a] 161 | // nodes [a, b] = [Node2 a b] 162 | // nodes [a, b, c] = [Node3 a b c] 163 | // nodes [a, b, c, d] = [Node2 a b, Node2 c d] 164 | // nodes (a : b : c : xs) = Node3 a b c : nodes xs 165 | // ``` 166 | pub(crate) struct LiftNodesIter 167 | where 168 | I: Iterator>, 169 | R: Refs, 170 | V: Measured, 171 | { 172 | buff: [Option>; 5], // look ahead ring buffer 173 | index: u8, // current index in buffer 174 | left: u8, // nodes left in buffer 175 | iter: I, 176 | } 177 | 178 | impl LiftNodesIter 179 | where 180 | I: Iterator>, 181 | R: Refs, 182 | V: Measured, 183 | { 184 | fn new(mut iter: I) -> Self { 185 | let buff = [ 186 | iter.next(), 187 | iter.next(), 188 | iter.next(), 189 | iter.next(), 190 | iter.next(), 191 | ]; 192 | let left = buff.iter().map(|n| if n.is_some() { 1 } else { 0 }).sum(); 193 | LiftNodesIter { 194 | buff, 195 | index: 0, 196 | left, 197 | iter, 198 | } 199 | } 200 | 201 | fn buff_next(&mut self) -> Node { 202 | let next = self.iter.next(); 203 | if next.is_none() { 204 | self.left -= 1; 205 | } 206 | let node = mem::replace(&mut self.buff[self.index as usize], next).unwrap(); 207 | self.index = (self.index + 1) % 5; 208 | node 209 | } 210 | } 211 | 212 | impl Iterator for LiftNodesIter 213 | where 214 | I: Iterator>, 215 | R: Refs, 216 | V: Measured, 217 | { 218 | type Item = Node; 219 | 220 | fn next(&mut self) -> Option { 221 | match self.left { 222 | 0 => None, 223 | 1 => panic!("Node::lift is called on a single element interator"), 224 | 2 | 4 => Some(Node::node2(self.buff_next(), self.buff_next())), 225 | _ => Some(Node::node3( 226 | self.buff_next(), 227 | self.buff_next(), 228 | self.buff_next(), 229 | )), 230 | } 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /src/reference.rs: -------------------------------------------------------------------------------- 1 | use std::ops::Deref; 2 | use std::rc::Rc; 3 | use std::sync::Arc; 4 | 5 | use crate::measure::Measured; 6 | use crate::node::NodeInner; 7 | use crate::tree::TreeInner; 8 | 9 | /// Interface that all reference types should implement 10 | pub trait Ref: Clone + Deref 11 | where 12 | Self::Target: Sized, 13 | { 14 | /// Construct reference from target type 15 | fn new(value: Self::Target) -> Self; 16 | } 17 | 18 | impl Ref for Rc { 19 | fn new(value: Self::Target) -> Self { 20 | Rc::new(value) 21 | } 22 | } 23 | 24 | impl Ref for Arc { 25 | fn new(value: Self::Target) -> Self { 26 | Arc::new(value) 27 | } 28 | } 29 | 30 | /// Interface which defines all reference types needed by finger tree implementation. 31 | /// 32 | /// By implementing this interface for your reference type you can use finger tree 33 | /// with your reference type. 34 | /// 35 | /// # Example: 36 | /// ``` 37 | /// use std::rc::Rc; 38 | /// use std::ops::Deref; 39 | /// use fingertrees::measure::Size; 40 | /// use fingertrees::{FingerTree, Measured, Ref, fingertree_define_refs}; 41 | /// 42 | /// // your custom reference type 43 | /// struct MyRef(Rc); 44 | /// 45 | /// impl Clone for MyRef { 46 | /// fn clone(&self) -> Self { 47 | /// MyRef(self.0.clone()) 48 | /// } 49 | /// } 50 | /// 51 | /// impl Deref for MyRef { 52 | /// type Target = T; 53 | /// fn deref(&self) -> &T { 54 | /// &*self.0 55 | /// } 56 | /// } 57 | /// 58 | /// impl Ref for MyRef { 59 | /// fn new(value: T) -> Self { 60 | /// MyRef(Rc::new(value)) 61 | /// } 62 | /// } 63 | /// 64 | /// // define type family for your reference 65 | /// fingertree_define_refs!(MyRefs, MyRef); 66 | /// 67 | /// // now you can construct fingertree using your reference type 68 | /// let _: FingerTree = (0..128).map(Size).collect(); 69 | /// ``` 70 | pub trait Refs: Sized 71 | where 72 | V: Measured, 73 | { 74 | /// Reference on a `Node` 75 | type Node: Ref>; 76 | /// Reference on a `Tree` 77 | type Tree: Ref>; 78 | } 79 | 80 | /// Helper macro to define custom [`Refs`](trait.Refs.html) for `FingerTree` 81 | #[macro_export] 82 | macro_rules! fingertree_define_refs { 83 | (pub $refs:ident, $ref:ident) => { 84 | /// References type family 85 | pub enum $refs {} 86 | fingertree_define_refs!(@refs_impl $refs, $ref); 87 | }; 88 | 89 | ($refs:ident, $ref:ident) => { 90 | /// References type family 91 | enum $refs {} 92 | fingertree_define_refs!(@refs_impl $refs, $ref); 93 | }; 94 | 95 | (@refs_impl $refs:ident, $ref:ident) => { 96 | impl $crate::Refs for $refs 97 | where 98 | V: $crate::measure::Measured, 99 | { 100 | type Node = $ref<$crate::NodeInner>; 101 | type Tree = $ref<$crate::TreeInner>; 102 | } 103 | }; 104 | } 105 | 106 | fingertree_define_refs!(pub RcRefs, Rc); 107 | fingertree_define_refs!(pub ArcRefs, Arc); 108 | -------------------------------------------------------------------------------- /src/test/mod.rs: -------------------------------------------------------------------------------- 1 | mod quickcheck; 2 | mod simple; 3 | 4 | use std::fmt; 5 | 6 | use super::FingerTree; 7 | use crate::measure::Measured; 8 | use crate::monoid::Monoid; 9 | use crate::node::{Node, NodeInner}; 10 | use crate::reference::Refs; 11 | use crate::tree::Tree; 12 | 13 | // constraint that is dynamic in current implementation but static in 14 | // original algorithm due to the fact that rust does not support 15 | // non-regular recursive types. Each level of spine should add one level 16 | // of depth to all nodes in current level. 17 | pub fn validate(ft: &FingerTree) 18 | where 19 | R: Refs, 20 | V: Measured, 21 | V::Measure: Eq + PartialEq + fmt::Debug, 22 | { 23 | fn validate_node_rec(depth: usize, node: &Node) 24 | where 25 | R: Refs, 26 | V: Measured, 27 | V::Measure: Eq + PartialEq + fmt::Debug, 28 | { 29 | if depth == 0 { 30 | match node.as_ref() { 31 | NodeInner::Leaf(..) => (), 32 | _ => panic!("all zero depth nodes must be leafs"), 33 | } 34 | } else { 35 | match node.as_ref() { 36 | NodeInner::Leaf(..) => panic!("leaf node with depth: {}", depth), 37 | NodeInner::Node2 { 38 | ref left, 39 | ref right, 40 | ref measure, 41 | } => { 42 | validate_node_rec(depth - 1, left); 43 | validate_node_rec(depth - 1, right); 44 | assert_eq!(measure.clone(), left.measure().join(&right.measure())); 45 | } 46 | NodeInner::Node3 { 47 | ref left, 48 | ref middle, 49 | ref right, 50 | ref measure, 51 | } => { 52 | validate_node_rec(depth - 1, left); 53 | validate_node_rec(depth - 1, middle); 54 | validate_node_rec(depth - 1, right); 55 | assert_eq!( 56 | measure.clone(), 57 | left.measure() 58 | .join(&middle.measure()) 59 | .join(&right.measure()) 60 | ); 61 | } 62 | } 63 | } 64 | } 65 | fn validate_ft_rec(depth: usize, ft: &Tree) 66 | where 67 | R: Refs, 68 | V: Measured, 69 | V::Measure: Eq + PartialEq + fmt::Debug, 70 | { 71 | match ft { 72 | Tree::Empty => (), 73 | Tree::Single(ref node) => validate_node_rec(depth, node), 74 | Tree::Deep(ref deep) => { 75 | let mut m = V::Measure::unit(); 76 | 77 | for node in deep.left.as_ref() { 78 | validate_node_rec(depth, node); 79 | m = m.join(&node.measure()); 80 | } 81 | 82 | validate_ft_rec(depth + 1, &deep.spine); 83 | m = m.join(&deep.spine.measure()); 84 | 85 | for node in deep.right.as_ref() { 86 | validate_node_rec(depth, node); 87 | m = m.join(&node.measure()); 88 | } 89 | 90 | assert_eq!(deep.measure.clone(), m); 91 | } 92 | } 93 | } 94 | validate_ft_rec(0, &ft.rec) 95 | } 96 | -------------------------------------------------------------------------------- /src/test/quickcheck.rs: -------------------------------------------------------------------------------- 1 | use crate::measure::{Measured, Size}; 2 | use crate::sync::FingerTree; 3 | use crate::test::validate; 4 | use quickcheck::{quickcheck, Arbitrary, Gen}; 5 | 6 | impl Arbitrary for FingerTree 7 | where 8 | V: Arbitrary + Measured + Sync, 9 | V::Measure: Send + Sync, 10 | { 11 | fn arbitrary(g: &mut Gen) -> Self { 12 | let vec: Vec = Arbitrary::arbitrary(g); 13 | vec.into_iter().collect() 14 | } 15 | 16 | fn shrink(&self) -> Box> { 17 | let vec: Vec<_> = self.into_iter().collect(); 18 | Box::new(vec.shrink().map(|v| v.into_iter().collect::())) 19 | } 20 | } 21 | 22 | impl Arbitrary for Size 23 | where 24 | V: Arbitrary, 25 | { 26 | fn arbitrary(g: &mut Gen) -> Self { 27 | Size(Arbitrary::arbitrary(g)) 28 | } 29 | 30 | fn shrink(&self) -> Box> { 31 | Box::new((**self).shrink().map(Size)) 32 | } 33 | } 34 | 35 | quickcheck! { 36 | fn split_and_concat(ft: FingerTree>, index: usize) -> bool { 37 | let len = *ft.measure(); 38 | let index = if len != 0 { index % len } else { 0 }; 39 | let (left, right) = ft.split(|m| **m > index); 40 | validate(&left); 41 | validate(&right); 42 | true 43 | // correct split 44 | && *left.measure() == index 45 | && *right.measure() == len - index 46 | // concat is inverse to split 47 | && left.concat(&right) == ft 48 | } 49 | 50 | fn from_slice(items: Vec>) -> bool { 51 | let ft = FingerTree::from(items.as_slice()); 52 | validate(&ft); 53 | items.as_slice().measure() == ft.measure() 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/simple.rs: -------------------------------------------------------------------------------- 1 | use crate::measure::{Measured, Size}; 2 | use crate::monoid::Monoid; 3 | use crate::rc::FingerTree as RcFingerTree; 4 | use crate::sync::FingerTree as ArcFingerTree; 5 | use crate::test::validate; 6 | 7 | const TEST_SIZE: usize = 512; 8 | 9 | #[test] 10 | fn queue() { 11 | let ft: RcFingerTree<_> = (0..TEST_SIZE).map(Size).collect(); 12 | validate(&ft); 13 | assert_eq!(*ft.measure(), TEST_SIZE); 14 | 15 | let mut count = 0; 16 | for (value, expected) in ft.iter().zip(0..) { 17 | assert_eq!(*value, expected); 18 | count += 1; 19 | } 20 | assert_eq!(*ft.measure(), count); 21 | } 22 | 23 | #[test] 24 | fn concat() { 25 | for split in 0..TEST_SIZE { 26 | let left: RcFingerTree<_> = (0..split).map(Size).collect(); 27 | let right: RcFingerTree<_> = (split..TEST_SIZE).map(Size).collect(); 28 | 29 | let ft = &left + &right; 30 | assert_eq!(ft.measure(), left.measure().join(&right.measure())); 31 | validate(&left); 32 | validate(&right); 33 | validate(&ft); 34 | 35 | for (value, expected) in ft.iter().zip(0..) { 36 | assert_eq!(*value, expected, "failed to concat: {:?} {:?}", left, right); 37 | } 38 | } 39 | } 40 | 41 | #[test] 42 | fn split() { 43 | let ft: RcFingerTree<_> = (0..TEST_SIZE).map(Size).collect(); 44 | for split in 0..TEST_SIZE { 45 | let (left, right) = ft.split(|m| **m > split); 46 | validate(&left); 47 | validate(&right); 48 | assert_eq!(*left.measure(), split); 49 | assert_eq!(*right.measure(), TEST_SIZE - split); 50 | assert_eq!(ft, &left + &right); 51 | } 52 | } 53 | 54 | #[test] 55 | fn split_left() { 56 | let ft: RcFingerTree<_> = (0..TEST_SIZE).map(Size).collect(); 57 | for split in 0..TEST_SIZE { 58 | let left = ft.split_left(|m| **m > split); 59 | validate(&left); 60 | assert_eq!(*left.measure(), split); 61 | } 62 | } 63 | 64 | #[test] 65 | fn split_right() { 66 | let ft: RcFingerTree<_> = (0..TEST_SIZE).map(Size).collect(); 67 | for split in 0..TEST_SIZE { 68 | let right = ft.split_right(|m| **m > split); 69 | validate(&right); 70 | assert_eq!(*right.measure(), TEST_SIZE - split); 71 | } 72 | } 73 | 74 | #[test] 75 | fn reversed() { 76 | let ft: RcFingerTree<_> = (0..TEST_SIZE).map(Size).collect(); 77 | assert_eq!( 78 | ft.iter().rev().collect::>(), 79 | (0..TEST_SIZE).map(Size).rev().collect::>() 80 | ); 81 | 82 | let mut iter = ft.iter(); 83 | assert_eq!( 84 | iter.by_ref().take(TEST_SIZE / 2).collect::>(), 85 | (0..TEST_SIZE / 2).map(Size).collect::>(), 86 | ); 87 | assert_eq!( 88 | iter.rev().collect::>(), 89 | (TEST_SIZE / 2..TEST_SIZE) 90 | .rev() 91 | .map(Size) 92 | .collect::>(), 93 | ); 94 | } 95 | 96 | #[test] 97 | fn find() { 98 | let ft: RcFingerTree<_> = (0..TEST_SIZE).map(Size).collect(); 99 | for index in 0..TEST_SIZE { 100 | assert_eq!(ft.find(|m| **m > index), Some(&Size(index))) 101 | } 102 | assert!(ft.find(|m| **m > TEST_SIZE).is_none()) 103 | } 104 | 105 | #[test] 106 | fn sync_send() { 107 | trait TestSend: Send {} 108 | impl TestSend for ArcFingerTree 109 | where 110 | V: Measured + Send + Sync, 111 | V::Measure: Send + Sync, 112 | { 113 | } 114 | 115 | trait TestSync: Sync {} 116 | impl TestSync for ArcFingerTree 117 | where 118 | V: Measured + Send + Sync, 119 | V::Measure: Send + Sync, 120 | { 121 | } 122 | 123 | fn is_sync() {} 124 | fn is_send() {} 125 | is_sync::>>(); 126 | is_send::>>(); 127 | } 128 | 129 | #[test] 130 | fn from_slice() { 131 | for size in 0..TEST_SIZE { 132 | let vals: Vec<_> = (0..size).map(Size).collect(); 133 | let one: RcFingerTree<_> = vals.iter().cloned().collect(); 134 | let two = RcFingerTree::from(vals.as_slice()); 135 | validate(&one); 136 | validate(&two); 137 | assert_eq!(one.measure(), two.measure()); 138 | assert_eq!(one, two); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /src/tree.rs: -------------------------------------------------------------------------------- 1 | use self::Tree::{Deep, Empty, Single}; 2 | use crate::digit::Digit; 3 | use crate::measure::Measured; 4 | use crate::monoid::Monoid; 5 | use crate::node::Node; 6 | use crate::reference::{Ref, Refs}; 7 | 8 | /// Only visible to define custom [`Refs`](trait.Refs.html) 9 | pub struct TreeInner 10 | where 11 | R: Refs, 12 | V: Measured, 13 | { 14 | pub(crate) measure: V::Measure, 15 | pub(crate) left: Digit>, 16 | pub(crate) spine: Tree, //TODO: lazy spine 17 | pub(crate) right: Digit>, 18 | } 19 | 20 | pub enum Tree 21 | where 22 | R: Refs, 23 | V: Measured, 24 | { 25 | Empty, 26 | Single(Node), 27 | Deep(R::Tree), 28 | } 29 | 30 | impl Measured for Tree 31 | where 32 | R: Refs, 33 | V: Measured, 34 | { 35 | type Measure = V::Measure; 36 | 37 | fn measure(&self) -> Self::Measure { 38 | match self { 39 | Empty => Self::Measure::unit(), 40 | Single(node) => node.measure(), 41 | Deep(deep) => deep.measure.clone(), 42 | } 43 | } 44 | } 45 | 46 | impl Clone for Tree 47 | where 48 | R: Refs, 49 | V: Measured, 50 | { 51 | fn clone(&self) -> Self { 52 | match self { 53 | Empty => Empty, 54 | Single(node) => Single(node.clone()), 55 | Deep(deep) => Deep(deep.clone()), 56 | } 57 | } 58 | } 59 | 60 | impl Tree 61 | where 62 | R: Refs, 63 | V: Measured, 64 | { 65 | pub(crate) fn empty() -> Self { 66 | Tree::Empty 67 | } 68 | 69 | pub(crate) fn single(node: Node) -> Self { 70 | Tree::Single(node) 71 | } 72 | 73 | pub(crate) fn deep( 74 | left: Digit>, 75 | spine: Tree, 76 | right: Digit>, 77 | ) -> Self { 78 | let measure = left.measure().join(&spine.measure()).join(&right.measure()); 79 | Tree::Deep(R::Tree::new(TreeInner { 80 | measure, 81 | left, 82 | spine, 83 | right, 84 | })) 85 | } 86 | 87 | pub(crate) fn push_left(&self, value: Node) -> Self { 88 | match self { 89 | Empty => Self::single(value), 90 | Single(other) => Self::deep( 91 | Digit::One([value]), 92 | Self::empty(), 93 | Digit::One([other.clone()]), 94 | ), 95 | Deep(deep) => { 96 | if let [l0, l1, l2, l3] = deep.left.as_ref() { 97 | Self::deep( 98 | Digit::Two([value, l0.clone()]), 99 | deep.spine 100 | .push_left(Node::node3(l1.clone(), l2.clone(), l3.clone())), 101 | deep.right.clone(), 102 | ) 103 | } else { 104 | Self::deep( 105 | &Digit::One([value]) + &deep.left, 106 | deep.spine.clone(), 107 | deep.right.clone(), 108 | ) 109 | } 110 | } 111 | } 112 | } 113 | 114 | pub(crate) fn push_right(&self, value: Node) -> Self { 115 | match self { 116 | Empty => Self::single(value), 117 | Single(other) => Self::deep( 118 | Digit::One([other.clone()]), 119 | Self::empty(), 120 | Digit::One([value]), 121 | ), 122 | Deep(deep) => { 123 | if let [r0, r1, r2, r3] = deep.right.as_ref() { 124 | Self::deep( 125 | deep.left.clone(), 126 | deep.spine 127 | .push_right(Node::node3(r0.clone(), r1.clone(), r2.clone())), 128 | Digit::Two([r3.clone(), value]), 129 | ) 130 | } else { 131 | Self::deep( 132 | deep.left.clone(), 133 | deep.spine.clone(), 134 | &deep.right + Digit::One([value]), 135 | ) 136 | } 137 | } 138 | } 139 | } 140 | 141 | // left element is not `Digit` because `Digit` cannot be empty, but left in current 142 | // position can be. 143 | fn deep_left(left: &[Node], spine: &Tree, right: &Digit>) -> Self { 144 | if left.is_empty() { 145 | match spine.view_left() { 146 | Some((head, tail)) => Self::deep((&head).into(), tail, right.clone()), 147 | None => Tree::from(right), 148 | } 149 | } else { 150 | Self::deep(left.into(), spine.clone(), right.clone()) 151 | } 152 | } 153 | 154 | pub(crate) fn view_left(&self) -> Option<(Node, Self)> { 155 | match self { 156 | Empty => None, 157 | Single(value) => Some((value.clone(), Tree::empty())), 158 | Deep(deep) => match deep.left.as_ref().split_first() { 159 | None => unreachable!("digit cannot be empty"), 160 | Some((head, tail)) => Some(( 161 | head.clone(), 162 | Self::deep_left(tail, &deep.spine, &deep.right), 163 | )), 164 | }, 165 | } 166 | } 167 | 168 | fn deep_right(left: &Digit>, spine: &Tree, right: &[Node]) -> Self { 169 | if right.is_empty() { 170 | match spine.view_right() { 171 | Some((head, tail)) => Self::deep(left.clone(), tail, (&head).into()), 172 | None => Tree::from(left), 173 | } 174 | } else { 175 | Self::deep(left.clone(), spine.clone(), right.into()) 176 | } 177 | } 178 | 179 | pub(crate) fn view_right(&self) -> Option<(Node, Self)> { 180 | match self { 181 | Empty => None, 182 | Single(value) => Some((value.clone(), Tree::empty())), 183 | Deep(deep) => match deep.right.as_ref().split_last() { 184 | None => unreachable!("digit cannot be empty"), 185 | Some((head, tail)) => Some(( 186 | head.clone(), 187 | Self::deep_right(&deep.left, &deep.spine, tail), 188 | )), 189 | }, 190 | } 191 | } 192 | 193 | pub(crate) fn split( 194 | &self, 195 | measure: V::Measure, 196 | pred: &mut F, 197 | ) -> (Tree, Node, Tree) 198 | where 199 | F: FnMut(&V::Measure) -> bool, 200 | { 201 | match self { 202 | Empty => unreachable!("recursive split of finger-tree called on empty tree"), 203 | Single(value) => (Tree::empty(), value.clone(), Tree::empty()), 204 | Deep(deep) => { 205 | // left 206 | let left_measure = measure.join(&deep.left.measure()); 207 | if pred(&left_measure) { 208 | let (l, x, r) = deep.left.split(measure, pred); 209 | return ( 210 | Tree::from(l), 211 | x.clone(), 212 | Self::deep_left(r, &deep.spine, &deep.right), 213 | ); 214 | } 215 | // spine 216 | let spine_measure = left_measure.join(&deep.spine.measure()); 217 | if pred(&spine_measure) { 218 | let (sl, sx, sr) = deep.spine.split(left_measure.clone(), pred); 219 | let sx = Digit::from(&sx); 220 | let (l, x, r) = sx.split(left_measure.join(&sl.measure()), pred); 221 | return ( 222 | Self::deep_right(&deep.left, &sl, l), 223 | x.clone(), 224 | Self::deep_left(r, &sr, &deep.right), 225 | ); 226 | } 227 | // right 228 | let (l, x, r) = deep.right.split(spine_measure, pred); 229 | ( 230 | Self::deep_right(&deep.left, &deep.spine, l), 231 | x.clone(), 232 | Tree::from(r), 233 | ) 234 | } 235 | } 236 | } 237 | 238 | pub(crate) fn split_left( 239 | &self, 240 | measure: V::Measure, 241 | pred: &mut F, 242 | ) -> (Tree, Node) 243 | where 244 | F: FnMut(&V::Measure) -> bool, 245 | { 246 | match self { 247 | Empty => unreachable!("recursive split of finger-tree called on empty tree"), 248 | Single(value) => (Tree::empty(), value.clone()), 249 | Deep(deep) => { 250 | // left 251 | let left_measure = measure.join(&deep.left.measure()); 252 | if pred(&left_measure) { 253 | let (l, x, _r) = deep.left.split(measure, pred); 254 | return (Tree::from(l), x.clone()); 255 | } 256 | // spine 257 | let spine_measure = left_measure.join(&deep.spine.measure()); 258 | if pred(&spine_measure) { 259 | let (sl, sx) = deep.spine.split_left(left_measure.clone(), pred); 260 | let sx = Digit::from(&sx); 261 | let (l, x, _r) = sx.split(left_measure.join(&sl.measure()), pred); 262 | return (Self::deep_right(&deep.left, &sl, l), x.clone()); 263 | } 264 | // right 265 | let (l, x, _r) = deep.right.split(spine_measure, pred); 266 | (Self::deep_right(&deep.left, &deep.spine, l), x.clone()) 267 | } 268 | } 269 | } 270 | 271 | pub(crate) fn split_right( 272 | &self, 273 | measure: V::Measure, 274 | pred: &mut F, 275 | ) -> (V::Measure, Node, Tree) 276 | where 277 | F: FnMut(&V::Measure) -> bool, 278 | { 279 | match self { 280 | Empty => unreachable!("recursive split of finger-tree called on empty tree"), 281 | Single(value) => (measure, value.clone(), Tree::empty()), 282 | Deep(deep) => { 283 | // left 284 | let left_measure = measure.join(&deep.left.measure()); 285 | if pred(&left_measure) { 286 | let (l, x, r) = deep.left.split(measure.to_owned(), pred); 287 | return ( 288 | measure.join(&l.measure()), 289 | x.clone(), 290 | Self::deep_left(r, &deep.spine, &deep.right), 291 | ); 292 | } 293 | // spine 294 | let spine_measure = left_measure.join(&deep.spine.measure()); 295 | if pred(&spine_measure) { 296 | let (slm, sx, sr) = deep.spine.split_right(left_measure.clone(), pred); 297 | let sx = Digit::from(&sx); 298 | let (l, x, r) = sx.split(slm.to_owned(), pred); 299 | return ( 300 | slm.join(&l.measure()), 301 | x.clone(), 302 | Self::deep_left(r, &sr, &deep.right), 303 | ); 304 | } 305 | // right 306 | let (l, x, r) = deep.right.split(spine_measure.to_owned(), pred); 307 | (spine_measure.join(&l.measure()), x.clone(), Tree::from(r)) 308 | } 309 | } 310 | } 311 | 312 | fn push_left_many(self, iter: &mut dyn Iterator>) -> Self { 313 | match iter.next() { 314 | None => self, 315 | Some(node) => self.push_left_many(iter).push_left(node), 316 | } 317 | } 318 | 319 | fn push_right_many(self, iter: &mut dyn Iterator>) -> Self { 320 | match iter.next() { 321 | None => self, 322 | Some(node) => self.push_right(node).push_right_many(iter), 323 | } 324 | } 325 | 326 | pub(crate) fn concat( 327 | left: &Self, 328 | mid: &mut dyn Iterator>, 329 | right: &Self, 330 | ) -> Self { 331 | match (left, right) { 332 | (Empty, _) => right.clone().push_left_many(mid), 333 | (_, Empty) => left.clone().push_right_many(mid), 334 | (Single(left), _) => right.clone().push_left_many(mid).push_left(left.clone()), 335 | (_, Single(right)) => left.clone().push_right_many(mid).push_right(right.clone()), 336 | (Deep(deep0), Deep(deep1)) => { 337 | let left = deep0.right.as_ref().iter().cloned(); 338 | let right = deep1.left.as_ref().iter().cloned(); 339 | Self::deep( 340 | deep0.left.clone(), 341 | Self::concat( 342 | &deep0.spine, 343 | &mut Node::lift(left.chain(mid).chain(right)), 344 | &deep1.spine, 345 | ), 346 | deep1.right.clone(), 347 | ) 348 | } 349 | } 350 | } 351 | 352 | pub(crate) fn find(&self, measure: V::Measure, pred: &mut F) -> &V 353 | where 354 | F: FnMut(&V::Measure) -> bool, 355 | { 356 | match self { 357 | Empty => unreachable!("recursive find of finger-tree called on empty tree"), 358 | Single(value) => value.find(measure, pred), 359 | Deep(deep) => { 360 | // left 361 | let left_measure = measure.join(&deep.left.measure()); 362 | if pred(&left_measure) { 363 | let (measure, node) = deep.left.find(measure, pred); 364 | return node.find(measure, pred); 365 | } 366 | // spine 367 | let spine_measure = left_measure.join(&deep.spine.measure()); 368 | if pred(&spine_measure) { 369 | return deep.spine.find(left_measure, pred); 370 | } 371 | // right 372 | let (measure, node) = deep.right.find(spine_measure, pred); 373 | node.find(measure, pred) 374 | } 375 | } 376 | } 377 | } 378 | 379 | impl From for Tree 380 | where 381 | R: Refs, 382 | T: AsRef<[Node]>, 383 | V: Measured, 384 | { 385 | fn from(slice: T) -> Self { 386 | slice 387 | .as_ref() 388 | .iter() 389 | .fold(Tree::empty(), |ft, v| ft.push_right(v.clone())) 390 | } 391 | } 392 | 393 | pub(crate) fn build(nodes: &mut [Node]) -> Tree 394 | where 395 | R: Refs, 396 | V: Measured, 397 | { 398 | match nodes { 399 | [] => Tree::empty(), 400 | [n] => Tree::single(n.clone()), 401 | [n0, n1] => Tree::deep( 402 | Digit::One([n0.clone()]), 403 | Tree::empty(), 404 | Digit::One([n1.clone()]), 405 | ), 406 | [n0, n1, n2] => Tree::deep( 407 | Digit::Two([n0.clone(), n1.clone()]), 408 | Tree::empty(), 409 | Digit::One([n2.clone()]), 410 | ), 411 | [n0, n1, n2, n3] => Tree::deep( 412 | Digit::Two([n0.clone(), n1.clone()]), 413 | Tree::empty(), 414 | Digit::Two([n2.clone(), n3.clone()]), 415 | ), 416 | [n0, n1, n2, n3, n4] => Tree::deep( 417 | Digit::Three([n0.clone(), n1.clone(), n2.clone()]), 418 | Tree::empty(), 419 | Digit::Two([n3.clone(), n4.clone()]), 420 | ), 421 | [n0, n1, n2, n3, n4, n5] => Tree::deep( 422 | Digit::Three([n0.clone(), n1.clone(), n2.clone()]), 423 | Tree::empty(), 424 | Digit::Three([n3.clone(), n4.clone(), n5.clone()]), 425 | ), 426 | [n0, n1, n2, n3, n4, n5, n6] => Tree::deep( 427 | Digit::Four([n0.clone(), n1.clone(), n2.clone(), n3.clone()]), 428 | Tree::empty(), 429 | Digit::Three([n4.clone(), n5.clone(), n6.clone()]), 430 | ), 431 | [n0, n1, n2, n3, n4, n5, n6, n7] => Tree::deep( 432 | Digit::Four([n0.clone(), n1.clone(), n2.clone(), n3.clone()]), 433 | Tree::empty(), 434 | Digit::Four([n4.clone(), n5.clone(), n6.clone(), n7.clone()]), 435 | ), 436 | [n0, n1, n2, n3, n4, n5, n6, n7, n8] => Tree::deep( 437 | Digit::Four([n0.clone(), n1.clone(), n2.clone(), n3.clone()]), 438 | Tree::single(Node::node2(n4.clone(), n5.clone())), 439 | Digit::Three([n6.clone(), n7.clone(), n8.clone()]), 440 | ), 441 | _ => { 442 | let mut start = 4; 443 | let end = nodes.len() - 4; 444 | let left = Digit::from(&nodes[..start]); 445 | let right = Digit::from(&nodes[end..]); 446 | // lift nodes in-place 447 | let mut offset = 0; 448 | loop { 449 | match end - start { 450 | 0 => break, 451 | 1 => unreachable!(), 452 | 2 => { 453 | let node = Node::node2(nodes[start].clone(), nodes[start + 1].clone()); 454 | nodes[offset] = node; 455 | start += 2; 456 | offset += 1; 457 | } 458 | 4 => { 459 | let n0 = Node::node2(nodes[start].clone(), nodes[start + 1].clone()); 460 | let n1 = Node::node2(nodes[start + 2].clone(), nodes[start + 3].clone()); 461 | nodes[offset] = n0; 462 | nodes[offset + 1] = n1; 463 | start += 4; 464 | offset += 2; 465 | } 466 | _ => { 467 | let node = Node::node3( 468 | nodes[start].clone(), 469 | nodes[start + 1].clone(), 470 | nodes[start + 2].clone(), 471 | ); 472 | nodes[offset] = node; 473 | start += 3; 474 | offset += 1; 475 | } 476 | } 477 | } 478 | Tree::deep(left, build(&mut nodes[..offset]), right) 479 | } 480 | } 481 | } 482 | --------------------------------------------------------------------------------