#![macro_use]
use super::uset::USet;
use itertools::{Itertools, MinMaxResult};
use std::clone::Clone;
use std::cmp;
use std::fmt;
use std::ops::Add;
use std::iter::FromIterator;
#[allow(unused_macros)]
macro_rules! umap {
($($x:expr),*) => (UMap::from_slice(&vec![$($x),*]))
}
#[derive(Default, Clone)]
pub struct UMap<T> {
pub vec: Vec<Option<T>>,
len: usize,
offset: usize,
min: usize,
max: usize,
}
#[derive(Debug, Clone)]
pub struct UMapIter<'a, T: 'a> {
handle: &'a UMap<T>,
index: usize,
rindex: usize,
}
impl<'a, T> Iterator for UMapIter<'a, T>
where
T: Clone + PartialEq,
{
type Item = (usize, &'a T);
fn next(&mut self) -> Option<Self::Item> {
let max = self.handle.vec.len() - self.rindex;
while self.index < max {
let index = self.index;
self.index += 1;
if let Some(ref value) = self.handle.vec[index] {
return Some((index + self.handle.offset, value));
}
}
None
}
}
impl<'a, T> DoubleEndedIterator for UMapIter<'a, T>
where
T: Clone + PartialEq,
{
fn next_back(&mut self) -> Option<Self::Item> {
let len = self.handle.vec.len();
while self.rindex < len - self.index {
let index = len - self.rindex - 1;
self.rindex += 1;
if let Some(ref value) = self.handle.vec[index] {
return Some((index + self.handle.offset, &value));
}
}
None
}
}
pub const INITIAL_CAPACITY: usize = 8;
impl<T> UMap<T>
where
T: Clone + PartialEq,
{
pub fn new() -> Self {
UMap::with_capacity(0)
}
pub fn with_capacity(size: usize) -> Self {
UMap {
vec: vec![None; size],
len: 0,
offset: 0,
min: 0,
max: 0,
}
}
pub fn len(&self) -> usize {
self.len
}
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn capacity(&self) -> usize {
self.vec.len()
}
pub fn shrink_to_fit(&mut self) {
if !self.is_empty() && (self.vec[0].is_none() || self.vec[self.vec.len() - 1].is_none()) {
let mut vec = vec![None; self.max - self.min + 1];
for id in self.min..=self.max {
vec[id - self.min] = self.get(id);
}
self.vec = vec;
self.offset = self.min;
} else if self.is_empty() && self.capacity() > 0 {
self.vec = Vec::with_capacity(0);
}
}
pub fn truncate(&mut self, len: usize) {
if !self.is_empty() && len > 0 && len < self.len {
let mut values_left = len;
let mut new_max = 0usize;
self.vec
.iter_mut()
.enumerate()
.for_each(|(index, value_holder)| {
if value_holder.is_some() {
if values_left > 0 {
values_left -= 1;
new_max = index;
} else {
*value_holder = None;
}
}
});
self.max = new_max + self.offset;
self.len = len;
} else if !self.is_empty() && len == 0 {
self.vec
.iter_mut()
.for_each(|value_holder| *value_holder = None);
self.offset = 0;
self.min = 0;
self.max = 0;
self.len = 0;
}
}
pub fn drain(&mut self, len: usize) -> Self {
if !self.is_empty() && len > 0 && len < self.len {
let mut new_map = UMap::with_capacity(self.len - len);
let mut values_left = len;
let mut new_max = 0usize;
let offset = self.offset;
self.vec
.iter_mut()
.enumerate()
.for_each(|(index, value_holder)| {
if let Some(ref value) = value_holder {
if values_left > 0 {
values_left -= 1;
new_max = index;
} else {
new_map.put(index + offset, value.clone());
*value_holder = None;
}
}
});
self.max = new_max + self.offset;
self.len = len;
new_map.shrink_to_fit(); new_map
} else if !self.is_empty() && len == 0 {
let new_map = self.clone();
self.vec.iter_mut().for_each(|value_holder| {
if value_holder.is_some() {
*value_holder = None
}
});
self.offset = 0;
self.min = 0;
self.max = 0;
self.len = 0;
new_map
} else {
UMap::with_capacity(0)
}
}
pub fn clear(&mut self) {
self.truncate(0)
}
pub fn enlarge_capacity_to(&mut self, new_capacity: usize) {
if new_capacity > self.capacity() {
self.vec.resize(new_capacity, None);
}
}
pub fn push(&mut self, value: T) -> usize {
let id = self.max + 1;
self.put(id, value);
id
}
pub fn push_all(&mut self, slice: &[T]) -> Vec<usize> {
self.enlarge_capacity_to(self.capacity() + slice.len());
slice.iter().map(|v| self.push(v.clone())).collect()
}
pub fn put(&mut self, id: usize, value: T) {
match id {
_ if self.capacity() == 0 => {
self.vec = vec![None; INITIAL_CAPACITY];
self.vec[0] = Some(value);
self.min = id;
self.len += 1;
self.max = id;
self.offset = id;
}
_ if self.is_empty() => {
self.vec[0] = Some(value);
self.min = id;
self.len = 1;
self.max = id;
self.offset = id;
}
_ if id < self.offset => {
let mut vec = vec![None; self.max - id + 1];
vec[0] = Some(value);
for i in self.min..=self.max {
vec[i - id] = self.get(i);
}
self.vec = vec;
self.len += 1;
self.min = id;
self.offset = id;
}
_ if id >= self.offset + self.capacity() => {
self.vec.resize(id + 1 - self.offset, None);
self.vec[id - self.offset] = Some(value);
self.len += 1;
self.max = id;
}
_ if self.vec[id - self.offset].is_none() => {
self.vec[id - self.offset] = Some(value);
self.len += 1;
if id < self.min {
self.min = id
} else if id > self.max {
self.max = id
}
}
_ => {}
}
}
pub fn contains(&self, id: usize) -> bool {
id >= self.min && id <= self.max && self.vec[id - self.offset].is_some()
}
pub fn get(&self, id: usize) -> Option<T> {
if id >= self.min && id <= self.max {
unsafe { self.vec.get_unchecked(id - self.offset).clone() }
} else {
None
}
}
pub fn get_ref(&self, id: usize) -> Option<&T> {
if id >= self.min && id <= self.max {
unsafe {
if let Some(ref v) = self.vec.get_unchecked(id - self.offset) {
Some(v)
} else {
None
}
}
} else {
None
}
}
pub fn get_ref_mut(&mut self, id: usize) -> Option<&mut T> {
if id >= self.min && id <= self.max {
unsafe {
if let Some(ref mut v) = self.vec.get_unchecked_mut(id - self.offset) {
Some(v)
} else {
None
}
}
} else {
None
}
}
pub fn remove(&mut self, id: usize) -> Option<T> {
match id {
_ if id < self.min || id > self.max || !self.contains(id) => None,
_ if self.len == 1 => {
let t = self.vec[id - self.offset].clone();
self.vec[id - self.offset] = None;
self.max = 0;
self.min = 0;
self.len = 0;
self.offset = 0;
t
}
_ if id > self.min && id < self.max => {
let t = self.vec[id - self.offset].clone();
self.vec[id - self.offset] = None;
self.len -= 1;
t
}
_ if id == self.min => {
let t = self.vec[id - self.offset].clone();
self.vec[id - self.offset] = None;
self.len -= 1;
self.min = (self.min..self.max)
.find(|&i| self.vec[i - self.offset].is_some())
.unwrap_or(self.max);
t
}
_ if id == self.max => {
let t = self.vec[id - self.offset].clone();
self.vec[id - self.offset] = None;
self.len -= 1;
self.max = (self.min..self.max)
.rev()
.find(|&i| self.vec[i - self.offset].is_some())
.unwrap_or(self.min);
t
}
_ => None,
}
}
pub fn keys(&self) -> USet {
let set: Vec<bool> = self.vec.iter().map(Option::is_some).collect();
USet::from_fields(set, self.offset)
}
pub fn pop(&mut self, index: usize) -> Option<(usize, T)> {
let d = self.at_index(index);
if let Some((id, value)) = d {
self.remove(id);
Some((id, value.clone()))
} else {
None
}
}
pub fn at_index(&self, index: usize) -> Option<(usize, T)> {
if index >= self.len {
None
} else {
let mut it = self.iter();
for _i in 0..index {
it.next();
}
it.next().map(|(id, value)| (id, value.clone()))
}
}
pub fn iter(&self) -> UMapIter<T> {
UMapIter {
handle: self,
index: 0,
rindex: 0,
}
}
pub fn min(&self) -> Option<usize> {
if self.is_empty() {
None
} else {
Some(self.min)
}
}
pub fn max(&self) -> Option<usize> {
if self.is_empty() {
None
} else {
Some(self.max)
}
}
fn make_from_slice(slice: &[(usize, T)]) -> (usize, usize, usize, Vec<Option<T>>) {
match slice.iter().minmax_by_key(|(ref id, _)| *id) {
MinMaxResult::NoElements => (0, 0, 0, Vec::<Option<T>>::new()),
MinMaxResult::OneElement((ref id, value)) => {
(*id, *id, 1, vec![Some(value.clone()); 1])
}
MinMaxResult::MinMax(&(min, _), &(max, _)) => {
let len = slice.len();
let capacity = cmp::max(INITIAL_CAPACITY, max + 1 - min);
let mut vec = vec![None; capacity];
slice
.iter()
.for_each(|(id, value)| vec[*id - min] = Some(value.clone()));
(min, max, len, vec)
}
}
}
pub fn from_slice(slice: &[(usize, T)]) -> Self {
if slice.is_empty() {
UMap::new()
} else {
let (min, max, len, new_vec) = UMap::make_from_slice(slice);
UMap {
vec: new_vec,
len,
offset: min,
min,
max,
}
}
}
fn debug_compare(self: &Self, other: &UMap<T>) {
debug_assert!(self
.iter()
.zip(other.iter())
.find(|&((i1, ref v1), (i2, ref v2))| i1 == i2 && v1 != v2)
.is_none());
}
pub fn put_all(&mut self, slice: &[(usize, T)]) {
if !slice.is_empty() {
if self.is_empty() {
let (min, max, len, new_vec) = UMap::make_from_slice(slice);
self.min = min;
self.max = max;
self.offset = min;
self.len = len;
self.vec = new_vec;
} else {
let (min, max) = match slice.iter().minmax_by_key(|&(id, _)| *id) {
MinMaxResult::NoElements => (0, 0), MinMaxResult::OneElement(&(min, _)) => (min, min),
MinMaxResult::MinMax(&(min, _), &(max, _)) => (min, max),
};
if min >= self.min && max <= self.max {
slice.iter().for_each(|(ref id, value)| {
if self.vec[*id - self.offset].is_none() {
self.vec[*id - self.offset] = Some(value.clone());
self.len += 1;
}
})
} else {
let new_min = cmp::min(self.min, min);
let new_max = cmp::max(self.max, max);
let mut new_vec = vec![None; new_max - new_min + 1];
self.iter()
.skip(self.min - self.offset)
.take(self.max - self.min + 1)
.for_each(|(id, value)| new_vec[id - new_min] = Some(value.clone()));
slice.iter().for_each(|(ref id, value)| {
if new_vec[*id - new_min].is_none() {
new_vec[*id - new_min] = Some(value.clone());
self.len += 1;
}
});
self.min = new_min;
self.offset = new_min;
self.max = new_max;
self.vec = new_vec;
}
}
}
}
pub fn join(&self, other: &Self) -> Self {
if self.is_empty() {
if other.is_empty() {
UMap::new()
} else {
other.clone()
}
} else if other.is_empty() {
if self.is_empty() {
UMap::new()
} else {
self.clone()
}
} else {
self.debug_compare(other);
let min: usize = cmp::min(self.min, other.min);
let max: usize = cmp::max(self.max, other.max);
let mut vec = vec![None; max + 1 - min];
let mut len = 0usize;
vec.iter_mut().enumerate().for_each(|(id, value)| {
if self.contains(id + min) {
*value = self.get(id + min);
len += 1;
} else if other.contains(id + min) {
*value = other.get(id + min);
len += 1;
}
});
UMap {
vec,
len,
offset: min,
min,
max,
}
}
}
pub fn submap(&self, set: &USet) -> Self {
if set.is_empty() {
UMap::new()
} else {
let min = set.min().unwrap();
let max = set.max().unwrap();
let mut vec = vec![None; max - min + 1];
set.iter().for_each(|id| vec[id - min] = self.get(id));
UMap {
vec,
len: set.len(),
offset: min,
min,
max,
}
}
}
pub fn retrieve(&self, set: &USet) -> Vec<T> {
let mut vec = Vec::with_capacity(set.len());
set.iter()
.filter_map(|id| self.get(id))
.for_each(|value| vec.push(value));
vec
}
pub fn retrieve_ref(&self, set: &USet) -> Vec<&T> {
let mut vec = Vec::with_capacity(set.len());
set.iter()
.filter_map(|id| self.get_ref(id))
.for_each(|value| vec.push(value));
vec
}
pub fn query(&self, predicate: impl Fn(&T) -> bool) -> USet {
if self.is_empty() {
USet::new()
} else {
let mut vec = Vec::with_capacity(self.max - self.min + 1);
for id in self.min..=self.max {
if let Some(v) = self.get_ref(id) {
if predicate(v) {
vec.push(id);
}
}
}
USet::from_slice(&vec)
}
}
pub fn all(&self, predicate: impl Fn(&T) -> bool) -> bool {
self.iter().all(|(_id, value)| predicate(value))
}
pub fn any(&self, predicate: impl Fn(&T) -> bool) -> bool {
self.iter().any(|(_id, value)| predicate(value))
}
pub fn all_in_subset(&self, subset: &USet, predicate: impl Fn(&T) -> bool) -> bool {
!self
.iter()
.any(|(id, value)| subset.contains(id) && !predicate(value))
}
pub fn any_in_subset(&self, subset: &USet, predicate: impl Fn(&T) -> bool) -> bool {
self.iter()
.any(|(id, value)| subset.contains(id) && predicate(value))
}
pub fn remove_all(&mut self, subset: &USet) {
subset.iter().for_each(|id| {
self.remove(id);
});
}
pub fn replace(&mut self, id: usize, value: T) {
if let Some(v) = self.get_ref_mut(id) {
*v = value;
} else {
self.put(id, value);
}
}
pub fn replace_all(&mut self, other: &UMap<T>) {
other.iter().for_each(|(id, v)| self.replace(id, v.clone()));
}
}
impl<T> PartialEq for UMap<T>
where
T: Clone + PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.len == other.len
&& self.min == other.min
&& self.max == other.max
&& self
.vec
.iter()
.skip(self.min - self.offset)
.take(self.max + 1 - self.min)
.zip(
other
.vec
.iter()
.skip(other.min - other.offset)
.take(other.max + 1 - other.min),
)
.all(|(a, b)| *a == *b)
}
}
impl<T> Eq for UMap<T> where T: Clone + PartialEq {}
impl<'a, T> Add for &'a UMap<T>
where
T: Clone + PartialEq,
{
type Output = UMap<T>;
fn add(self, other: &UMap<T>) -> UMap<T> {
self.join(other)
}
}
impl<'a, T> From<&'a [(usize, T)]> for UMap<T>
where
T: Clone + PartialEq,
{
fn from(slice: &'a [(usize, T)]) -> Self {
UMap::from_slice(slice)
}
}
impl<T> From<Vec<(usize, T)>> for UMap<T>
where
T: Clone + PartialEq,
{
fn from(vec: Vec<(usize, T)>) -> Self {
UMap::from_slice(&vec)
}
}
impl<A> FromIterator<(usize, A)> for UMap<A>
where
A: Clone + PartialEq,
{
fn from_iter<T: IntoIterator<Item = (usize, A)>>(iter: T) -> Self {
let vec: Vec<(usize, A)> = iter.into_iter().collect();
UMap::from_slice(&vec)
}
}
impl<T> Into<Vec<(usize, T)>> for UMap<T>
where
T: Clone + PartialEq,
{
fn into(self) -> Vec<(usize, T)> {
self.iter().map(|(id, value)| (id, value.clone())).collect()
}
}
impl<T> fmt::Debug for UMap<T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "UMap(").unwrap();
for item in &self.vec {
if let Some(entry) = item {
write!(f, "{:?}", entry).unwrap();
}
}
write!(f, ")").unwrap();
Ok(())
}
}
impl<A> Extend<(usize, A)> for UMap<A>
where
A: Clone + PartialEq,
{
fn extend<T: IntoIterator<Item = (usize, A)>>(&mut self, iter: T) {
for (id, value) in iter {
self.put(id, value);
}
}
}
impl<A> Extend<A> for UMap<A>
where
A: Clone + PartialEq,
{
fn extend<T: IntoIterator<Item = A>>(&mut self, iter: T) {
for value in iter {
self.push(value);
}
}
}