1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
//! Traits and types for building trie-based indices.
//!
//! The trie structure has each each element of each layer indicate a range of elements
//! in the next layer. Similarly, ranges of elements in the layer itself may correspond
//! to single elements in the layer above.
pub mod ordered;
pub mod ordered_leaf;
// pub mod hashed;
// pub mod weighted;
// pub mod unordered;
/// A collection of tuples, and types for building and enumerating them.
///
/// There are some implicit assumptions about the elements in trie-structured data, mostly that
/// the items have some `(key, val)` structure. Perhaps we will nail these down better in the
/// future and get a better name for the trait.
pub trait Trie : ::std::marker::Sized {
/// The type of item from which the type is constructed.
type Item;
/// The type of cursor used to navigate the type.
type Cursor: Cursor<Self>;
/// The type used to merge instances of the type together.
type MergeBuilder: MergeBuilder<Trie=Self>;
/// The type used to assemble instances of the type from its `Item`s.
type TupleBuilder: TupleBuilder<Trie=Self, Item=Self::Item>;
/// The number of distinct keys, as distinct from the total number of tuples.
fn keys(&self) -> usize;
/// The total number of tuples in the collection.
fn tuples(&self) -> usize;
/// Returns a cursor capable of navigating the collection.
fn cursor(&self) -> Self::Cursor { self.cursor_from(0, self.keys()) }
/// Returns a cursor over a range of data, commonly used by others to restrict navigation to
/// sub-collections.
fn cursor_from(&self, lower: usize, upper: usize) -> Self::Cursor;
/// Merges two collections into a third.
///
/// Collections are allowed their own semantics for merging. For example, unordered collections
/// simply collect values, whereas weighted collections accumulate weights and discard elements
/// whose weights are zero.
fn merge(&self, other: &Self) -> Self {
let mut merger = Self::MergeBuilder::with_capacity(self, other);
// println!("{:?} and {:?}", self.keys(), other.keys());
merger.push_merge((self, 0, self.keys()), (other, 0, other.keys()));
merger.done()
}
}
/// A type used to assemble collections.
pub trait Builder {
/// The type of collection produced.
type Trie: Trie;
/// Requests a commitment to the offset of the current-most sub-collection.
///
/// This is most often used by parent collections to indicate that some set of values are now
/// logically distinct from the next set of values, and that the builder should acknowledge this
/// and report the limit (to store as an offset in the parent collection).
fn boundary(&mut self) -> usize;
/// Finalizes the building process and returns the collection.
fn done(self) -> Self::Trie;
}
/// A type used to assemble collections by merging other instances.
pub trait MergeBuilder : Builder {
/// Allocates an instance of the builder with sufficient capacity to contain the merged data.
fn with_capacity(other1: &Self::Trie, other2: &Self::Trie) -> Self;
/// Copies sub-collections of `other` into this collection.
fn copy_range(&mut self, other: &Self::Trie, lower: usize, upper: usize);
/// Merges two sub-collections into one sub-collection.
fn push_merge(&mut self, other1: (&Self::Trie, usize, usize), other2: (&Self::Trie, usize, usize)) -> usize;
}
/// A type used to assemble collections from ordered sequences of tuples.
pub trait TupleBuilder : Builder {
/// The type of item accepted for construction.
type Item;
/// Allocates a new builder.
fn new() -> Self;
/// Allocates a new builder with capacity for at least `cap` tuples.
fn with_capacity(cap: usize) -> Self; // <-- unclear how to set child capacities...
/// Inserts a new into the collection.
fn push_tuple(&mut self, tuple: Self::Item);
}
/// A type supporting navigation.
///
/// The precise meaning of this navigation is not defined by the trait. It is likely that having
/// navigated around, the cursor will be different in some other way, but the `Cursor` trait does
/// not explain how this is so.
pub trait Cursor<Storage> {
/// The type revealed by the cursor.
type Key;
/// Reveals the current key.
fn key<'a>(&self, storage: &'a Storage) -> &'a Self::Key;
/// Advances the cursor by one element.
fn step(&mut self, storage: &Storage);
/// Advances the cursor until the location where `key` would be expected.
fn seek(&mut self, storage: &Storage, key: &Self::Key);
/// Returns `true` if the cursor points at valid data. Returns `false` if the cursor is exhausted.
fn valid(&self, storage: &Storage) -> bool;
/// Rewinds the cursor to its initial state.
fn rewind(&mut self, storage: &Storage);
/// Repositions the cursor to a different range of values.
fn reposition(&mut self, storage: &Storage, lower: usize, upper: usize);
}