added first unittests
This commit is contained in:
parent
7ed3555489
commit
9cf7b2f2b0
@ -5,12 +5,15 @@ pub struct PoolCfg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PoolCfg {
|
impl PoolCfg {
|
||||||
pub fn add_pool(&mut self, num_elems: NumBuckets, elem_size: usize) {
|
pub fn new(cfg: Vec<(NumBuckets, usize)>) -> Self {
|
||||||
self.cfg.push((num_elems, elem_size))
|
PoolCfg { cfg }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn order(&mut self) -> usize {
|
pub fn sanitize(&mut self) -> usize {
|
||||||
self.cfg.sort_unstable();
|
self.cfg
|
||||||
|
.retain(|&(bucket_num, size)| bucket_num > 0 && size < LocalPool::MAX_SIZE);
|
||||||
|
self.cfg
|
||||||
|
.sort_unstable_by(|(_, sz0), (_, sz1)| sz0.partial_cmp(sz1).unwrap());
|
||||||
self.cfg.len()
|
self.cfg.len()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,7 +54,7 @@ impl LocalPool {
|
|||||||
const MAX_SIZE: PoolSize = Self::STORE_FREE - 1;
|
const MAX_SIZE: PoolSize = Self::STORE_FREE - 1;
|
||||||
|
|
||||||
pub fn new(mut cfg: PoolCfg) -> LocalPool {
|
pub fn new(mut cfg: PoolCfg) -> LocalPool {
|
||||||
let subpools_num = cfg.order();
|
let subpools_num = cfg.sanitize();
|
||||||
let mut local_pool = LocalPool {
|
let mut local_pool = LocalPool {
|
||||||
pool_cfg: cfg,
|
pool_cfg: cfg,
|
||||||
pool: Vec::with_capacity(subpools_num),
|
pool: Vec::with_capacity(subpools_num),
|
||||||
@ -186,3 +189,34 @@ impl LocalPool {
|
|||||||
Some(addr.packet_idx as usize * size)
|
Some(addr.packet_idx as usize * size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::core::pool::{LocalPool, PoolCfg};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cfg() {
|
||||||
|
// Values where number of buckets is 0 or size is too large should be removed
|
||||||
|
let mut pool_cfg = PoolCfg::new(vec![(0, 0), (1, 0), (2, LocalPool::MAX_SIZE)]);
|
||||||
|
pool_cfg.sanitize();
|
||||||
|
assert_eq!(pool_cfg.cfg, vec![(1, 0)]);
|
||||||
|
// Entries should be ordered according to bucket size
|
||||||
|
pool_cfg = PoolCfg::new(vec![(16, 6), (32, 3), (8, 12)]);
|
||||||
|
pool_cfg.sanitize();
|
||||||
|
assert_eq!(pool_cfg.cfg, vec![(32, 3), (16, 6), (8, 12)]);
|
||||||
|
// Unstable sort is used, so order of entries with same block length should not matter
|
||||||
|
pool_cfg = PoolCfg::new(vec![(12, 12), (14, 16), (10, 12)]);
|
||||||
|
pool_cfg.sanitize();
|
||||||
|
assert!(
|
||||||
|
pool_cfg.cfg == vec![(12, 12), (10, 12), (14, 16)]
|
||||||
|
|| pool_cfg.cfg == vec![(10, 12), (12, 12), (14, 16)]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_basic() {
|
||||||
|
// 4 buckets of 4 bytes, 2 of 8 bytes and 1 of 16 bytes
|
||||||
|
let pool_cfg = PoolCfg::new(vec![(4, 4), (2, 8), (1, 16)]);
|
||||||
|
let _local_pool = LocalPool::new(pool_cfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
92
src/main.rs
92
src/main.rs
@ -1,3 +1,91 @@
|
|||||||
fn main() {
|
use std::sync::{Arc, RwLock};
|
||||||
println!("Hello World")
|
use std::thread;
|
||||||
|
|
||||||
|
struct PoolDummy {
|
||||||
|
test_buf: [u8; 128],
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PoolAccessDummy<'a> {
|
||||||
|
pool_dummy: &'a mut PoolDummy,
|
||||||
|
no_deletion: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PoolAccessDummy<'_> {
|
||||||
|
fn modify(&mut self) -> &mut [u8] {
|
||||||
|
self.pool_dummy.modify()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn release(&mut self) {
|
||||||
|
self.no_deletion = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for PoolAccessDummy<'_> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if self.no_deletion {
|
||||||
|
println!("Pool access: Drop with no deletion")
|
||||||
|
} else {
|
||||||
|
self.pool_dummy.delete();
|
||||||
|
println!("Pool access: Drop with deletion");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PoolDummy {
|
||||||
|
fn default() -> Self {
|
||||||
|
PoolDummy { test_buf: [0; 128] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PoolDummy {
|
||||||
|
fn modify(&mut self) -> &mut [u8] {
|
||||||
|
self.test_buf.as_mut_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn modify_with_accessor(&mut self) -> PoolAccessDummy {
|
||||||
|
PoolAccessDummy {
|
||||||
|
pool_dummy: self,
|
||||||
|
no_deletion: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read(&self) -> &[u8] {
|
||||||
|
self.test_buf.as_slice()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn delete(&mut self) {
|
||||||
|
println!("Store content was deleted");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
println!("Hello World");
|
||||||
|
let shared_dummy = Arc::new(RwLock::new(PoolDummy::default()));
|
||||||
|
let shared_clone = shared_dummy.clone();
|
||||||
|
let jh0 = thread::spawn(move || loop {
|
||||||
|
{
|
||||||
|
let mut dummy = shared_dummy.write().unwrap();
|
||||||
|
let buf = dummy.modify();
|
||||||
|
buf[0] = 1;
|
||||||
|
|
||||||
|
let mut accessor = dummy.modify_with_accessor();
|
||||||
|
let buf = accessor.modify();
|
||||||
|
buf[0] = 2;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let jh1 = thread::spawn(move || loop {
|
||||||
|
{
|
||||||
|
let dummy = shared_clone.read().unwrap();
|
||||||
|
let buf = dummy.read();
|
||||||
|
println!("Buffer 0: {:?}", buf[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut dummy = shared_clone.write().unwrap();
|
||||||
|
let mut accessor = dummy.modify_with_accessor();
|
||||||
|
let buf = accessor.modify();
|
||||||
|
buf[0] = 3;
|
||||||
|
accessor.release();
|
||||||
|
});
|
||||||
|
jh0.join().unwrap();
|
||||||
|
jh1.join().unwrap();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user