pub mod ordered;
pub mod ordered_leaf;
pub trait Trie : ::std::marker::Sized {
type Item;
type Cursor: Cursor<Self>;
type MergeBuilder: MergeBuilder<Trie=Self>;
type TupleBuilder: TupleBuilder<Trie=Self, Item=Self::Item>;
fn keys(&self) -> usize;
fn tuples(&self) -> usize;
fn cursor(&self) -> Self::Cursor { self.cursor_from(0, self.keys()) }
fn cursor_from(&self, lower: usize, upper: usize) -> Self::Cursor;
fn merge(&self, other: &Self) -> Self {
let mut merger = Self::MergeBuilder::with_capacity(self, other);
merger.push_merge((self, 0, self.keys()), (other, 0, other.keys()));
merger.done()
}
}
pub trait Builder {
type Trie: Trie;
fn boundary(&mut self) -> usize;
fn done(self) -> Self::Trie;
}
pub trait MergeBuilder : Builder {
fn with_capacity(other1: &Self::Trie, other2: &Self::Trie) -> Self;
fn copy_range(&mut self, other: &Self::Trie, lower: usize, upper: usize);
fn push_merge(&mut self, other1: (&Self::Trie, usize, usize), other2: (&Self::Trie, usize, usize)) -> usize;
}
pub trait TupleBuilder : Builder {
type Item;
fn new() -> Self;
fn with_capacity(cap: usize) -> Self; fn push_tuple(&mut self, tuple: Self::Item);
}
pub trait Cursor<Storage> {
type Key;
fn key<'a>(&self, storage: &'a Storage) -> &'a Self::Key;
fn step(&mut self, storage: &Storage);
fn seek(&mut self, storage: &Storage, key: &Self::Key);
fn valid(&self, storage: &Storage) -> bool;
fn rewind(&mut self, storage: &Storage);
fn reposition(&mut self, storage: &Storage, lower: usize, upper: usize);
}
pub fn advance<T, F: Fn(&T)->bool>(slice: &[T], function: F) -> usize {
let small_limit = 8;
if slice.len() > small_limit && function(&slice[small_limit]) {
let mut index = small_limit + 1;
if index < slice.len() && function(&slice[index]) {
let mut step = 1;
while index + step < slice.len() && function(&slice[index + step]) {
index += step;
step = step << 1;
}
step = step >> 1;
while step > 0 {
if index + step < slice.len() && function(&slice[index + step]) {
index += step;
}
step = step >> 1;
}
index += 1;
}
index
}
else {
let limit = std::cmp::min(slice.len(), small_limit);
slice[..limit].iter().filter(|x| function(*x)).count()
}
}