use std::mem::{replace};
use std::fmt::Debug;
use std::ops::{Index, IndexMut};
use std::slice::{Iter, IterMut};
use crate::Map;
#[derive(Debug, Hash)]
pub struct VecMap<T> {
entries: Vec<Option<T>>, len: usize,}
impl<T> Default for VecMap<T> {
fn default() -> Self {
VecMap::new()
}
}
impl<T: Clone> Clone for VecMap<T> {
fn clone(&self) -> Self {
VecMap {
entries: self.entries.to_vec(),
len: self.len,
}
}
}
impl<T> VecMap<T> {
pub fn new() -> Self {
VecMap::with_capacity(0)
}
pub fn with_capacity(capacity: usize) -> VecMap<T> {
VecMap {
entries: Vec::with_capacity(capacity),
len: 0,
}
}
pub fn capacity(&self) -> usize {
self.entries.capacity()
}
pub fn reserve(&mut self, additional: usize) {
if self.capacity() - self.len >= additional {
return;
}
let need_add = self.len + additional - self.entries.len();
self.entries.reserve(need_add);
}
pub fn reserve_exact(&mut self, additional: usize) {
if self.capacity() - self.len >= additional {
return;
}
let need_add = self.len + additional - self.entries.len();
self.entries.reserve_exact(need_add);
}
pub fn clear(&mut self) {
self.entries.clear();
self.len = 0;
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len == 0
}
pub fn iter(&self) -> Iter<Option<T>> {
self.entries.iter()
}
pub fn iter_mut(&mut self) -> IterMut<Option<T>> {
self.entries.iter_mut()
}
pub unsafe fn replace(&mut self, index: usize, value: T) -> T {
replace(&mut self.entries[index], Some(value)).unwrap()
}
pub fn get(&self, index: usize) -> Option<&T> {
if index == usize::max_value() || index >= self.entries.len(){
return None;
}
match &self.entries[index] {
Some(v) => Some(v),
None => None,
}
}
pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
if index == usize::max_value() || index >= self.entries.len(){
return None;
}
match &mut self.entries[index] {
Some(v) => Some(v),
None => None,
}
}
pub unsafe fn get_unchecked(&self, index: usize) -> &T {
self.entries[index].as_ref().unwrap()
}
pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &mut T {
self.entries[index].as_mut().unwrap()
}
pub fn insert(&mut self, index:usize, val: T) -> Option<T>{
let len = self.entries.len();
if len == index {
self.entries.push(Some(val));
self.len += 1;
None
} else if index >= len {
self.entries.extend((0..index - len + 1).map(|_| None));
self.len += 1;
replace(&mut self.entries[index], Some(val))
}else {
let r = replace(&mut self.entries[index], Some(val));
if r.is_none(){
self.len += 1;
}
r
}
}
pub fn remove(&mut self, index: usize) -> Option<T> {
if index >= self.entries.len() {
return None;
}
match replace(&mut self.entries[index], None) {
Some(v) => {
self.len -= 1;
Some(v)
},
None => None,
}
}
pub unsafe fn remove_unchecked(&mut self, index: usize) -> T {
self.len -= 1;
replace(&mut self.entries[index], None).unwrap()
}
pub fn contains(&self, index: usize) -> bool {
if index == usize::max_value() || index >= self.entries.len(){
return false;
}
match &self.entries[index] {
Some(_v) => true,
None => false,
}
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
}
impl<T> Map for VecMap<T> {
type Key = usize;
type Val = T;
#[inline]
fn get(&self, key: &usize) -> Option<&T> {
self.get(*key)
}
#[inline]
fn get_mut(&mut self, key: &usize) -> Option<&mut T> {
self.get_mut(*key)
}
#[inline]
unsafe fn get_unchecked(&self, key: &usize) -> &T {
self.get_unchecked(*key)
}
#[inline]
unsafe fn get_unchecked_mut(&mut self, key: &usize) -> &mut T {
self.get_unchecked_mut(*key)
}
#[inline]
unsafe fn remove_unchecked(&mut self, key: &usize) -> T {
self.remove_unchecked(*key)
}
#[inline]
fn insert(&mut self, key: usize, val: T) -> Option<T> {
self.insert(key, val)
}
#[inline]
fn remove(&mut self, key: &usize) -> Option<T> {
self.remove(*key)
}
#[inline]
fn contains(&self, key: &usize) -> bool {
self.contains(*key)
}
#[inline]
fn len(&self) -> usize {
self.len
}
#[inline]
fn capacity(&self) -> usize {
self.entries.capacity()
}
#[inline]
fn mem_size(&self) -> usize {
self.capacity() * std::mem::size_of::<T>()
}
fn with_capacity(capacity: usize) -> Self {
VecMap::with_capacity(capacity)
}
}
impl<T> Index<usize> for VecMap<T> {
type Output = T;
fn index(&self, index: usize) -> &T {
self.entries[index].as_ref().unwrap()
}
}
impl<T> IndexMut<usize> for VecMap<T> {
fn index_mut(&mut self, index: usize) -> &mut T {
self.entries[index].as_mut().unwrap()
}
}
#[cfg(test)]
use std::time::Instant;
#[test]
fn test_time(){
let mut map: VecMap<[f32; 16]> = VecMap::new();
map.entries = Vec::with_capacity(0);
let mut arr = Vec::with_capacity(100000);
let time = Instant::now();
for _i in 0..10000 {
arr.push(Some([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0]));
}
println!("insert vec time: {:?}", Instant::now() - time);
let time = Instant::now();
for i in 1..10001 {
map.insert(i, [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0]);
}
println!("insert vecmap time: {:?}", Instant::now() - time);
let mut map: VecMap<f32> = VecMap::new();
map.entries = Vec::with_capacity(100000);
let time = Instant::now();
for i in 1..10001 {
map.insert(i, 1.0);
}
println!("insert vecmap time: {:?}", Instant::now() - time);
}
#[test]
fn test(){
let mut map: VecMap<u64> = VecMap::new();
for i in 1..71{
map.insert(i as usize, i);
println!("map------{:?}", map);
}
map.remove(30);
println!("r 30------{:?}", map);
map.remove(31);
println!("r 31------{:?}", map);
map.remove(69);
println!("r 69------{:?}", map);
map.remove(70);
println!("r 70------{:?}", map);
assert_eq!(map.contains(0), false);
assert_eq!(map.contains(1), true);
assert_eq!(map.contains(71), false);
assert_eq!(map.contains(72), false);
assert_eq!(map.get(0), None);
assert_eq!(map.get(1), Some(&1));
assert_eq!(map.get(50), Some(&50));
assert_eq!(map.get(70), None);
assert_eq!(map.get(72), None);
assert_eq!(map.get_mut(0), None);
assert_eq!(map.get_mut(64), Some(&mut 64));
assert_eq!(map.get_mut(30), None);
assert_eq!(map.get_mut(20), Some(&mut 20));
assert_eq!(map.get_mut(75), None);
assert_eq!(unsafe{map.get_unchecked(2)}, &2);
assert_eq!(unsafe{map.get_unchecked(9)}, &9);
assert_eq!(unsafe{map.get_unchecked(55)}, &55);
assert_eq!(unsafe{map.get_unchecked(60)}, &60);
assert_eq!(unsafe{map.get_unchecked_mut(44)}, &mut 44);
assert_eq!(unsafe{map.get_unchecked_mut(33)}, &mut 33);
assert_eq!(unsafe{map.get_unchecked_mut(7)}, &mut 7);
}