mycroft_support/storage/
data.rs1use index::hash::HashIndex;
5use std::hash::Hash;
6use std::ops::Index;
7use std::rc::Rc;
8use std::cell::UnsafeCell;
9
10pub struct Data<T> {
15 raw: Rc<UnsafeCell<RawData<T>>>,
16}
17
18impl<T> Clone for Data<T> {
19 fn clone(&self) -> Self {
20 Self {
21 raw: self.raw.clone(),
22 }
23 }
24}
25
26#[derive(Debug, Eq, Clone, PartialEq)]
27enum Usage {
28 Read(usize),
29 Write,
30}
31
32struct RawData<T> {
33 inner: Vec<T>,
34 index: HashIndex<T>,
35 usage: Usage,
37}
38
39impl<T: PartialEq + Hash> Data<T> {
40 pub fn new() -> Self {
42 Self {
43 raw: Rc::new(UnsafeCell::new(RawData::new())),
44 }
45 }
46
47 pub fn insert(&self, data: T) -> usize {
50 unsafe {
51 let raw: &mut RawData<T> = &mut *self.raw.get();
52 raw.insert(data)
53 }
54 }
55
56 pub unsafe fn read_exit(&self, delta: usize) {
58 (*self.raw.get()).read_exit(delta)
59 }
60}
61
62impl<T: PartialEq + Hash> RawData<T> {
63 fn new() -> Self {
64 RawData {
65 inner: Vec::new(),
66 index: HashIndex::new(),
67 usage: Usage::Read(0),
68 }
69 }
70
71 fn insert(&mut self, data: T) -> usize {
72 assert_eq!(self.usage, Usage::Read(0));
74 self.usage = Usage::Write;
75 let key = match self.find(&data) {
76 Some(key) => key,
77 None => {
78 let key = self.inner.len();
79 self.index.insert(key, &data);
80 self.inner.push(data);
81 key
82 }
83 };
84 self.usage = Usage::Read(0);
85 key
86 }
87
88 fn find(&self, data: &T) -> Option<usize> {
89 self.index.find(data, &self.inner)
90 }
91}
92
93impl<T> RawData<T> {
94 fn read_exit(&mut self, delta: usize) {
95 match self.usage {
96 Usage::Read(n) => self.usage = Usage::Read(n - delta),
97 Usage::Write => panic!("Tried to end read borrow while write was in progress"),
98 }
99 }
100 fn read_enter(&mut self, delta: usize) {
101 match self.usage {
102 Usage::Read(n) => self.usage = Usage::Read(n + delta),
103 Usage::Write => panic!("Tried to start reading while a write is in progress"),
104 }
105 }
106}
107
108impl<T> Index<usize> for Data<T> {
109 type Output = T;
110 fn index(&self, key: usize) -> &Self::Output {
111 unsafe {
112 let raw = &mut *self.raw.get();
113 raw.read_enter(1);
114 &raw.inner[key]
115 }
116 }
117}