1use std::marker::PhantomData;
2use std::fmt::{self, Formatter};
3use std::hash::{self, Hasher};
4use std::cmp::Ordering;
5
6#[derive(Clone)]
15pub struct Reservoir<T>(Vec<T>);
16
17impl<T> Reservoir<T> {
18 pub const SMALL_CAPACITY: usize = 64;
19 pub const MEDIUM_CAPACITY: usize = 256;
20 pub const LARGE_CAPACITY: usize = 1024;
21
22 pub fn new(capacity: usize) -> Self {
23 Reservoir(Vec::with_capacity(capacity))
24 }
25
26 pub fn get(&self, handle: Handle<T>) -> &T {
27 &self.0[handle.0]
28 }
29
30 pub fn get_mut(&mut self, handle: Handle<T>) -> &mut T {
31 &mut self.0[handle.0]
32 }
33
34 pub fn insert(&mut self, data: T) -> Handle<T> {
35 self.0.push(data);
36 Handle(self.0.len() - 1, PhantomData)
37 }
38}
39
40impl<T> Default for Reservoir<T> {
41 fn default() -> Self {
42 Reservoir::new(Self::MEDIUM_CAPACITY)
43 }
44}
45
46pub struct Handle<T>(usize, PhantomData<T>);
49
50impl<T> Clone for Handle<T> {
51 fn clone(&self) -> Self {
52 Handle(self.0, self.1)
53 }
54}
55
56impl<T> fmt::Debug for Handle<T> {
57 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
58 write!(f, "Handle({})", self.0)
59 }
60}
61
62impl<T> hash::Hash for Handle<T> {
63 fn hash<H>(&self, state: &mut H) where H: Hasher {
64 self.0.hash(state)
65 }
66}
67
68impl<T> PartialEq for Handle<T> {
69 fn eq(&self, other: &Self) -> bool {
70 self.0 == other.0
71 }
72}
73
74impl<T> PartialOrd for Handle<T> {
75 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
76 self.0.partial_cmp(&other.0)
77 }
78}
79
80impl<T> Ord for Handle<T> {
81 fn cmp(&self, other: &Self) -> Ordering {
82 self.0.cmp(&other.0)
83 }
84}
85
86impl<T> Copy for Handle<T> {}
87impl<T> Eq for Handle<T> {}
88
89#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[test]
101 fn sanity_check() {
102 let mut r: Reservoir<String> = Reservoir::default();
103 let h = r.insert(String::from("hello"));
104 assert_eq!("hello", r.get(h));
105
106 r.get_mut(h).push('!');
107 assert_eq!("hello!", r.get(h));
108 }
109}