use bitcoinleveldb_cache::*;
use bitcoinleveldb_slice::*;
use bitcoin_imports::*;
#[traced_test]
fn cache_test_hit_and_miss() {
let mut fixture = CacheTest::new(CACHE_TEST_CACHE_SIZE);
set_current_cache_test(&mut fixture as *mut CacheTest);
assert_eq!(-1, fixture.lookup(100));
fixture.insert(100, 101, None);
assert_eq!(101, fixture.lookup(100));
assert_eq!(-1, fixture.lookup(200));
assert_eq!(-1, fixture.lookup(300));
fixture.insert(200, 201, None);
assert_eq!(101, fixture.lookup(100));
assert_eq!(201, fixture.lookup(200));
assert_eq!(-1, fixture.lookup(300));
fixture.insert(100, 102, None);
assert_eq!(102, fixture.lookup(100));
assert_eq!(201, fixture.lookup(200));
assert_eq!(-1, fixture.lookup(300));
assert_eq!(1, fixture.deleted_keys().len());
assert_eq!(100, fixture.deleted_keys()[0]);
assert_eq!(101, fixture.deleted_values()[0]);
}
#[traced_test]
fn cache_test_erase() {
let mut fixture = CacheTest::new(CACHE_TEST_CACHE_SIZE);
set_current_cache_test(&mut fixture as *mut CacheTest);
fixture.erase(200);
assert_eq!(0, fixture.deleted_keys().len());
fixture.insert(100, 101, None);
fixture.insert(200, 201, None);
fixture.erase(100);
assert_eq!(-1, fixture.lookup(100));
assert_eq!(201, fixture.lookup(200));
assert_eq!(1, fixture.deleted_keys().len());
assert_eq!(100, fixture.deleted_keys()[0]);
assert_eq!(101, fixture.deleted_values()[0]);
fixture.erase(100);
assert_eq!(-1, fixture.lookup(100));
assert_eq!(201, fixture.lookup(200));
assert_eq!(1, fixture.deleted_keys().len());
}
#[traced_test]
fn cache_test_entries_are_pinned() {
let mut fixture = CacheTest::new(CACHE_TEST_CACHE_SIZE);
set_current_cache_test(&mut fixture as *mut CacheTest);
fixture.insert(100, 101, None);
let h1 = unsafe {
let encoded = encode_key(100);
let key_slice: Slice = (&encoded[..]).into();
let cache = fixture.cache_mut();
(**cache).lookup(&key_slice)
};
assert!(!h1.is_null());
let v1 = unsafe {
let cache = fixture.cache_mut();
decode_value((**cache).value(h1))
};
assert_eq!(101, v1);
fixture.insert(100, 102, None);
let h2 = unsafe {
let encoded = encode_key(100);
let key_slice: Slice = (&encoded[..]).into();
let cache = fixture.cache_mut();
(**cache).lookup(&key_slice)
};
assert!(!h2.is_null());
let v2 = unsafe {
let cache = fixture.cache_mut();
decode_value((**cache).value(h2))
};
assert_eq!(102, v2);
assert_eq!(0, fixture.deleted_keys().len());
unsafe {
let cache = fixture.cache_mut();
(**cache).release(h1);
}
assert_eq!(1, fixture.deleted_keys().len());
assert_eq!(100, fixture.deleted_keys()[0]);
assert_eq!(101, fixture.deleted_values()[0]);
fixture.erase(100);
assert_eq!(-1, fixture.lookup(100));
assert_eq!(1, fixture.deleted_keys().len());
unsafe {
let cache = fixture.cache_mut();
(**cache).release(h2);
}
assert_eq!(2, fixture.deleted_keys().len());
assert_eq!(100, fixture.deleted_keys()[1]);
assert_eq!(102, fixture.deleted_values()[1]);
}
#[traced_test]
fn cache_test_eviction_policy() {
let mut fixture = CacheTest::new(CACHE_TEST_CACHE_SIZE);
set_current_cache_test(&mut fixture as *mut CacheTest);
fixture.insert(100, 101, None);
fixture.insert(200, 201, None);
fixture.insert(300, 301, None);
let h = unsafe {
let encoded = encode_key(300);
let key_slice: Slice = (&encoded[..]).into();
let cache = fixture.cache_mut();
(**cache).lookup(&key_slice)
};
assert!(!h.is_null());
for i in 0..(CACHE_TEST_CACHE_SIZE as i32 + 100) {
let key = 1000 + i;
let value = 2000 + i;
fixture.insert(key, value, None);
assert_eq!(value, fixture.lookup(key));
assert_eq!(101, fixture.lookup(100));
}
assert_eq!(101, fixture.lookup(100));
assert_eq!(-1, fixture.lookup(200));
assert_eq!(301, fixture.lookup(300));
unsafe {
let cache = fixture.cache_mut();
(**cache).release(h);
}
}
#[traced_test]
fn cache_test_use_exceeds_size() {
let mut fixture = CacheTest::new(CACHE_TEST_CACHE_SIZE);
set_current_cache_test(&mut fixture as *mut CacheTest);
let mut handles: Vec<*mut CacheHandle> = Vec::new();
for i in 0..(CACHE_TEST_CACHE_SIZE as i32 + 100) {
let key = 1000 + i;
let value = 2000 + i;
let h = fixture.insert_and_return_handle(key, value, None);
handles.push(h);
}
for i in 0..handles.len() as i32 {
let key = 1000 + i;
let expected = 2000 + i;
assert_eq!(expected, fixture.lookup(key));
}
unsafe {
let cache = fixture.cache_mut();
for h in handles {
(**cache).release(h);
}
}
}
#[traced_test]
fn cache_test_heavy_entries() {
let mut fixture = CacheTest::new(CACHE_TEST_CACHE_SIZE);
set_current_cache_test(&mut fixture as *mut CacheTest);
const LIGHT: i32 = 1;
const HEAVY: i32 = 10;
let mut added = 0;
let mut index = 0;
while added < 2 * CACHE_TEST_CACHE_SIZE as i32 {
let weight = if (index & 1) != 0 { LIGHT } else { HEAVY };
fixture.insert(index, 1000 + index, Some(weight));
added += weight;
index += 1;
}
let mut cached_weight = 0;
for i in 0..index {
let weight = if (i & 1) != 0 { LIGHT } else { HEAVY };
let r = fixture.lookup(i);
if r >= 0 {
cached_weight += weight;
assert_eq!(1000 + i, r);
}
}
let limit = CACHE_TEST_CACHE_SIZE as i32 + CACHE_TEST_CACHE_SIZE as i32 / 10;
assert!(
cached_weight <= limit,
"cached_weight={} limit={}",
cached_weight,
limit
);
}
#[traced_test]
fn cache_test_new_id() {
let mut fixture = CacheTest::new(CACHE_TEST_CACHE_SIZE);
set_current_cache_test(&mut fixture as *mut CacheTest);
let a = unsafe {
let cache = fixture.cache_mut();
(**cache).new_id()
};
let b = unsafe {
let cache = fixture.cache_mut();
(**cache).new_id()
};
assert_ne!(a, b);
}
#[traced_test]
fn cache_test_prune() {
let mut fixture = CacheTest::new(CACHE_TEST_CACHE_SIZE);
set_current_cache_test(&mut fixture as *mut CacheTest);
fixture.insert(1, 100, None);
fixture.insert(2, 200, None);
let handle = unsafe {
let encoded = encode_key(1);
let key_slice: Slice = (&encoded[..]).into();
let cache = fixture.cache_mut();
(**cache).lookup(&key_slice)
};
assert!(!handle.is_null());
unsafe {
let cache = fixture.cache_mut();
(**cache).prune();
(**cache).release(handle);
}
assert_eq!(100, fixture.lookup(1));
assert_eq!(-1, fixture.lookup(2));
}
#[traced_test]
fn cache_test_zero_size() {
let mut fixture = CacheTest::new(CACHE_TEST_CACHE_SIZE);
set_current_cache_test(&mut fixture as *mut CacheTest);
fixture.reset_cache(0);
fixture.insert(1, 100, None);
assert_eq!(-1, fixture.lookup(1));
}