use crate::cache::Cache;
use crate::sync_cache::SyncCache;
use std::collections::HashMap;
use std::hash::Hash;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug)]
pub struct Dump<K, V> {
pub capacity: usize,
pub data: Vec<(K, V)>,
}
impl<K, V> From<Vec<(K, V)>> for Cache<K, V>
where
K: Hash + Eq,
{
fn from(vec: Vec<(K, V)>) -> Cache<K, V> {
let mut cache = Cache::new(vec.len());
vec.into_iter().map(|x| cache.insert(x.0, x.1)).count();
cache
}
}
impl<K, V> From<HashMap<K, V>> for Cache<K, V>
where
K: Hash + Eq,
{
fn from(map: HashMap<K, V>) -> Cache<K, V> {
let mut cache = Cache::new(map.len());
map.into_iter().map(|x| cache.insert(x.0, x.1)).count();
cache
}
}
impl<K, V> From<Dump<K, V>> for Cache<K, V>
where
K: Hash + Eq,
{
fn from(dump: Dump<K, V>) -> Cache<K, V> {
let mut cache = Cache::from(dump.data);
cache.resize(dump.capacity);
cache
}
}
impl<K, V> From<Vec<(K, V)>> for SyncCache<K, V>
where
K: Hash + Eq + Clone,
V: Clone,
{
fn from(vec: Vec<(K, V)>) -> SyncCache<K, V> {
let cache = SyncCache::new(vec.len());
vec.into_iter().map(|x| cache.insert(x.0, x.1)).count();
cache
}
}
impl<K, V> From<HashMap<K, V>> for SyncCache<K, V>
where
K: Hash + Eq + Clone,
V: Clone,
{
fn from(map: HashMap<K, V>) -> SyncCache<K, V> {
let cache = SyncCache::new(map.len());
map.into_iter().map(|x| cache.insert(x.0, x.1)).count();
cache
}
}
impl<K, V> From<Dump<K, V>> for SyncCache<K, V>
where
K: Hash + Eq + Clone,
V: Clone,
{
fn from(dump: Dump<K, V>) -> SyncCache<K, V> {
let cache = SyncCache::from(dump.data);
cache.resize(dump.capacity);
cache
}
}
impl<K, V> From<Cache<K, V>> for Vec<(K, V)>
where
K: Hash + Eq,
{
fn from(cache: Cache<K, V>) -> Vec<(K, V)> {
let mut vec = Vec::with_capacity(cache.len());
cache.into_iter().map(|x| vec.push(x)).count();
vec
}
}
impl<K, V> From<Cache<K, V>> for HashMap<K, V>
where
K: Hash + Eq,
{
fn from(cache: Cache<K, V>) -> HashMap<K, V> {
let mut map = HashMap::with_capacity(cache.len());
cache.into_iter().map(|x| map.insert(x.0, x.1)).count();
map
}
}
impl<K, V> From<Cache<K, V>> for Dump<K, V>
where
K: Hash + Eq,
{
fn from(cache: Cache<K, V>) -> Dump<K, V> {
let capacity = cache.capacity();
let data: Vec<(K, V)> = Vec::from(cache);
Dump { capacity, data }
}
}
impl<K, V> PartialEq<Dump<K, V>> for Dump<K, V>
where
K: Hash + Eq,
V: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
if self.capacity != other.capacity {
return false;
}
self.data == other.data
}
}
impl<K, V> Eq for Dump<K, V>
where
K: Hash + Eq + Clone,
V: Eq,
{
}
#[cfg(test)]
mod tests {
#[cfg(feature = "serde")]
#[test]
fn test_json() {
use super::{Cache, Dump};
use serde_json::json;
let mut cache = Cache::new(10);
cache.insert(1, 10);
cache.insert(2, 20);
let dump1 = cache.dump();
let export = json!(&dump1).to_string();
assert_eq!("{\"capacity\":10,\"data\":[[1,10],[2,20]]}", export);
let dump2: Dump<usize, usize> = serde_json::from_str(&export).unwrap();
cache.clear();
assert_eq!(0, cache.len());
cache.restore(&dump2);
assert_eq!(2, cache.len());
}
#[cfg(feature = "serde")]
#[test]
fn test_postcard() {
extern crate alloc;
use super::{Cache, Dump};
use alloc::vec::Vec;
use postcard::{from_bytes, to_allocvec};
let mut cache = Cache::<usize, usize>::new(1_000);
for i in 0..cache.capacity() / 2 {
cache.insert(i, i * 10);
}
let dump1 = cache.dump();
let export: Vec<u8> = to_allocvec(&dump1).unwrap();
println!("export len: {}", export.len());
let dump2: Dump<usize, usize> = from_bytes(&export).unwrap();
println!("dump1 capacity: {}", dump1.capacity);
println!("dump2 capacity: {}", dump2.capacity);
assert_eq!(&dump1, &dump2);
}
}