From 3fff5e94ebf772f8485aaa2bda2ea36be766fdb3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 10 Aug 2018 21:13:46 +0300 Subject: Add arena --- libanalysis/src/arena.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 libanalysis/src/arena.rs (limited to 'libanalysis') diff --git a/libanalysis/src/arena.rs b/libanalysis/src/arena.rs new file mode 100644 index 000000000..fc0c25c54 --- /dev/null +++ b/libanalysis/src/arena.rs @@ -0,0 +1,42 @@ +use parking_lot::RwLock; + +const CHUNK_LEN: usize = 16; + +pub struct Arena { + chunks: RwLock>>, +} + +impl Arena { + pub fn new(&self) -> Arena { + Arena { + chunks: RwLock::new(vec![Vec::with_capacity(CHUNK_LEN)]), + } + } + + pub fn push(&self, value: T) -> usize { + let mut guard = self.chunks.write(); + let mut idx = (guard.len() - 1) * CHUNK_LEN; + let chunk = { + if guard.last().unwrap().len() == CHUNK_LEN { + guard.push(Vec::with_capacity(CHUNK_LEN)); + } + guard.last_mut().unwrap() + }; + assert!(chunk.len() < chunk.capacity()); + idx += chunk.len(); + chunk.push(value); + idx + } + + pub fn get(&self, idx: usize) -> &T { + let chunk_idx = idx / CHUNK_LEN; + let chunk_off = idx - chunk_idx * CHUNK_LEN; + let guard = self.chunks.read(); + let value = &guard[chunk_idx][chunk_off]; + unsafe { + // We are careful to not move values in chunks, + // so this hopefully is safe + ::std::mem::transmute::<&T, &T>(value) + } + } +} -- cgit v1.2.3