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);
}