-
Notifications
You must be signed in to change notification settings - Fork 3
/
arena.rs
77 lines (68 loc) · 1.84 KB
/
arena.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
/// A struct to hold all bytes into the same Vec
#[derive(Debug)]
pub struct Arena {
data: Vec<u8>,
pos: Vec<usize>,
}
impl Arena {
pub fn new() -> Arena {
Arena {
data: Vec::new(),
pos: vec![0],
}
}
pub fn with_capacity(data_cap: usize, item_cap: usize) -> Arena {
let mut pos = Vec::with_capacity(item_cap + 1);
pos.push(0);
Arena {
data: Vec::with_capacity(data_cap),
pos,
}
}
pub fn push(&mut self, data: &[u8]) -> usize {
debug!(
"pushing data {} (len {}) in arena (len {})",
self.pos.len(),
data.len(),
self.data.len()
);
self.data.extend_from_slice(data);
self.pos.push(self.data.len());
self.pos.len() - 1
}
pub fn insert(&mut self, index: usize, data: &[u8]) {
debug!(
"inserting data {} (len {}) at position {} in arena (len {})",
self.pos.len(),
data.len(),
index,
self.data.len()
);
self.data[self.pos[index - 1]..self.pos[index]].copy_from_slice(data);
}
}
impl ::std::ops::Index<usize> for Arena {
type Output = [u8];
fn index(&self, i: usize) -> &[u8] {
&self.data[self.pos[i - 1]..self.pos[i]]
}
}
pub struct ArenaSlice<'a>(pub &'a [&'a [u8]]);
impl<'a> ::std::ops::Index<usize> for ArenaSlice<'a> {
type Output = [u8];
fn index(&self, i: usize) -> &[u8] {
&*self.0[i]
}
}
#[cfg(test)]
mod test {
use super::Arena;
#[test]
fn arena() {
let mut arena = Arena::new();
let idx = arena.push("test".as_bytes());
let idx2 = arena.push("test2".as_bytes());
assert_eq!(&arena[idx], "test".as_bytes());
assert_eq!(&arena[idx2], "test2".as_bytes(), "{:?}", arena);
}
}