pchain_sdk/collections/
vector.rs1use std::cell::RefCell;
9use std::collections::BTreeMap;
10use std::ops::Index;
11use std::ops::IndexMut;
12use borsh::{BorshSerialize, BorshDeserialize};
13
14use crate::storage;
15use crate::{Storable, StoragePath};
16
17#[derive(Clone, Default)]
69pub struct Vector<T> where T: Storable {
70 write_set: RefCell<BTreeMap<usize, T>>,
71 read_set: RefCell<BTreeMap<usize, T>>,
72 length: usize,
74 parent_key: Vec<u8>
76}
77
78pub struct VectorIter<'a, T> where T: Storable + Clone {
80 vector: &'a Vector<T>,
81 idx: usize,
82}
83
84pub struct VectorIterMut<'a, T> where T: Storable + Clone {
86 vector: &'a mut Vector<T>,
87 idx: usize,
88}
89
90impl<'a, T> Vector<T> where T: Storable + Clone {
91 pub fn new() -> Self {
92 Self {
93 write_set: RefCell::new(BTreeMap::new()),
94 read_set: RefCell::new(BTreeMap::new()),
95 length:0,
96 parent_key: vec![]
97 }
98 }
99
100 pub fn len(&self) -> usize {
102 self.length
103 }
104
105 pub fn is_empty(&self) -> bool {
107 self.len() == 0
108 }
109
110 pub fn push(&mut self, value: &T) {
112 self.write_set.get_mut().insert(self.length, value.clone());
113 self.length += 1;
114 }
115
116 pub fn pop(&mut self) {
119 if self.length > 0 {
120 self.length -= 1;
121 self.write_set.get_mut().remove(&(self.length));
122 self.read_set.get_mut().remove(&(self.length));
123 }
124 }
125
126 fn get(&self, idx: usize) -> &T {
127 self.get_mut(idx)
128 }
129
130 #[allow(clippy::mut_from_ref)]
132 fn get_mut(&self, idx: usize) -> &mut T {
133 if idx >= self.length {
134 panic!()
135 }
136
137 if let Some(value) = self.write_set.borrow_mut().get_mut(&idx) {
139 return self.write_to_read_set(idx, value.clone())
141 }
142
143 if let Some(value) = self.read_set.borrow_mut().get_mut(&idx) {
145 return unsafe {
146 let r = value as * const T;
147 &mut *(r as *mut T)
148 }
149 }
150
151 if self.parent_key.is_empty() { panic!() }
153
154 let value = T::__load_storage(&StoragePath::new().append(Self::wskey_index(self.parent_key.clone(), idx)));
156
157 self.write_to_read_set(idx, value)
159 }
160
161 #[allow(clippy::mut_from_ref)]
162 fn write_to_read_set(&self, idx: usize, value: T) -> &mut T {
163 let mut read_set = self.read_set.borrow_mut();
164 read_set.insert(idx, value);
165
166 match read_set.get_mut(&idx) {
167 Some(value) => {
168 unsafe{
169 let r = value as * const T;
170 &mut *(r as *mut T)
171 }
172 }
173 None => unreachable!()
174 }
175 }
176
177 fn write_to_write_set(&mut self, idx: usize, value: T) -> &mut T {
178 let mut write_set = self.write_set.borrow_mut();
179 write_set.insert(idx, value);
180
181 match write_set.get_mut(&idx) {
182 Some(value) => {
183 unsafe{
184 let r = value as * const T;
185 &mut *(r as *mut T)
186 }
187 }
188 None => unreachable!()
189 }
190 }
191
192 pub fn iter(&'a self) -> VectorIter<'a, T> {
194 VectorIter { vector: self, idx: 0 }
195 }
196
197 pub fn iter_mut(&'a mut self) -> VectorIterMut<'a, T> {
199 VectorIterMut { vector: self, idx: 0 }
200 }
201
202 fn len_in_ws(parent_key: Vec<u8>) -> usize {
204 storage::get(Self::wskey_len(parent_key).as_slice()).map_or(0, |bytes|{
205 usize::deserialize(&mut bytes.as_slice()).map_or(0, std::convert::identity)
206 })
207 }
208
209 fn wskey_len(parent_key: Vec<u8>) -> Vec<u8> {
211 [
212 parent_key,
213 [0u8].to_vec()
214 ].concat()
215 }
216
217 fn wskey_index(parent_key: Vec<u8>, idx: usize) -> Vec<u8> {
219 [
220 parent_key,
221 [1u8].to_vec(),
222 (idx as u32).to_le_bytes().to_vec()
223 ].concat()
224 }
225}
226
227impl<'a, T> Iterator for VectorIter<'a, T> where T: Storable + Clone {
228 type Item = &'a T;
229
230 fn next(&mut self) -> Option<Self::Item> {
231 if self.idx >= self.vector.len() {
232 return None
233 }
234 let value = self.vector.get(self.idx);
235 self.idx += 1;
236 Some(value)
237 }
238}
239
240impl<'a, T> Iterator for VectorIterMut<'a, T> where T: Storable + Clone {
241 type Item = &'a mut T;
242
243 fn next(&mut self) -> Option<Self::Item> {
244 if self.idx >= self.vector.len() {
245 return None
246 };
247 let value = self.vector.get(self.idx);
248 let ret = self.vector.write_to_write_set(self.idx, value.clone());
249 self.idx += 1;
250 Some(unsafe{
251 let r = ret as * const T;
252 &mut *(r as *mut T)
253 })
254 }
255}
256
257impl<T> Index<usize> for Vector<T> where T: Storable + Clone {
258 type Output = T;
259
260 fn index(&self, index: usize) -> &Self::Output {
261 self.get(index)
262 }
263}
264
265impl<T> IndexMut<usize> for Vector<T> where T: Storable + Clone {
266 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
267 let value = self.get(index);
268 self.write_to_write_set(index, value.clone())
270 }
271}
272
273impl<T> Storable for Vector<T> where T: Storable + Clone {
274 fn __load_storage(field: &StoragePath) -> Self {
275 let parent_key = field.get_path().to_vec();
276 Self {
277 write_set: RefCell::new(BTreeMap::new()),
278 read_set: RefCell::new(BTreeMap::new()),
279 length: Self::len_in_ws(parent_key.clone()),
280 parent_key,
281 }
282 }
283
284 fn __save_storage(&mut self, field :&StoragePath) {
285 let field_path = field.get_path().to_vec();
286 if self.parent_key != field_path {
288 self.parent_key = field_path;
289 }
290
291 if self.length != Self::len_in_ws(self.parent_key.clone()) {
293 storage::set(&Self::wskey_len(self.parent_key.clone()), self.length.try_to_vec().unwrap().as_slice());
294 }
295
296 let mut write_set = self.write_set.borrow_mut();
298 write_set.iter_mut().for_each(|(idx, v)|{
299 v.__save_storage(&StoragePath::new().append(Self::wskey_index(self.parent_key.clone(), *idx)));
300 });
301 }
302}