tickv/
async_ops.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! TicKV can be used asynchronously. This module provides documentation and
6//! tests for using it with an async `FlashController` interface.
7//!
8//! To do this first there are special error values to return from the
9//! `FlashController` functions. These are the `ReadNotReady`, `WriteNotReady`
10//! and `EraseNotReady` types.
11//!
12//! ```rust
13//! // EXAMPLE ONLY: The `DefaultHasher` is subject to change
14//! // and hence is not a good fit.
15//! use std::collections::hash_map::DefaultHasher;
16//! use core::hash::{Hash, Hasher};
17//! use std::cell::{Cell, RefCell};
18//! use tickv::{AsyncTicKV, MAIN_KEY};
19//! use tickv::error_codes::ErrorCode;
20//! use tickv::flash_controller::FlashController;
21//!
22//! fn get_hashed_key(unhashed_key: &[u8]) -> u64 {
23//!     let mut hash_function = DefaultHasher::new();
24//!     unhashed_key.hash(&mut hash_function);
25//!     hash_function.finish()
26//! }
27//!
28//! struct FlashCtrl {
29//!     buf: RefCell<[[u8; 1024]; 64]>,
30//!     async_read_region: Cell<usize>,
31//!     async_erase_region: Cell<usize>,
32//! }
33//!
34//! impl FlashCtrl {
35//!     fn new() -> Self {
36//!         Self {
37//!             buf: RefCell::new([[0xFF; 1024]; 64]),
38//!             async_read_region: Cell::new(10),
39//!             async_erase_region: Cell::new(10),
40//!         }
41//!     }
42//! }
43//!
44//! impl FlashController<1024> for FlashCtrl {
45//!     fn read_region(
46//!         &self,
47//!         region_number: usize,
48//!         buf: &mut [u8; 1024],
49//!     ) -> Result<(), ErrorCode> {
50//!          // We aren't ready yet, launch the async operation
51//!          self.async_read_region.set(region_number);
52//!          return Err(ErrorCode::ReadNotReady(region_number));
53//!
54//!         Ok(())
55//!     }
56//!
57//!     fn write(&self, address: usize, buf: &[u8]) -> Result<(), ErrorCode> {
58//!         // Save the write operation to a queue, we don't need to re-call
59//!         for (i, d) in buf.iter().enumerate() {
60//!             self.buf.borrow_mut()[address / 1024][(address % 1024) + i] = *d;
61//!         }
62//!         Ok(())
63//!     }
64//!
65//!     fn erase_region(&self, region_number: usize) -> Result<(), ErrorCode> {
66//!         if self.async_erase_region.get() != region_number {
67//!             // We aren't ready yet, launch the async operation
68//!             self.async_erase_region.set(region_number);
69//!             return Err(ErrorCode::EraseNotReady(region_number));
70//!         }
71//!
72//!         Ok(())
73//!     }
74//! }
75//!
76//! // Create the TicKV instance and loop until everything is done
77//! // NOTE in an real implementation you will want to wait on
78//! // callbacks/interrupts and make this async.
79//!
80//! let mut read_buf: [u8; 1024] = [0; 1024];
81//! let mut hash_function = DefaultHasher::new();
82//! MAIN_KEY.hash(&mut hash_function);
83//! let tickv = AsyncTicKV::<FlashCtrl, 1024>::new(FlashCtrl::new(),
84//!                   &mut read_buf, 0x1000);
85//!
86//! let mut ret = tickv.initialise(hash_function.finish());
87//! while ret.is_err() {
88//!     // There is no actual delay here, in a real implementation wait on some event
89//!     ret = tickv.continue_operation().0;
90//!
91//!     match ret {
92//!         Err(ErrorCode::ReadNotReady(reg)) => {
93//!             tickv.set_read_buffer(&tickv.tickv.controller.buf.borrow()[reg]);
94//!         }
95//!         Ok(_) => break,
96//!         Err(ErrorCode::WriteNotReady(reg)) => break,
97//!         Err(ErrorCode::EraseNotReady(reg)) => {}
98//!         _ => unreachable!(),
99//!     }
100//! }
101//!
102//! // Then when calling the TicKV function check for the error. For example
103//! // when appending a key:
104//!
105//! // Add a key
106//! static mut VALUE: [u8; 32] = [0x23; 32];
107//! let ret = unsafe { tickv.append_key(get_hashed_key(b"ONE"), &mut VALUE, 32) };
108//!
109//! match ret {
110//!     Err((_buf, ErrorCode::ReadNotReady(reg))) => {
111//!         // There is no actual delay in the test, just continue now
112//!         tickv.set_read_buffer(&tickv.tickv.controller.buf.borrow()[reg]);
113//!         tickv
114//!             .continue_operation().0
115//!             .unwrap();
116//!     }
117//!     Ok(_) => {}
118//!     _ => unreachable!(),
119//! }
120//!
121//! ```
122//!
123//! This will call into the `FlashController` again where the
124//! `FlashController` implementation must return the data that is requested.
125//! If the data isn't ready (multiple reads might occur) then the `NotReady`
126//! error types can still be used.
127//!
128
129use crate::error_codes::ErrorCode;
130use crate::flash_controller::FlashController;
131use crate::success_codes::SuccessCode;
132use crate::tickv::{State, TicKV};
133use core::cell::Cell;
134
135/// The return type from the continue operation
136type ContinueReturn = (
137    // Result
138    Result<SuccessCode, ErrorCode>,
139    // Buf Buffer
140    Option<&'static mut [u8]>,
141    // Length of valid data inside of the buffer.
142    usize,
143);
144
145/// The struct storing all of the TicKV information for the async implementation.
146pub struct AsyncTicKV<'a, C: FlashController<S>, const S: usize> {
147    /// The main TicKV struct
148    pub tickv: TicKV<'a, C, S>,
149    key: Cell<Option<u64>>,
150    value: Cell<Option<&'static mut [u8]>>,
151    value_length: Cell<usize>,
152}
153
154impl<'a, C: FlashController<S>, const S: usize> AsyncTicKV<'a, C, S> {
155    /// Create a new struct
156    ///
157    /// `C`: An implementation of the `FlashController` trait
158    ///
159    /// `controller`: An new struct implementing `FlashController`
160    /// `flash_size`: The total size of the flash used for TicKV
161    pub fn new(controller: C, read_buffer: &'a mut [u8; S], flash_size: usize) -> Self {
162        Self {
163            tickv: TicKV::<C, S>::new(controller, read_buffer, flash_size),
164            key: Cell::new(None),
165            value: Cell::new(None),
166            value_length: Cell::new(0),
167        }
168    }
169
170    /// This function setups the flash region to be used as a key-value store.
171    /// If the region is already initialised this won't make any changes.
172    ///
173    /// `hashed_main_key`: The u64 hash of the const string `MAIN_KEY`.
174    ///
175    /// If the specified region has not already been setup for TicKV
176    /// the entire region will be erased.
177    ///
178    /// On success a `SuccessCode` will be returned.
179    /// On error a `ErrorCode` will be returned.
180    pub fn initialise(&self, hashed_main_key: u64) -> Result<SuccessCode, ErrorCode> {
181        self.key.replace(Some(hashed_main_key));
182        self.tickv.initialise(hashed_main_key)
183    }
184
185    /// Appends the key/value pair to flash storage.
186    ///
187    /// `hash`: A hashed key. This key will be used in future to retrieve
188    ///         or remove the `value`.
189    /// `value`: A buffer containing the data to be stored to flash.
190    ///
191    /// On success nothing will be returned.
192    /// On error a `ErrorCode` will be returned.
193    pub fn append_key(
194        &self,
195        hash: u64,
196        value: &'static mut [u8],
197        length: usize,
198    ) -> Result<SuccessCode, (&'static mut [u8], ErrorCode)> {
199        match self.tickv.append_key(hash, &value[0..length]) {
200            Ok(_code) => {
201                // Ok is a problem, since that means no asynchronous operations
202                // were called, which means our client will never get a
203                // callback. We need to error.
204                Err((value, ErrorCode::WriteFail))
205            }
206            Err(e) => match e {
207                ErrorCode::ReadNotReady(_)
208                | ErrorCode::EraseNotReady(_)
209                | ErrorCode::WriteNotReady(_) => {
210                    // This is what we expect, since it means we are going
211                    // an asynchronous operation which this interface expects.
212                    self.key.replace(Some(hash));
213                    self.value.replace(Some(value));
214                    self.value_length.set(length);
215                    Ok(SuccessCode::Queued)
216                }
217                _ => {
218                    // On any other error we report the error.
219                    Err((value, e))
220                }
221            },
222        }
223    }
224
225    /// Retrieves the value from flash storage.
226    ///
227    /// `hash`: A hashed key.
228    /// `buf`: A buffer to store the value to.
229    ///
230    /// On success a `SuccessCode` will be returned.
231    /// On error a `ErrorCode` will be returned.
232    ///
233    /// If a power loss occurs before success is returned the data is
234    /// assumed to be lost.
235    pub fn get_key(
236        &self,
237        hash: u64,
238        buf: &'static mut [u8],
239    ) -> Result<SuccessCode, (&'static mut [u8], ErrorCode)> {
240        match self.tickv.get_key(hash, buf) {
241            Ok(_code) => {
242                // Ok is a problem, since that means no asynchronous operations
243                // were called, which means our client will never get a
244                // callback. We need to error.
245                Err((buf, ErrorCode::ReadFail))
246            }
247            Err(e) => match e {
248                ErrorCode::ReadNotReady(_)
249                | ErrorCode::EraseNotReady(_)
250                | ErrorCode::WriteNotReady(_) => {
251                    self.key.replace(Some(hash));
252                    self.value.replace(Some(buf));
253                    Ok(SuccessCode::Queued)
254                }
255                _ => Err((buf, e)),
256            },
257        }
258    }
259
260    /// Invalidates the key in flash storage
261    ///
262    /// `hash`: A hashed key.
263    /// `key`: A unhashed key. This will be hashed internally.
264    ///
265    /// On success a `SuccessCode` will be returned.
266    /// On error a `ErrorCode` will be returned.
267    ///
268    /// If a power loss occurs before success is returned the data is
269    /// assumed to be lost.
270    pub fn invalidate_key(&self, hash: u64) -> Result<SuccessCode, ErrorCode> {
271        match self.tickv.invalidate_key(hash) {
272            Ok(_code) => Err(ErrorCode::WriteFail),
273            Err(_e) => {
274                self.key.replace(Some(hash));
275                Ok(SuccessCode::Queued)
276            }
277        }
278    }
279
280    /// Zeroizes the key in flash storage
281    ///
282    /// `hash`: A hashed key.
283    /// `key`: A unhashed key. This will be hashed internally.
284    ///
285    /// On success a `SuccessCode` will be returned.
286    /// On error a `ErrorCode` will be returned.
287    ///
288    /// If a power loss occurs before success is returned the data is
289    /// assumed to be lost.
290    pub fn zeroise_key(&self, hash: u64) -> Result<SuccessCode, ErrorCode> {
291        match self.tickv.zeroise_key(hash) {
292            Ok(_code) => Err(ErrorCode::WriteFail),
293            Err(_e) => {
294                self.key.replace(Some(hash));
295                Ok(SuccessCode::Queued)
296            }
297        }
298    }
299
300    /// Perform a garbage collection on TicKV
301    ///
302    /// On success a `SuccessCode` will be returned.
303    /// On error a `ErrorCode` will be returned.
304    pub fn garbage_collect(&self) -> Result<SuccessCode, ErrorCode> {
305        match self.tickv.garbage_collect() {
306            Ok(_code) => Err(ErrorCode::EraseFail),
307            Err(_e) => Ok(SuccessCode::Queued),
308        }
309    }
310
311    /// Copy data from `read_buffer` argument to the internal read_buffer.
312    /// This should be used to copy the data that the implementation wanted
313    /// to read when calling `read_region` after the async operation has
314    /// completed.
315    pub fn set_read_buffer(&self, read_buffer: &[u8]) {
316        let buf = self.tickv.read_buffer.take().unwrap();
317        buf.copy_from_slice(read_buffer);
318        self.tickv.read_buffer.replace(Some(buf));
319    }
320
321    /// Continue the last operation after the async operation has completed.
322    /// This should be called from a read/erase complete callback.
323    /// NOTE: If called from a read callback, `set_read_buffer` should be
324    /// called first to update the data.
325    ///
326    /// `hash_function`: Hash function with no previous state. This is
327    ///                  usually a newly created hash.
328    ///
329    /// Returns a tuple of 3 values
330    ///    Result:
331    ///        On success a `SuccessCode` will be returned.
332    ///        On error a `ErrorCode` will be returned.
333    ///    Buf Buffer:
334    ///        An option of the buf buffer used
335    ///    Length usize:
336    ///        The number of valid bytes in the buffer. 0 if Buf is None.
337    /// The buffers will only be returned on a non async error or on success.
338    pub fn continue_operation(&self) -> ContinueReturn {
339        let (ret, length) = match self.tickv.state.get() {
340            State::Init(_) => (self.tickv.initialise(self.key.get().unwrap()), 0),
341            State::AppendKey(_) => {
342                let value = self.value.take().unwrap();
343                let value_length = self.value_length.get();
344                let ret = self
345                    .tickv
346                    .append_key(self.key.get().unwrap(), &value[0..value_length]);
347                self.value.replace(Some(value));
348                (ret, value_length)
349            }
350            State::GetKey(_) => {
351                let buf = self.value.take().unwrap();
352                let ret = self.tickv.get_key(self.key.get().unwrap(), buf);
353                self.value.replace(Some(buf));
354                match ret {
355                    Ok((s, len)) => (Ok(s), len),
356                    Err(e) => (Err(e), 0),
357                }
358            }
359            State::InvalidateKey(_) => (self.tickv.invalidate_key(self.key.get().unwrap()), 0),
360            State::ZeroiseKey(_) => (self.tickv.zeroise_key(self.key.get().unwrap()), 0),
361            State::GarbageCollect(_) => match self.tickv.garbage_collect() {
362                Ok(bytes_freed) => (Ok(SuccessCode::Complete), bytes_freed),
363                Err(e) => (Err(e), 0),
364            },
365            _ => unreachable!(),
366        };
367
368        match ret {
369            Ok(_) => {
370                self.tickv.state.set(State::None);
371                (ret, self.value.take(), length)
372            }
373            Err(e) => match e {
374                ErrorCode::ReadNotReady(_) | ErrorCode::EraseNotReady(_) => (ret, None, 0),
375                ErrorCode::WriteNotReady(_) => {
376                    self.tickv.state.set(State::None);
377                    (ret, None, 0)
378                }
379                _ => {
380                    self.tickv.state.set(State::None);
381                    (ret, self.value.take(), length)
382                }
383            },
384        }
385    }
386}
387
388#[cfg(test)]
389mod tests {
390    #![allow(unsafe_code)]
391
392    /// Tests using a flash controller that can store data
393    mod store_flast_ctrl {
394        use crate::async_ops::AsyncTicKV;
395        use crate::error_codes::ErrorCode;
396        use crate::flash_controller::FlashController;
397        use crate::success_codes::SuccessCode;
398        use crate::tickv::{HASH_OFFSET, LEN_OFFSET, MAIN_KEY, VERSION, VERSION_OFFSET};
399        use core::hash::{Hash, Hasher};
400        use core::ptr::addr_of_mut;
401        use std::cell::Cell;
402        use std::cell::RefCell;
403        use std::collections::hash_map::DefaultHasher;
404
405        fn check_region_main(buf: &[u8]) {
406            // Check the version
407            assert_eq!(buf[VERSION_OFFSET], VERSION);
408
409            // Check the length
410            assert_eq!(buf[LEN_OFFSET], 0x80);
411            assert_eq!(buf[LEN_OFFSET + 1], 15);
412
413            // Check the hash
414            assert_eq!(buf[HASH_OFFSET + 0], 0x7b);
415            assert_eq!(buf[HASH_OFFSET + 1], 0xc9);
416            assert_eq!(buf[HASH_OFFSET + 2], 0xf7);
417            assert_eq!(buf[HASH_OFFSET + 3], 0xff);
418            assert_eq!(buf[HASH_OFFSET + 4], 0x4f);
419            assert_eq!(buf[HASH_OFFSET + 5], 0x76);
420            assert_eq!(buf[HASH_OFFSET + 6], 0xf2);
421            assert_eq!(buf[HASH_OFFSET + 7], 0x44);
422
423            // Check the check hash
424            assert_eq!(buf[HASH_OFFSET + 8], 0xbb);
425            assert_eq!(buf[HASH_OFFSET + 9], 0x32);
426            assert_eq!(buf[HASH_OFFSET + 10], 0x74);
427            assert_eq!(buf[HASH_OFFSET + 11], 0x1d);
428        }
429
430        fn check_region_one(buf: &[u8]) {
431            // Check the version
432            assert_eq!(buf[VERSION_OFFSET], VERSION);
433
434            // Check the length
435            assert_eq!(buf[LEN_OFFSET], 0x80);
436            assert_eq!(buf[LEN_OFFSET + 1], 47);
437
438            // Check the hash
439            assert_eq!(buf[HASH_OFFSET + 0], 0x81);
440            assert_eq!(buf[HASH_OFFSET + 1], 0x13);
441            assert_eq!(buf[HASH_OFFSET + 2], 0x7e);
442            assert_eq!(buf[HASH_OFFSET + 3], 0x95);
443            assert_eq!(buf[HASH_OFFSET + 4], 0x9e);
444            assert_eq!(buf[HASH_OFFSET + 5], 0x93);
445            assert_eq!(buf[HASH_OFFSET + 6], 0xaa);
446            assert_eq!(buf[HASH_OFFSET + 7], 0x3d);
447
448            // Check the value
449            assert_eq!(buf[HASH_OFFSET + 8], 0x23);
450            assert_eq!(buf[28], 0x23);
451            assert_eq!(buf[42], 0x23);
452
453            // Check the check hash
454            assert_eq!(buf[43], 0xfd);
455            assert_eq!(buf[44], 0x24);
456            assert_eq!(buf[45], 0xf0);
457            assert_eq!(buf[46], 0x07);
458        }
459
460        fn check_region_two(buf: &[u8]) {
461            // Check the version
462            assert_eq!(buf[VERSION_OFFSET], VERSION);
463
464            // Check the length
465            assert_eq!(buf[LEN_OFFSET], 0x80);
466            assert_eq!(buf[LEN_OFFSET + 1], 47);
467
468            // Check the hash
469            assert_eq!(buf[HASH_OFFSET + 0], 0x9d);
470            assert_eq!(buf[HASH_OFFSET + 1], 0xd3);
471            assert_eq!(buf[HASH_OFFSET + 2], 0x71);
472            assert_eq!(buf[HASH_OFFSET + 3], 0x45);
473            assert_eq!(buf[HASH_OFFSET + 4], 0x05);
474            assert_eq!(buf[HASH_OFFSET + 5], 0xc2);
475            assert_eq!(buf[HASH_OFFSET + 6], 0xf8);
476            assert_eq!(buf[HASH_OFFSET + 7], 0x66);
477
478            // Check the value
479            assert_eq!(buf[HASH_OFFSET + 8], 0x23);
480            assert_eq!(buf[28], 0x23);
481            assert_eq!(buf[42], 0x23);
482
483            // Check the check hash
484            assert_eq!(buf[43], 0x1b);
485            assert_eq!(buf[44], 0x53);
486            assert_eq!(buf[45], 0xf9);
487            assert_eq!(buf[46], 0x54);
488        }
489
490        fn get_hashed_key(unhashed_key: &[u8]) -> u64 {
491            let mut hash_function = DefaultHasher::new();
492            unhashed_key.hash(&mut hash_function);
493            hash_function.finish()
494        }
495
496        #[derive(Clone, Copy)]
497        enum FlashCtrlAction {
498            Idle,
499            Read,
500            Write,
501            Erase,
502        }
503
504        // An example FlashCtrl implementation
505        struct FlashCtrl<const S: usize> {
506            buf: RefCell<[[u8; S]; 64]>,
507            run: Cell<u8>,
508            async_read_region: Cell<usize>,
509            async_erase_region: Cell<usize>,
510            waiting_on: Cell<FlashCtrlAction>,
511            check_write_contents: bool,
512        }
513
514        impl<const S: usize> FlashCtrl<S> {
515            fn new(check_write_contents: bool) -> Self {
516                Self {
517                    buf: RefCell::new([[0xFF; S]; 64]),
518                    run: Cell::new(0),
519                    async_read_region: Cell::new(100),
520                    async_erase_region: Cell::new(100),
521                    waiting_on: Cell::new(FlashCtrlAction::Idle),
522                    check_write_contents,
523                }
524            }
525
526            fn get_waiting_action(&self) -> FlashCtrlAction {
527                self.waiting_on.get()
528            }
529        }
530
531        impl<const S: usize> FlashController<S> for FlashCtrl<S> {
532            fn read_region(
533                &self,
534                region_number: usize,
535                _buf: &mut [u8; S],
536            ) -> Result<(), ErrorCode> {
537                println!("Read from region: {}", region_number);
538
539                // Pretend that we aren't ready
540                self.async_read_region.set(region_number);
541                println!("  Not ready");
542
543                self.waiting_on.set(FlashCtrlAction::Read);
544
545                Err(ErrorCode::ReadNotReady(region_number))
546            }
547
548            fn write(&self, address: usize, buf: &[u8]) -> Result<(), ErrorCode> {
549                println!(
550                    "Write to address: {:#x}, region: {}",
551                    address % S,
552                    address / S
553                );
554
555                for (i, d) in buf.iter().enumerate() {
556                    self.buf.borrow_mut()[address / S][(address % S) + i] = *d;
557                }
558
559                // Check to see if we are adding a key
560                if buf.len() > 1 && self.check_write_contents {
561                    if self.run.get() == 0 {
562                        println!("Writing main key: {:#x?}", buf);
563                        check_region_main(buf);
564                    } else if self.run.get() == 1 {
565                        println!("Writing key ONE: {:#x?}", buf);
566                        check_region_one(buf);
567                    } else if self.run.get() == 2 {
568                        println!("Writing key TWO: {:#x?}", buf);
569                        check_region_two(buf);
570                    }
571                }
572
573                self.run.set(self.run.get() + 1);
574                self.waiting_on.set(FlashCtrlAction::Write);
575                Err(ErrorCode::WriteNotReady(address))
576            }
577
578            fn erase_region(&self, region_number: usize) -> Result<(), ErrorCode> {
579                println!("Erase region: {}", region_number);
580
581                let mut local_buf = self.buf.borrow_mut()[region_number];
582
583                for d in local_buf.iter_mut() {
584                    *d = 0xFF;
585                }
586
587                // Pretend that we aren't ready
588                self.async_erase_region.set(region_number);
589
590                self.waiting_on.set(FlashCtrlAction::Erase);
591                Err(ErrorCode::EraseNotReady(region_number))
592            }
593        }
594
595        /// This function implements what would happen in the callback function
596        /// triggered by the underlying flash hardware. In effect, it is the
597        /// callback handler, but since we don't actually have an async flash
598        /// implementation, this is just called by each test after starting the
599        /// flash operation.
600        fn flash_ctrl_callback<const S: usize>(tickv: &AsyncTicKV<FlashCtrl<S>, S>) {
601            match tickv.tickv.controller.get_waiting_action() {
602                FlashCtrlAction::Read => {
603                    // This mimics a read is complete, and we provide the buffer
604                    // with the newly read data to the tickv layer.
605                    tickv.set_read_buffer(
606                        &tickv.tickv.controller.buf.borrow()
607                            [tickv.tickv.controller.async_read_region.get()],
608                    );
609                }
610                _ => {
611                    // For write an erase all of the operation already occurred
612                    // in the original operation, and nothing needs to be done
613                    // in the simulated callback.
614                }
615            }
616        }
617
618        #[test]
619        fn test_simple_append() {
620            let mut read_buf: [u8; 1024] = [0; 1024];
621            let mut hash_function = DefaultHasher::new();
622            MAIN_KEY.hash(&mut hash_function);
623
624            let tickv = AsyncTicKV::<FlashCtrl<1024>, 1024>::new(
625                FlashCtrl::new(true),
626                &mut read_buf,
627                0x1000,
628            );
629
630            let mut ret = tickv.initialise(hash_function.finish());
631            while ret.is_err() {
632                flash_ctrl_callback(&tickv);
633
634                // There is no actual delay in the test, just continue now
635                let (r, _buf, _len) = tickv.continue_operation();
636                ret = r;
637            }
638
639            static mut VALUE: [u8; 32] = [0x23; 32];
640
641            println!("HASHED KEY {:?}", get_hashed_key(b"ONE"));
642
643            let ret =
644                unsafe { tickv.append_key(get_hashed_key(b"ONE"), &mut *addr_of_mut!(VALUE), 32) };
645            match ret {
646                Ok(SuccessCode::Queued) => {
647                    // There is no actual delay in the test, just continue now
648                    flash_ctrl_callback(&tickv);
649                    tickv.continue_operation().0.unwrap();
650                }
651                Err(_) => {}
652                _ => unreachable!(),
653            }
654
655            let ret =
656                unsafe { tickv.append_key(get_hashed_key(b"TWO"), &mut *addr_of_mut!(VALUE), 32) };
657            match ret {
658                Ok(SuccessCode::Queued) => {
659                    // There is no actual delay in the test, just continue now
660                    flash_ctrl_callback(&tickv);
661                    tickv.continue_operation().0.unwrap();
662                }
663                Err(_) => {}
664                _ => unreachable!(),
665            }
666        }
667
668        #[test]
669        fn test_double_append() {
670            let mut read_buf: [u8; 1024] = [0; 1024];
671            let mut hash_function = DefaultHasher::new();
672            MAIN_KEY.hash(&mut hash_function);
673
674            let tickv = AsyncTicKV::<FlashCtrl<1024>, 1024>::new(
675                FlashCtrl::new(true),
676                &mut read_buf,
677                0x10000,
678            );
679
680            let mut ret = tickv.initialise(hash_function.finish());
681            while ret.is_err() {
682                flash_ctrl_callback(&tickv);
683
684                // There is no actual delay in the test, just continue now
685                let (r, _buf, _len) = tickv.continue_operation();
686                ret = r;
687            }
688
689            static mut VALUE: [u8; 32] = [0x23; 32];
690            static mut BUF: [u8; 32] = [0; 32];
691
692            println!("Add key ONE");
693            let ret =
694                unsafe { tickv.append_key(get_hashed_key(b"ONE"), &mut *addr_of_mut!(VALUE), 32) };
695            match ret {
696                Ok(SuccessCode::Queued) => {
697                    // There is no actual delay in the test, just continue now
698                    flash_ctrl_callback(&tickv);
699                    tickv.continue_operation().0.unwrap();
700                }
701                Err(_) => {}
702                _ => unreachable!(),
703            }
704
705            println!("Get key ONE");
706
707            let ret = unsafe { tickv.get_key(get_hashed_key(b"ONE"), &mut *addr_of_mut!(BUF)) };
708            match ret {
709                Ok(SuccessCode::Queued) => {
710                    flash_ctrl_callback(&tickv);
711                    tickv.continue_operation().0.unwrap();
712                }
713                Err(_) => {}
714                _ => unreachable!(),
715            }
716
717            println!("Get non-existent key TWO");
718            let ret = unsafe { tickv.get_key(get_hashed_key(b"TWO"), &mut *addr_of_mut!(BUF)) };
719            match ret {
720                Ok(SuccessCode::Queued) => {
721                    // There is no actual delay in the test, just continue now
722                    flash_ctrl_callback(&tickv);
723                    assert_eq!(tickv.continue_operation().0, Err(ErrorCode::KeyNotFound));
724                }
725                Err((_, ErrorCode::KeyNotFound)) => {}
726                _ => unreachable!(),
727            }
728
729            println!("Add key ONE again");
730            let ret =
731                unsafe { tickv.append_key(get_hashed_key(b"ONE"), &mut *addr_of_mut!(VALUE), 32) };
732            match ret {
733                Ok(SuccessCode::Queued) => {
734                    // There is no actual delay in the test, just continue now
735                    flash_ctrl_callback(&tickv);
736                    assert_eq!(
737                        tickv.continue_operation().0,
738                        Err(ErrorCode::KeyAlreadyExists)
739                    );
740                }
741                Err((_buf, ErrorCode::KeyAlreadyExists)) => {}
742                _ => unreachable!(),
743            }
744
745            println!("Add key TWO");
746            let ret =
747                unsafe { tickv.append_key(get_hashed_key(b"TWO"), &mut *addr_of_mut!(VALUE), 32) };
748            match ret {
749                Ok(SuccessCode::Queued) => {
750                    // There is no actual delay in the test, just continue now
751                    flash_ctrl_callback(&tickv);
752                    tickv.continue_operation().0.unwrap();
753                }
754                Err(_) => {}
755                _ => unreachable!(),
756            }
757
758            println!("Get key ONE");
759            let ret = unsafe { tickv.get_key(get_hashed_key(b"ONE"), &mut *addr_of_mut!(BUF)) };
760            match ret {
761                Ok(SuccessCode::Queued) => {
762                    // There is no actual delay in the test, just continue now
763                    flash_ctrl_callback(&tickv);
764                    tickv.continue_operation().0.unwrap();
765                }
766                Err(_) => {}
767                _ => unreachable!(),
768            }
769
770            println!("Get key TWO");
771            let ret = unsafe { tickv.get_key(get_hashed_key(b"TWO"), &mut *addr_of_mut!(BUF)) };
772            match ret {
773                Ok(SuccessCode::Queued) => {
774                    // There is no actual delay in the test, just continue now
775                    flash_ctrl_callback(&tickv);
776                    tickv.continue_operation().0.unwrap();
777                }
778                Err(_) => {}
779                _ => unreachable!(),
780            }
781
782            println!("Get non-existent key THREE");
783            let ret = unsafe { tickv.get_key(get_hashed_key(b"THREE"), &mut *addr_of_mut!(BUF)) };
784            match ret {
785                Ok(SuccessCode::Queued) => {
786                    // There is no actual delay in the test, just continue now
787                    flash_ctrl_callback(&tickv);
788                    assert_eq!(tickv.continue_operation().0, Err(ErrorCode::KeyNotFound));
789                }
790                _ => unreachable!(),
791            }
792
793            let ret = unsafe { tickv.get_key(get_hashed_key(b"THREE"), &mut *addr_of_mut!(BUF)) };
794            match ret {
795                Ok(SuccessCode::Queued) => {
796                    flash_ctrl_callback(&tickv);
797                    assert_eq!(tickv.continue_operation().0, Err(ErrorCode::KeyNotFound));
798                }
799                Err(_) => {}
800                _ => unreachable!(),
801            }
802        }
803
804        #[test]
805        fn test_spread_pages() {
806            let mut read_buf: [u8; 64] = [0; 64];
807            let mut hash_function = DefaultHasher::new();
808            MAIN_KEY.hash(&mut hash_function);
809
810            let tickv =
811                AsyncTicKV::<FlashCtrl<64>, 64>::new(FlashCtrl::new(false), &mut read_buf, 64 * 64);
812
813            let mut ret = tickv.initialise(hash_function.finish());
814            while ret.is_err() {
815                tickv.set_read_buffer(
816                    &tickv.tickv.controller.buf.borrow()
817                        [tickv.tickv.controller.async_read_region.get()],
818                );
819
820                // There is no actual delay in the test, just continue now
821                let (r, _buf, _len) = tickv.continue_operation();
822                ret = r;
823            }
824
825            static mut VALUE: [u8; 32] = [0x23; 32];
826            static mut BUF: [u8; 32] = [0; 32];
827
828            println!("Add key 0x1000");
829            let ret = unsafe { tickv.append_key(0x1000, &mut *addr_of_mut!(VALUE), 32) };
830            match ret {
831                Ok(SuccessCode::Queued) => {
832                    // There is no actual delay in the test, just continue now
833                    flash_ctrl_callback(&tickv);
834                    tickv.continue_operation().0.unwrap();
835                }
836                Err(e) => panic!("Unable to add key 0x100: {e:?}"),
837                _ => unreachable!(),
838            }
839
840            println!("Add key 0x2000");
841            let ret = unsafe { tickv.append_key(0x2000, &mut *addr_of_mut!(VALUE), 32) };
842            match ret {
843                Ok(SuccessCode::Queued) => {
844                    // There is no actual delay in the test, just continue now
845                    flash_ctrl_callback(&tickv);
846
847                    assert_eq!(
848                        tickv.continue_operation().0,
849                        Err(ErrorCode::ReadNotReady(1))
850                    );
851                    flash_ctrl_callback(&tickv);
852
853                    tickv.continue_operation().0.unwrap();
854                }
855                Err(e) => panic!("Unable to add key 0x200: {e:?}"),
856                _ => unreachable!(),
857            }
858
859            println!("Add key 0x3000");
860            let ret = unsafe { tickv.append_key(0x3000, &mut *addr_of_mut!(VALUE), 32) };
861            match ret {
862                Ok(SuccessCode::Queued) => {
863                    // There is no actual delay in the test, just continue now
864                    flash_ctrl_callback(&tickv);
865                }
866                Err(e) => panic!("Unable to add key 0x3000: {e:?}"),
867                _ => unreachable!(),
868            }
869
870            loop {
871                let ret = tickv.continue_operation().0;
872                match ret {
873                    Err(ErrorCode::ReadNotReady(_reg)) => {
874                        // There is no actual delay in the test, just continue now
875                        flash_ctrl_callback(&tickv);
876                    }
877                    Err(e) => panic!("Unable to add key 0x3000: {e:?}"),
878                    Ok(_) => break,
879                }
880            }
881
882            println!("Get key 0x1000");
883            let ret = unsafe { tickv.get_key(0x1000, &mut *addr_of_mut!(BUF)) };
884            match ret {
885                Ok(SuccessCode::Queued) => {
886                    // There is no actual delay in the test, just continue now
887                    flash_ctrl_callback(&tickv);
888                }
889                _ => unreachable!(),
890            }
891
892            loop {
893                let ret = tickv.continue_operation().0;
894                match ret {
895                    Err(ErrorCode::ReadNotReady(_reg)) => {
896                        // There is no actual delay in the test, just continue now
897                        flash_ctrl_callback(&tickv);
898                    }
899                    Err(e) => panic!("Unable to get key 0x1000: {e:?}"),
900                    Ok(_) => break,
901                }
902            }
903
904            println!("Get key 0x3000");
905            let ret = unsafe { tickv.get_key(0x3000, &mut *addr_of_mut!(BUF)) };
906            match ret {
907                Ok(_) => flash_ctrl_callback(&tickv),
908                Err(_) => unreachable!(),
909            }
910
911            loop {
912                let ret = tickv.continue_operation().0;
913                match ret {
914                    Err(ErrorCode::ReadNotReady(reg)) => {
915                        // There is no actual delay in the test, just continue now
916                        tickv.set_read_buffer(&tickv.tickv.controller.buf.borrow()[reg]);
917                    }
918                    Err(e) => panic!("Unable to get key 0x1000: {e:?}"),
919                    Ok(_) => break,
920                }
921            }
922        }
923
924        #[test]
925        fn test_append_and_delete() {
926            let mut read_buf: [u8; 1024] = [0; 1024];
927            let mut hash_function = DefaultHasher::new();
928            MAIN_KEY.hash(&mut hash_function);
929
930            let tickv = AsyncTicKV::<FlashCtrl<1024>, 1024>::new(
931                FlashCtrl::new(true),
932                &mut read_buf,
933                0x10000,
934            );
935
936            let mut ret = tickv.initialise(hash_function.finish());
937            while ret.is_err() {
938                flash_ctrl_callback(&tickv);
939
940                // There is no actual delay in the test, just continue now
941                let (r, _buf, _len) = tickv.continue_operation();
942                ret = r;
943            }
944
945            static mut VALUE: [u8; 32] = [0x23; 32];
946            static mut BUF: [u8; 32] = [0; 32];
947
948            println!("Add key ONE");
949            let ret =
950                unsafe { tickv.append_key(get_hashed_key(b"ONE"), &mut *addr_of_mut!(VALUE), 32) };
951            match ret {
952                Ok(SuccessCode::Queued) => {
953                    // There is no actual delay in the test, just continue now
954                    flash_ctrl_callback(&tickv);
955                    tickv.continue_operation().0.unwrap();
956                }
957                Err(_) => {}
958                _ => unreachable!(),
959            }
960
961            println!("Get key ONE");
962            let ret = unsafe { tickv.get_key(get_hashed_key(b"ONE"), &mut *addr_of_mut!(BUF)) };
963            match ret {
964                Ok(SuccessCode::Queued) => {
965                    // There is no actual delay in the test, just continue now
966                    flash_ctrl_callback(&tickv);
967                    tickv.continue_operation().0.unwrap();
968                }
969                Err(_) => {}
970                _ => unreachable!(),
971            }
972
973            println!("Delete Key ONE");
974            let ret = tickv.invalidate_key(get_hashed_key(b"ONE"));
975            match ret {
976                Ok(SuccessCode::Queued) => {
977                    flash_ctrl_callback(&tickv);
978                    tickv.continue_operation().0.unwrap();
979                }
980                Err(_) => {}
981                _ => unreachable!(),
982            }
983
984            println!("Get non-existent key ONE");
985            unsafe {
986                match tickv.get_key(get_hashed_key(b"ONE"), &mut *addr_of_mut!(BUF)) {
987                    Ok(SuccessCode::Queued) => {
988                        flash_ctrl_callback(&tickv);
989
990                        assert_eq!(
991                            tickv.continue_operation().0,
992                            Err(ErrorCode::ReadNotReady(62))
993                        );
994                        flash_ctrl_callback(&tickv);
995
996                        match tickv.continue_operation().0 {
997                            Err(ErrorCode::ReadNotReady(reg)) => {
998                                panic!("Searching too far for keys: {reg}");
999                            }
1000                            Err(ErrorCode::KeyNotFound) => {}
1001                            e => {
1002                                panic!("Expected ErrorCode::KeyNotFound, got {e:?}");
1003                            }
1004                        }
1005                    }
1006                    _ => unreachable!(),
1007                }
1008            }
1009
1010            println!("Try to delete Key ONE Again");
1011            match tickv.invalidate_key(get_hashed_key(b"ONE")) {
1012                Ok(SuccessCode::Queued) => {
1013                    let reg = tickv.tickv.controller.async_read_region.get();
1014
1015                    flash_ctrl_callback(&tickv);
1016                    assert_eq!(
1017                        tickv.continue_operation().0,
1018                        Err(ErrorCode::ReadNotReady(reg + 1))
1019                    );
1020
1021                    // In normal operation we will read region `reg`, determine
1022                    // that it isn't full and stop looking for the key
1023                    //
1024                    // The following test is a hack to continue testing.
1025                    // We don't fill the read buffer with new data. So
1026                    // the read buffer will continue to provide the data from
1027                    // `reg`, which means TicKV will continue searching for
1028                    // an empty region.
1029                    //
1030                    // In normal operation this isn't correct, but for the test
1031                    // case it's a good check to test region searching
1032                    assert_eq!(
1033                        tickv.continue_operation().0,
1034                        Err(ErrorCode::ReadNotReady(reg - 1))
1035                    );
1036
1037                    assert_eq!(
1038                        tickv.continue_operation().0,
1039                        Err(ErrorCode::ReadNotReady(reg + 2))
1040                    );
1041
1042                    assert_eq!(
1043                        tickv.continue_operation().0,
1044                        Err(ErrorCode::ReadNotReady(reg - 2))
1045                    );
1046
1047                    assert_eq!(
1048                        tickv.continue_operation().0,
1049                        Err(ErrorCode::ReadNotReady(reg - 3))
1050                    );
1051
1052                    // Now set the read buffer and end the search
1053                    tickv.set_read_buffer(&tickv.tickv.controller.buf.borrow()[reg - 1]);
1054
1055                    match tickv.continue_operation().0 {
1056                        Err(ErrorCode::ReadNotReady(reg)) => {
1057                            panic!("Searching too far for keys: {reg}");
1058                        }
1059                        Err(ErrorCode::KeyNotFound) => {}
1060                        e => {
1061                            panic!("Expected ErrorCode::KeyNotFound, got {e:?}");
1062                        }
1063                    }
1064                }
1065                e => {
1066                    panic!("Expected ErrorCode::KeyNotFound, got {e:?}");
1067                }
1068            }
1069        }
1070
1071        #[test]
1072        fn test_garbage_collect() {
1073            let mut read_buf: [u8; 1024] = [0; 1024];
1074            let mut hash_function = DefaultHasher::new();
1075            MAIN_KEY.hash(&mut hash_function);
1076
1077            let tickv = AsyncTicKV::<FlashCtrl<1024>, 1024>::new(
1078                FlashCtrl::new(true),
1079                &mut read_buf,
1080                0x10000,
1081            );
1082
1083            let mut ret = tickv.initialise(hash_function.finish());
1084            while ret.is_err() {
1085                flash_ctrl_callback(&tickv);
1086
1087                // There is no actual delay in the test, just continue now
1088                let (r, _buf, _len) = tickv.continue_operation();
1089                ret = r;
1090            }
1091
1092            static mut VALUE: [u8; 32] = [0x23; 32];
1093            static mut BUF: [u8; 32] = [0; 32];
1094
1095            println!("Garbage collect empty flash");
1096            let ret = tickv.garbage_collect();
1097            match ret {
1098                Ok(SuccessCode::Queued) => loop {
1099                    flash_ctrl_callback(&tickv);
1100                    let (res, _buf, len) = tickv.continue_operation();
1101                    if res.is_ok() {
1102                        assert_eq!(len, 0);
1103                        break;
1104                    }
1105                },
1106                Ok(_) => {}
1107                _ => unreachable!(),
1108            }
1109
1110            println!("Add key ONE");
1111            let ret =
1112                unsafe { tickv.append_key(get_hashed_key(b"ONE"), &mut *addr_of_mut!(VALUE), 32) };
1113            match ret {
1114                Ok(SuccessCode::Queued) => {
1115                    // There is no actual delay in the test, just continue now
1116                    flash_ctrl_callback(&tickv);
1117                    tickv.continue_operation().0.unwrap();
1118                }
1119                Ok(_) => {}
1120                _ => unreachable!(),
1121            }
1122
1123            println!("Garbage collect flash with valid key");
1124            let ret = tickv.garbage_collect();
1125            match ret {
1126                Ok(SuccessCode::Queued) => loop {
1127                    flash_ctrl_callback(&tickv);
1128                    let (res, _buf, len) = tickv.continue_operation();
1129                    if res.is_ok() {
1130                        assert_eq!(len, 0);
1131                        break;
1132                    }
1133                },
1134                Ok(_) => {}
1135                _ => unreachable!(),
1136            }
1137
1138            println!("Delete Key ONE");
1139            let ret = tickv.invalidate_key(get_hashed_key(b"ONE"));
1140            match ret {
1141                Ok(SuccessCode::Queued) => {
1142                    flash_ctrl_callback(&tickv);
1143                    tickv.continue_operation().0.unwrap();
1144                }
1145                Err(_) => {}
1146                _ => unreachable!(),
1147            }
1148
1149            println!("Garbage collect flash with deleted key");
1150            let ret = tickv.garbage_collect();
1151            match ret {
1152                Ok(SuccessCode::Queued) => loop {
1153                    flash_ctrl_callback(&tickv);
1154                    let (res, _buf, len) = tickv.continue_operation();
1155                    if res.is_ok() {
1156                        assert_eq!(len, 1024);
1157                        break;
1158                    }
1159                },
1160                Ok(_) => {}
1161                _ => unreachable!(),
1162            }
1163
1164            println!("Get non-existent key ONE");
1165            match unsafe { tickv.get_key(get_hashed_key(b"ONE"), &mut *addr_of_mut!(BUF)) } {
1166                Ok(SuccessCode::Queued) => {
1167                    flash_ctrl_callback(&tickv);
1168                    assert_eq!(
1169                        tickv.continue_operation().0,
1170                        Err(ErrorCode::ReadNotReady(62))
1171                    );
1172                    flash_ctrl_callback(&tickv);
1173                    assert_eq!(tickv.continue_operation().0, Err(ErrorCode::KeyNotFound));
1174                }
1175                _ => unreachable!(),
1176            }
1177
1178            println!("Add Key ONE");
1179            let ret =
1180                unsafe { tickv.append_key(get_hashed_key(b"ONE"), &mut *addr_of_mut!(VALUE), 32) };
1181            match ret {
1182                Ok(SuccessCode::Queued) => {
1183                    // There is no actual delay in the test, just continue now
1184                    flash_ctrl_callback(&tickv);
1185                    tickv.continue_operation().0.unwrap();
1186                }
1187                _ => unreachable!("ret: {:?}", ret),
1188            }
1189        }
1190    }
1191}