use super::Cursor;
#[derive(Debug)]
pub struct CursorList<K, V, T, R, C: Cursor<K, V, T, R>> {
_phantom: ::std::marker::PhantomData<(K, V, T, R)>,
cursors: Vec<(C, usize)>, equiv_keys: usize, equiv_vals: usize, valid_keys: usize, valid_vals: usize, }
impl<K, V, T, R, C: Cursor<K, V, T, R>> CursorList<K, V, T, R, C> where K: Ord, V: Ord {
pub fn new(cursors: Vec<C>, storage: &Vec<C::Storage>) -> Self {
let cursors_len = cursors.len();
let mut result = CursorList {
_phantom: ::std::marker::PhantomData,
cursors: cursors.into_iter().enumerate().map(|(i,c)| (c,i)).collect(),
equiv_keys: cursors_len,
equiv_vals: 0,
valid_keys: cursors_len,
valid_vals: 0,
};
result.tidy_keys(storage, cursors_len);
result
}
fn tidy_keys(&mut self, storage: &Vec<C::Storage>, prefix: usize) {
self.equiv_keys = 0;
let mut dirty = 0;
for index in 0 .. prefix {
if self.cursors[index].0.key_valid(&storage[self.cursors[index].1]) {
self.cursors.swap(dirty, index);
dirty += 1;
}
}
if prefix - dirty > 0 { for index in prefix .. self.valid_keys {
self.cursors.swap(index, index - (prefix - dirty));
}
}
self.valid_keys -= prefix - dirty;
if dirty > 0 {
let mut max_index = 0;
for index in 1 .. dirty {
if self.cursors[index].0.key(&storage[self.cursors[index].1]) > self.cursors[max_index].0.key(&storage[self.cursors[max_index].1]) {
max_index = index;
}
}
let mut beyond = dirty;
while beyond < self.valid_keys && self.cursors[beyond].0.key(&storage[self.cursors[beyond].1]) < self.cursors[max_index].0.key(&storage[self.cursors[max_index].1]) {
beyond += 1;
}
self.cursors[.. beyond].sort_by(|x,y| x.0.key(&storage[x.1]).cmp(y.0.key(&storage[y.1])));
}
if self.valid_keys > 0 {
self.equiv_keys = 1;
while self.equiv_keys < self.valid_keys && self.cursors[self.equiv_keys].0.key(&storage[self.cursors[self.equiv_keys].1]) == self.cursors[0].0.key(&storage[self.cursors[0].1]) {
self.equiv_keys += 1;
}
}
let to_tidy = self.equiv_keys;
self.valid_vals = self.equiv_keys; self.tidy_vals(storage, to_tidy);
}
fn tidy_vals(&mut self, storage: &Vec<C::Storage>, prefix: usize) {
self.equiv_vals = 0;
let mut dirty = 0;
for index in 0 .. prefix {
if self.cursors[index].0.val_valid(&storage[self.cursors[index].1]) {
self.cursors.swap(dirty, index);
dirty += 1;
}
}
if prefix - dirty > 0 {
for index in prefix .. self.valid_vals {
self.cursors.swap(index, index - (prefix - dirty));
}
}
self.valid_vals -= prefix - dirty;
if dirty > 0 {
let mut max_index = 0;
for index in 1 .. dirty {
if self.cursors[index].0.val(&storage[self.cursors[index].1]) > self.cursors[max_index].0.val(&storage[self.cursors[max_index].1]) {
max_index = index;
}
}
let mut beyond = dirty;
while beyond < self.valid_vals && self.cursors[beyond].0.val(&storage[self.cursors[beyond].1]) < self.cursors[max_index].0.val(&storage[self.cursors[max_index].1]) {
beyond += 1;
}
self.cursors[.. beyond].sort_by(|x,y| x.0.val(&storage[x.1]).cmp(y.0.val(&storage[y.1])));
}
if self.valid_vals > 0 {
self.equiv_vals = 1;
while self.equiv_vals < self.valid_vals && self.cursors[self.equiv_vals].0.val(&storage[self.cursors[self.equiv_vals].1]) == self.cursors[0].0.val(&storage[self.cursors[0].1]) {
self.equiv_vals += 1;
}
}
}
}
impl<K, V, T, R, C: Cursor<K, V, T, R>> Cursor<K, V, T, R> for CursorList<K, V, T, R, C>
where
K: Ord,
V: Ord {
type Storage = Vec<C::Storage>;
fn key_valid(&self, _storage: &Self::Storage) -> bool { self.valid_keys > 0 }
fn val_valid(&self, _storage: &Self::Storage) -> bool { self.valid_vals > 0 }
fn key<'a>(&self, storage: &'a Self::Storage) -> &'a K {
debug_assert!(self.key_valid(storage));
self.cursors[0].0.key(&storage[self.cursors[0].1])
}
fn val<'a>(&self, storage: &'a Self::Storage) -> &'a V {
debug_assert!(self.key_valid(storage));
debug_assert!(self.val_valid(storage));
self.cursors[0].0.val(&storage[self.cursors[0].1])
}
fn map_times<L: FnMut(&T, R)>(&mut self, storage: &Self::Storage, mut logic: L) {
for cursor in &mut self.cursors[.. self.equiv_vals] {
cursor.0.map_times(&storage[cursor.1], |t,d| logic(t,d));
}
}
fn step_key(&mut self, storage: &Self::Storage) {
for cursor in &mut self.cursors[.. self.equiv_keys] {
cursor.0.step_key(&storage[cursor.1]);
}
let to_tidy = self.equiv_keys;
self.tidy_keys(storage, to_tidy);
}
fn seek_key(&mut self, storage: &Self::Storage, key: &K) {
let mut index = 0;
while index < self.valid_keys && self.cursors[index].0.key(&storage[self.cursors[index].1]) < &key {
let temp = self.cursors[index].1;
self.cursors[index].0.seek_key(&storage[temp], key);
index += 1;
}
self.tidy_keys(storage, index);
}
fn step_val(&mut self, storage: &Self::Storage) {
for cursor in &mut self.cursors[.. self.equiv_vals] {
cursor.0.step_val(&storage[cursor.1]);
}
let to_tidy = self.equiv_vals;
self.tidy_vals(storage, to_tidy);
}
fn seek_val(&mut self, storage: &Self::Storage, val: &V) {
let mut index = 0;
while index < self.valid_vals && self.cursors[index].0.val(&storage[self.cursors[index].1]) < &val {
let temp = self.cursors[index].1;
self.cursors[index].0.seek_val(&storage[temp], val);
index += 1;
}
self.tidy_vals(storage, index);
}
fn rewind_keys(&mut self, storage: &Self::Storage) {
let len = self.cursors.len();
self.valid_keys = len;
for cursor in &mut self.cursors[.. len] {
cursor.0.rewind_keys(&storage[cursor.1]);
}
self.tidy_keys(storage, len);
}
fn rewind_vals(&mut self, storage: &Self::Storage) {
let len = self.equiv_keys;
self.valid_vals = len;
for cursor in &mut self.cursors[.. len] {
cursor.0.rewind_vals(&storage[cursor.1]);
}
self.tidy_vals(storage, len);
}
}