oasis_runtime_sdk/storage/
prefix.rs

1use oasis_core_runtime::storage::mkvs;
2
3use super::{Prefix, Store};
4
5/// A key-value store that prefixes all keys with the given prefix.
6pub struct PrefixStore<S: Store, P: AsRef<[u8]>> {
7    parent: S,
8    prefix: P,
9}
10
11impl<S: Store, P: AsRef<[u8]>> PrefixStore<S, P> {
12    /// Create a new prefix store with the given prefix.
13    pub fn new(parent: S, prefix: P) -> Self {
14        Self { parent, prefix }
15    }
16}
17
18impl<S: Store, P: AsRef<[u8]>> Store for PrefixStore<S, P> {
19    fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
20        self.parent.get(&[self.prefix.as_ref(), key].concat())
21    }
22
23    fn insert(&mut self, key: &[u8], value: &[u8]) {
24        self.parent
25            .insert(&[self.prefix.as_ref(), key].concat(), value);
26    }
27
28    fn remove(&mut self, key: &[u8]) {
29        self.parent.remove(&[self.prefix.as_ref(), key].concat());
30    }
31
32    fn iter(&self) -> Box<dyn mkvs::Iterator + '_> {
33        Box::new(PrefixStoreIterator::new(
34            self.parent.iter(),
35            self.prefix.as_ref(),
36        ))
37    }
38
39    fn prefetch_prefixes(&mut self, prefixes: Vec<Prefix>, limit: u16) {
40        self.parent.prefetch_prefixes(prefixes, limit);
41    }
42}
43
44/// An iterator over the `PrefixStore`.
45pub(crate) struct PrefixStoreIterator<'store> {
46    inner: Box<dyn mkvs::Iterator + 'store>,
47    prefix: &'store [u8],
48}
49
50impl<'store> PrefixStoreIterator<'store> {
51    fn new(mut inner: Box<dyn mkvs::Iterator + 'store>, prefix: &'store [u8]) -> Self {
52        inner.seek(prefix);
53        Self { inner, prefix }
54    }
55}
56
57impl Iterator for PrefixStoreIterator<'_> {
58    type Item = (Vec<u8>, Vec<u8>);
59
60    fn next(&mut self) -> Option<Self::Item> {
61        Iterator::next(&mut self.inner).and_then(|(mut k, v)| {
62            if k.starts_with(self.prefix) {
63                Some((k.split_off(self.prefix.len()), v))
64            } else {
65                None
66            }
67        })
68    }
69}
70
71impl mkvs::Iterator for PrefixStoreIterator<'_> {
72    fn set_prefetch(&mut self, prefetch: usize) {
73        self.inner.set_prefetch(prefetch)
74    }
75
76    fn is_valid(&self) -> bool {
77        if !self
78            .inner
79            .get_key()
80            .as_ref()
81            .unwrap_or(&vec![])
82            .starts_with(self.prefix)
83        {
84            return false;
85        }
86        self.inner.is_valid()
87    }
88
89    fn error(&self) -> &Option<anyhow::Error> {
90        self.inner.error()
91    }
92
93    fn rewind(&mut self) {
94        self.inner.seek(self.prefix);
95    }
96
97    fn seek(&mut self, key: &[u8]) {
98        self.inner.seek(&[self.prefix, key].concat());
99    }
100
101    fn get_key(&self) -> &Option<mkvs::Key> {
102        self.inner.get_key()
103    }
104
105    fn get_value(&self) -> &Option<Vec<u8>> {
106        self.inner.get_value()
107    }
108
109    fn next(&mut self) {
110        if !self.is_valid() {
111            // Could be invalid due to prefix mismatch.
112            return;
113        }
114        mkvs::Iterator::next(&mut *self.inner)
115    }
116}