1use crate::tickv::{KVSystem, KVSystemClient, KeyType};
31use kernel::hil::kv;
32use kernel::utilities::cells::{MapCell, OptionalCell, TakeCell};
33use kernel::utilities::leasable_buffer::SubSliceMut;
34use kernel::ErrorCode;
35
36#[derive(Clone, Copy, PartialEq, Debug)]
37enum Operation {
38 Get,
39 Set,
40 Add,
41 Update,
42 Delete,
43 GarbageCollect,
44}
45
46pub struct TicKVKVStore<'a, K: KVSystem<'a> + KVSystem<'a, K = T>, T: 'static + KeyType> {
49 kv: &'a K,
50 hashed_key: TakeCell<'static, T>,
51
52 client: OptionalCell<&'a dyn kv::KVClient>,
53 operation: OptionalCell<Operation>,
54
55 unhashed_key: MapCell<SubSliceMut<'static, u8>>,
56 value: MapCell<SubSliceMut<'static, u8>>,
57}
58
59impl<'a, K: KVSystem<'a, K = T>, T: KeyType> TicKVKVStore<'a, K, T> {
60 pub fn new(kv: &'a K, key: &'static mut T) -> TicKVKVStore<'a, K, T> {
61 Self {
62 kv,
63 hashed_key: TakeCell::new(key),
64 client: OptionalCell::empty(),
65 operation: OptionalCell::empty(),
66 unhashed_key: MapCell::empty(),
67 value: MapCell::empty(),
68 }
69 }
70
71 fn insert(
72 &self,
73 key: SubSliceMut<'static, u8>,
74 value: SubSliceMut<'static, u8>,
75 operation: Operation,
76 ) -> Result<
77 (),
78 (
79 SubSliceMut<'static, u8>,
80 SubSliceMut<'static, u8>,
81 ErrorCode,
82 ),
83 > {
84 if self.operation.is_some() {
85 return Err((key, value, ErrorCode::BUSY));
86 }
87
88 self.operation.set(operation);
89
90 match self.hashed_key.take() {
91 Some(hashed_key) => match self.kv.generate_key(key, hashed_key) {
92 Ok(()) => {
93 self.value.replace(value);
94 Ok(())
95 }
96 Err((unhashed_key, hashed_key, _e)) => {
97 self.operation.clear();
98 self.hashed_key.replace(hashed_key);
99 Err((unhashed_key, value, ErrorCode::FAIL))
100 }
101 },
102 None => Err((key, value, ErrorCode::FAIL)),
103 }
104 }
105}
106
107impl<'a, K: KVSystem<'a, K = T>, T: KeyType> kv::KV<'a> for TicKVKVStore<'a, K, T> {
108 fn set_client(&self, client: &'a dyn kv::KVClient) {
109 self.client.set(client);
110 }
111
112 fn get(
113 &self,
114 key: SubSliceMut<'static, u8>,
115 value: SubSliceMut<'static, u8>,
116 ) -> Result<
117 (),
118 (
119 SubSliceMut<'static, u8>,
120 SubSliceMut<'static, u8>,
121 ErrorCode,
122 ),
123 > {
124 if self.operation.is_some() {
125 return Err((key, value, ErrorCode::BUSY));
126 }
127
128 self.operation.set(Operation::Get);
129
130 match self.hashed_key.take() {
131 Some(hashed_key) => match self.kv.generate_key(key, hashed_key) {
132 Ok(()) => {
133 self.value.replace(value);
134 Ok(())
135 }
136 Err((unhashed_key, hashed_key, _e)) => {
137 self.operation.clear();
138 self.hashed_key.replace(hashed_key);
139 Err((unhashed_key, value, ErrorCode::FAIL))
140 }
141 },
142 None => Err((key, value, ErrorCode::FAIL)),
143 }
144 }
145
146 fn set(
147 &self,
148 key: SubSliceMut<'static, u8>,
149 value: SubSliceMut<'static, u8>,
150 ) -> Result<
151 (),
152 (
153 SubSliceMut<'static, u8>,
154 SubSliceMut<'static, u8>,
155 ErrorCode,
156 ),
157 > {
158 self.insert(key, value, Operation::Set)
159 }
160
161 fn add(
162 &self,
163 key: SubSliceMut<'static, u8>,
164 value: SubSliceMut<'static, u8>,
165 ) -> Result<
166 (),
167 (
168 SubSliceMut<'static, u8>,
169 SubSliceMut<'static, u8>,
170 ErrorCode,
171 ),
172 > {
173 self.insert(key, value, Operation::Add)
174 }
175
176 fn update(
177 &self,
178 key: SubSliceMut<'static, u8>,
179 value: SubSliceMut<'static, u8>,
180 ) -> Result<
181 (),
182 (
183 SubSliceMut<'static, u8>,
184 SubSliceMut<'static, u8>,
185 ErrorCode,
186 ),
187 > {
188 self.insert(key, value, Operation::Update)
189 }
190
191 fn delete(
192 &self,
193 key: SubSliceMut<'static, u8>,
194 ) -> Result<(), (SubSliceMut<'static, u8>, ErrorCode)> {
195 if self.operation.is_some() {
196 return Err((key, ErrorCode::BUSY));
197 }
198
199 self.operation.set(Operation::Delete);
200
201 match self.hashed_key.take() {
202 Some(hashed_key) => match self.kv.generate_key(key, hashed_key) {
203 Ok(()) => Ok(()),
204 Err((unhashed_key, hashed_key, _e)) => {
205 self.hashed_key.replace(hashed_key);
206 self.operation.clear();
207 Err((unhashed_key, ErrorCode::FAIL))
208 }
209 },
210 None => Err((key, ErrorCode::FAIL)),
211 }
212 }
213
214 fn garbage_collect(&self) -> Result<(), ErrorCode> {
215 if self.operation.is_some() {
216 return Err(ErrorCode::BUSY);
217 }
218
219 self.operation.set(Operation::GarbageCollect);
220
221 if let Err(e) = self.kv.garbage_collect() {
222 self.operation.clear();
223 Err(e)
224 } else {
225 Ok(())
226 }
227 }
228}
229
230impl<'a, K: KVSystem<'a, K = T>, T: KeyType> KVSystemClient<T> for TicKVKVStore<'a, K, T> {
231 fn generate_key_complete(
232 &self,
233 result: Result<(), ErrorCode>,
234 unhashed_key: SubSliceMut<'static, u8>,
235 hashed_key: &'static mut T,
236 ) {
237 self.operation.map(|op| {
238 if result.is_err() {
239 self.hashed_key.replace(hashed_key);
243 self.operation.clear();
244
245 match op {
246 Operation::Get => {
247 self.value.take().map(|value| {
248 self.client.map(move |cb| {
249 cb.get_complete(Err(ErrorCode::FAIL), unhashed_key, value);
250 });
251 });
252 }
253 Operation::Set => {
254 self.value.take().map(|value| {
255 self.client.map(move |cb| {
256 cb.set_complete(Err(ErrorCode::FAIL), unhashed_key, value);
257 });
258 });
259 }
260 Operation::Add => {
261 self.value.take().map(|value| {
262 self.client.map(move |cb| {
263 cb.add_complete(Err(ErrorCode::FAIL), unhashed_key, value);
264 });
265 });
266 }
267 Operation::Update => {
268 self.value.take().map(|value| {
269 self.client.map(move |cb| {
270 cb.update_complete(Err(ErrorCode::FAIL), unhashed_key, value);
271 });
272 });
273 }
274 Operation::Delete => {
275 self.client.map(move |cb| {
276 cb.delete_complete(Err(ErrorCode::FAIL), unhashed_key);
277 });
278 }
279 Operation::GarbageCollect => {}
280 }
281 } else {
282 match op {
283 Operation::Get => {
284 self.value
285 .take()
286 .map(|value| match self.kv.get_value(hashed_key, value) {
287 Ok(()) => {
288 self.unhashed_key.replace(unhashed_key);
289 }
290 Err((key, value, _e)) => {
291 self.hashed_key.replace(key);
292 self.operation.clear();
293 self.client.map(move |cb| {
294 cb.get_complete(Err(ErrorCode::FAIL), unhashed_key, value);
295 });
296 }
297 });
298 }
299 Operation::Set => {
300 self.value.take().map(|value| {
301 match self.kv.append_key(hashed_key, value) {
303 Ok(()) => {
304 self.unhashed_key.replace(unhashed_key);
305 }
306 Err((key, value, e)) => {
307 self.hashed_key.replace(key);
308 self.operation.clear();
309 self.client.map(move |cb| {
310 cb.set_complete(Err(e), unhashed_key, value);
311 });
312 }
313 }
314 });
315 }
316 Operation::Add => {
317 self.value.take().map(|value| {
318 match self.kv.append_key(hashed_key, value) {
321 Ok(()) => {
322 self.unhashed_key.replace(unhashed_key);
323 }
324 Err((key, value, e)) => {
325 self.hashed_key.replace(key);
326 self.operation.clear();
327 self.client.map(move |cb| {
328 cb.add_complete(Err(e), unhashed_key, value);
329 });
330 }
331 }
332 });
333 }
334 Operation::Update => {
335 match self.kv.invalidate_key(hashed_key) {
338 Ok(()) => {
339 self.unhashed_key.replace(unhashed_key);
340 }
341 Err((key, _e)) => {
342 self.hashed_key.replace(key);
343 self.operation.clear();
344 self.value.take().map(|value| {
345 self.client.map(move |cb| {
346 cb.update_complete(
347 Err(ErrorCode::FAIL),
348 unhashed_key,
349 value,
350 );
351 });
352 });
353 }
354 }
355 }
356 Operation::Delete => match self.kv.invalidate_key(hashed_key) {
357 Ok(()) => {
358 self.unhashed_key.replace(unhashed_key);
359 }
360 Err((key, _e)) => {
361 self.hashed_key.replace(key);
362 self.operation.clear();
363 self.client.map(move |cb| {
364 cb.delete_complete(Err(ErrorCode::FAIL), unhashed_key);
365 });
366 }
367 },
368 Operation::GarbageCollect => {}
369 }
370 }
371 });
372 }
373
374 fn append_key_complete(
375 &self,
376 result: Result<(), ErrorCode>,
377 key: &'static mut T,
378 value: SubSliceMut<'static, u8>,
379 ) {
380 self.hashed_key.replace(key);
381
382 self.operation.map(|op| match op {
383 Operation::Get | Operation::Delete => {}
384 Operation::Set => {
385 match result {
386 Err(ErrorCode::NOSUPPORT) => {
387 self.hashed_key.take().map(|hashed_key| {
390 match self.kv.invalidate_key(hashed_key) {
391 Ok(()) => {
392 self.value.replace(value);
393 }
394 Err((key, _e)) => {
395 self.hashed_key.replace(key);
396 self.operation.clear();
397 self.unhashed_key.take().map(|unhashed_key| {
398 self.client.map(move |cb| {
399 cb.set_complete(
400 Err(ErrorCode::FAIL),
401 unhashed_key,
402 value,
403 );
404 });
405 });
406 }
407 }
408 });
409 }
410 _ => {
411 self.operation.clear();
414 self.unhashed_key.take().map(|unhashed_key| {
415 self.client.map(move |cb| {
416 cb.set_complete(
417 result.map_err(|e| match e {
418 ErrorCode::NOMEM => ErrorCode::NOMEM,
419 _ => ErrorCode::FAIL,
420 }),
421 unhashed_key,
422 value,
423 );
424 });
425 });
426 }
427 }
428 }
429 Operation::Add => {
430 self.operation.clear();
431 self.unhashed_key.take().map(|unhashed_key| {
432 self.client.map(move |cb| {
433 cb.add_complete(
434 result.map_err(|e| match e {
435 ErrorCode::NOSUPPORT => ErrorCode::NOSUPPORT,
436 ErrorCode::NOMEM => ErrorCode::NOMEM,
437 _ => ErrorCode::FAIL,
438 }),
439 unhashed_key,
440 value,
441 );
442 });
443 });
444 }
445 Operation::Update => {
446 self.operation.clear();
447 self.unhashed_key.take().map(|unhashed_key| {
448 self.client.map(move |cb| {
449 cb.update_complete(
450 result.map_err(|e| match e {
451 ErrorCode::NOMEM => ErrorCode::NOMEM,
452 _ => ErrorCode::FAIL,
453 }),
454 unhashed_key,
455 value,
456 );
457 });
458 });
459 }
460 Operation::GarbageCollect => {}
461 });
462 }
463
464 fn get_value_complete(
465 &self,
466 result: Result<(), ErrorCode>,
467 key: &'static mut T,
468 ret_buf: SubSliceMut<'static, u8>,
469 ) {
470 self.operation.map(|op| match op {
471 Operation::Get => {
472 self.hashed_key.replace(key);
473 self.operation.clear();
474
475 self.unhashed_key.take().map(|unhashed_key| {
476 self.client.map(move |cb| {
477 cb.get_complete(
478 result.map_err(|e| match e {
479 ErrorCode::SIZE => ErrorCode::SIZE,
480 ErrorCode::NOSUPPORT => ErrorCode::NOSUPPORT,
481 _ => ErrorCode::FAIL,
482 }),
483 unhashed_key,
484 ret_buf,
485 );
486 });
487 });
488 }
489 _ => {}
490 });
491 }
492
493 fn invalidate_key_complete(&self, result: Result<(), ErrorCode>, key: &'static mut T) {
494 self.hashed_key.replace(key);
495
496 self.operation.map(|op| match op {
497 Operation::Get | Operation::Add => {}
498 Operation::Set => {
499 match result {
502 Ok(()) => {
503 self.hashed_key.take().map(|hashed_key| {
504 self.value.take().map(|value| {
505 match self.kv.append_key(hashed_key, value) {
506 Ok(()) => {}
507 Err((key, value, e)) => {
508 self.hashed_key.replace(key);
509 self.operation.clear();
510 self.unhashed_key.take().map(|unhashed_key| {
511 self.client.map(move |cb| {
512 cb.set_complete(Err(e), unhashed_key, value);
513 });
514 });
515 }
516 }
517 });
518 });
519 }
520 _ => {
521 self.operation.clear();
523 self.unhashed_key.take().map(|unhashed_key| {
524 self.value.take().map(|value| {
525 self.client.map(move |cb| {
526 cb.set_complete(Err(ErrorCode::FAIL), unhashed_key, value);
527 });
528 });
529 });
530 }
531 }
532 }
533 Operation::Update => {
534 match result {
537 Ok(()) => {
538 self.hashed_key.take().map(|hashed_key| {
539 self.value.take().map(|value| {
540 match self.kv.append_key(hashed_key, value) {
541 Ok(()) => {}
542 Err((key, value, _e)) => {
543 self.hashed_key.replace(key);
544 self.operation.clear();
545 self.unhashed_key.take().map(|unhashed_key| {
546 self.client.map(move |cb| {
547 cb.update_complete(
548 Err(ErrorCode::FAIL),
549 unhashed_key,
550 value,
551 );
552 });
553 });
554 }
555 }
556 });
557 });
558 }
559 _ => {
560 self.operation.clear();
562 self.unhashed_key.take().map(|unhashed_key| {
563 self.value.take().map(|value| {
564 self.client.map(move |cb| {
565 cb.update_complete(
566 Err(ErrorCode::NOSUPPORT),
567 unhashed_key,
568 value,
569 );
570 });
571 });
572 });
573 }
574 }
575 }
576 Operation::Delete => {
577 self.operation.clear();
578 self.unhashed_key.take().map(|unhashed_key| {
579 self.client.map(move |cb| {
580 cb.delete_complete(result, unhashed_key);
581 });
582 });
583 }
584 Operation::GarbageCollect => {}
585 });
586 }
587
588 fn garbage_collect_complete(&self, result: Result<(), ErrorCode>) {
589 self.operation.clear();
590 self.client.map(move |cb| {
591 cb.garbage_collection_complete(result);
592 });
593 }
594}