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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use register::Register;
pub use self::cacheable::Cacheable;
mod cacheable;
#[cfg(test)]
mod test;
#[cfg(test)]
mod bench;
#[allow(dead_code)]
pub struct Cache<C: Cacheable> {
register: Box<Register<C::UpperKey, *mut Register<C::LowerKey, C::Payload>>>,
registers: Box<[Register<C::LowerKey, C::Payload>]>
}
impl<C: Cacheable> Cache<C> {
pub fn new(cache_size: usize, register_size: usize) -> Cache<C> {
let mut registers = Vec::with_capacity(cache_size);
let mut register = Register::new(cache_size);
for _ in 0..cache_size {
registers.push(Register::<C::LowerKey, C::Payload>::new(register_size));
}
let mut registers_box = registers.into_boxed_slice();
for i in 0..cache_size {
register.entries[i].payload = &mut registers_box[i] as *mut Register<C::LowerKey, C::Payload>;
}
Cache{
register: Box::new(register),
registers: registers_box
}
}
#[inline]
pub fn set(&mut self, upper_key: C::UpperKey, lower_key: C::LowerKey, payload: C::Payload) -> bool {
match self.register.get(upper_key) {
Some(pcache) => {
let mut cache: &mut Register<C::LowerKey, C::Payload> = unsafe{ &mut **pcache };
return cache.set(lower_key, Some(payload))
},
None => ()
}
self.register.set(upper_key, None);
let mut cache: &mut Register<C::LowerKey, C::Payload> = unsafe{ &mut **self.register.get(upper_key).unwrap() };
cache.reset();
cache.set(lower_key, Some(payload))
}
#[inline]
pub fn has(&mut self, upper_key: C::UpperKey) -> Option<usize> {
self.register.get(upper_key).map(|pcache| unsafe{ &mut **pcache }.cur_size )
}
#[inline]
pub fn get(&mut self, upper_key: C::UpperKey, lower_key: C::LowerKey) -> Option<&C::Payload> {
match self.register.get(upper_key) {
Some(pcache) => {
let cache: &mut Register<C::LowerKey, C::Payload> = unsafe{ &mut **pcache };
cache.get(lower_key)
},
None => None
}
}
}
#[cfg(test)]
struct Types;
#[cfg(test)]
impl Cacheable for Types {
type UpperKey = u8;
type LowerKey = u8;
type Payload = bool;
}
#[test]
fn initialize_registers() {
let mut cache = Cache::<Types>::new(10, 10);
let entries = cache.register.entries;
let mut iter = entries.iter().enumerate();
assert!(entries.len() == 10);
loop {
match iter.next() {
Some((i, entry)) => {
assert!(entry.payload == &mut cache.registers[i] as *mut Register<u8, bool>);
},
None => { break; }
}
}
}