use sorted_vec::index::PosIndex;
const LOAD_FACTOR: usize = 1000;
#[derive(Debug, Clone)]
pub struct SortedVec<T: Ord> {
vectors: Vec<Vec<T>>,
maxes: Vec<T>,
index: PosIndex,
len: usize,
load: usize,
half: usize,
dual: usize,
}
impl<T: Ord> SortedVec<T> {
pub fn new() -> Self {
SortedVec {
vectors: Vec::new(),
maxes: Vec::new(),
index: PosIndex::new(),
len: 0,
load: LOAD_FACTOR,
half: LOAD_FACTOR >> 1,
dual: LOAD_FACTOR << 1,
}
}
pub fn with_load_factor(load_factor: usize) -> Self {
SortedVec {
vectors: Vec::new(),
maxes: Vec::new(),
index: PosIndex::new(),
len: 0,
load: load_factor,
half: load_factor >> 1,
dual: load_factor << 1,
}
}
pub fn len(&self) -> usize {
self.len
}
pub fn into_vec(mut self) -> Vec<T> {
let mut vector = Vec::with_capacity(self.len());
for mut vec in self.vectors.drain(..) {
vector.extend(vec.drain(..));
}
vector
}
}
impl<T: Ord + Clone> SortedVec<T> {
pub fn add(&mut self, elem: T) {
if self.maxes.is_empty() {
self.vectors.push(vec![elem.clone()]);
self.maxes.push(elem);
} else {
let pos;
match self.maxes.binary_search(&elem) {
Ok(i) => {
pos = i;
self.vectors[i].push(elem);
}
Err(i) => {
if i == self.maxes.len() {
pos = i - 1;
self.vectors[pos].push(elem.clone());
self.maxes[pos] = elem;
} else {
pos = i;
let j = self.vectors[pos].binary_search(&elem).unwrap_or_else(|e| e);
self.vectors[pos].insert(j, elem);
}
}
}
self.expand(pos);
}
self.len += 1;
}
pub fn to_vec(&self) -> Vec<T> {
let mut vector = Vec::with_capacity(self.len());
for vec in self.vectors.iter() {
vector.extend(vec.iter().cloned());
}
vector
}
}
impl<T: Ord + Clone> SortedVec<T> {
fn expand(&mut self, pos: usize) {
if self.vectors[pos].len() > self.dual {
let last_half: Vec<_> = self.vectors[pos].drain(self.load..).collect();
self.vectors.insert(pos + 1, last_half);
self.maxes
.insert(pos, self.vectors[pos][self.load - 1].clone());
} else {
}
}
}