use super::{Allocator, Cache, FreeList};
use crate::{
config::Config,
device::{MemoryDevice, PageOps, ReadPage},
};
use std::{sync::Arc, time::Duration};
#[test]
fn test_reuse_freed_page() {
let disc = Box::new(MemoryDevice::new(None).unwrap());
let (_, allocator) = Allocator::init(disc, &Config::new()).unwrap();
allocator.allocate(10).unwrap();
let first = allocator.allocate(10).unwrap().get_index();
let second = allocator.allocate(10).unwrap().get_index();
let third = allocator.allocate(11).unwrap().get_index();
let _forth_to_avoid_trim = allocator.allocate(11).unwrap();
allocator.free(first).unwrap();
allocator.free(second).unwrap();
allocator.free(third).unwrap();
let val = allocator.allocate(10).unwrap().get_index();
assert_eq!(val, first);
let val = allocator.allocate(10).unwrap().get_index();
assert_eq!(val, second);
let val = allocator.allocate(10).unwrap().get_index();
assert!(val != first);
assert!(val != second);
let val = allocator.allocate(11).unwrap().get_index();
assert_eq!(val, third);
let val = allocator.allocate(11).unwrap().get_index();
assert!(val != third);
}
#[test]
fn test_remove_freed_page() {
let disc = Box::new(MemoryDevice::new(None).unwrap());
let (_, allocator) = Allocator::init(disc, &Config::new()).unwrap();
allocator.allocate(5).unwrap();
let first = allocator.allocate(10).unwrap().get_index();
let second = allocator.allocate(10).unwrap().get_index();
let third = allocator.allocate(10).unwrap().get_index();
let _forth_to_avoid_trim = allocator.allocate(11).unwrap();
allocator.free(first).unwrap();
allocator.free(second).unwrap();
allocator.free(third).unwrap();
allocator.remove_from_free(second, 10).unwrap();
let val = allocator.allocate(10).unwrap().get_index();
assert_eq!(val, first);
let val = allocator.allocate(10).unwrap().get_index();
assert_eq!(val, third);
}
#[test]
fn test_cache_limit_evict() {
let mut cache = Cache::new(1050 as u64, Duration::from_secs(3600));
cache.put(10, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
cache.put(20, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
cache.put(30, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
assert!(cache.size() < 1050);
assert_eq!(cache.entry_count(), 2);
let ten = 10 as u64;
match cache.get(ten) {
Some(_) => assert!(false),
None => assert!(true),
}
let ten = 20 as u64;
match cache.get(ten) {
Some(_) => assert!(true),
None => assert!(false),
}
let ten = 30 as u64;
match cache.get(ten) {
Some(_) => assert!(true),
None => assert!(false),
}
}
#[test]
fn test_cache_limit_refresh_evict() {
let mut cache = Cache::new(1050 as u64, Duration::from_secs(3600));
cache.put(10, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
cache.put(20, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
let ten = 10 as u64;
match cache.get(ten) {
Some(_) => assert!(true),
None => assert!(false),
}
cache.put(30, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
assert!(cache.size() < 1050);
assert_eq!(cache.entry_count(), 2);
let ten = 10 as u64;
match cache.get(ten) {
Some(_) => assert!(true),
None => assert!(false),
}
let ten = 20 as u64;
match cache.get(ten) {
Some(_) => assert!(false),
None => assert!(true),
}
let ten = 30 as u64;
match cache.get(ten) {
Some(_) => assert!(true),
None => assert!(false),
}
}
#[test]
fn test_read_write_free_list() {
use super::free_list::LISTS_COUNT;
let mut heads = [0u64; LISTS_COUNT];
for p in 0..heads.len() {
heads[p] = p as u64 + 10 * 3;
}
let mut tails = [0u64; LISTS_COUNT];
for p in 0..tails.len() {
tails[p] = p as u64 + 10 * 3;
}
let buf = FreeList::write_free_list(&heads, &tails);
let (read_heads, read_tails) = FreeList::read_free_list(&buf);
assert_eq!(heads, read_heads);
assert_eq!(tails, read_tails);
}
#[test]
fn test_cache_limit_remove() {
let mut cache = Cache::new(1050 as u64, Duration::from_secs(3600));
cache.put(10, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
cache.put(20, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
cache.put(30, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
assert!(cache.size() < 1050);
assert_eq!(cache.entry_count(), 2);
cache.remove(20);
cache.remove(30);
assert_eq!(cache.size(), 0);
}
#[test]
fn test_cache_replace_limit_stay() {
let mut cache = Cache::new(100000 as u64, Duration::from_secs(3600));
cache.put(10, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
cache.put(20, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
cache.put(30, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
let pre = cache.size();
cache.put(20, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
assert_eq!(cache.size(), pre);
cache.put(20, ReadPage::new(Arc::new(Vec::new()), 0, 10, 10));
assert_eq!(cache.size(), pre - (1 << 9) + (1 << 10));
}
#[test]
fn test_cache_time_clean() {
let mut cache = Cache::new(100000 as u64, Duration::from_millis(500));
cache.put(10, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
cache.put(20, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
cache.put(30, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
std::thread::sleep(Duration::from_millis(600));
cache.put(20, ReadPage::new(Arc::new(Vec::new()), 0, 10, 9));
assert_eq!(cache.size(), 1 << 9);
}