cfx_storage/storage_db/
key_value_db.rs

1// Copyright 2019 Conflux Foundation. All rights reserved.
2// Conflux is free software and distributed under GNU General Public License.
3// See http://www.gnu.org/licenses/
4
5/// One of the elementary value type supported by db.
6pub trait DbValueType {
7    type Type: ?Sized;
8}
9
10pub trait KeyValueDbTypes {
11    type ValueType: DbValueType;
12}
13
14pub trait KeyValueDbTraitRead: KeyValueDbTypes {
15    fn get(&self, key: &[u8]) -> Result<Option<Self::ValueType>>;
16
17    fn get_with_number_key(&self, key: i64) -> Result<Option<Self::ValueType>> {
18        self.get(key.to_string().as_bytes())
19    }
20}
21
22/// The difference between this trait and KeyValueDbTraitRead is that, the type
23/// which implements KeyValueDbTraitRead may use lock to serialize the reads,
24/// which is not necessarily a multi reader.
25pub trait KeyValueDbTraitMultiReader: KeyValueDbTraitRead {}
26
27/// These special get methods are provided for db like sqlite, where concurrency
28/// can only be achieved by opening a separate connection, otherwise
29/// lock is required for concurrent read.
30pub trait KeyValueDbTraitOwnedRead: KeyValueDbTypes {
31    fn get_mut(&mut self, key: &[u8]) -> Result<Option<Self::ValueType>>;
32
33    fn get_mut_with_number_key(
34        &mut self, key: i64,
35    ) -> Result<Option<Self::ValueType>> {
36        trace!(
37            "KeyValue:get: key={:?} {:?}",
38            key,
39            key.to_string().as_bytes()
40        );
41        self.get_mut(key.to_string().as_bytes())
42    }
43}
44
45enable_impl_transmute_for_element_satisfy! {
46    generic Item;
47    trait 'static + FallibleIterator<Item = Item, Error = Error>;
48}
49
50pub struct KvdbIterIterator<Item, KeyType: ?Sized, T: ?Sized> {
51    __i_m: std::marker::PhantomData<Item>,
52    __k_m: std::marker::PhantomData<KeyType>,
53    __t_m: std::marker::PhantomData<T>,
54}
55
56pub trait KeyValueDbIterableTrait<Item, KeyType: ?Sized, Tag: ?Sized>
57where KvdbIterIterator<Item, KeyType, Tag>:
58        WrappedTrait<dyn FallibleIterator<Item = Item, Error = Error>>
59{
60    fn iter_range(
61        &mut self, lower_bound_incl: &KeyType,
62        upper_bound_excl: Option<&KeyType>,
63    ) -> Result<
64        Wrap<
65            '_,
66            KvdbIterIterator<Item, KeyType, Tag>,
67            dyn FallibleIterator<Item = Item, Error = Error>,
68        >,
69    >;
70    fn iter_range_excl(
71        &mut self, lower_bound_excl: &KeyType, upper_bound_excl: &KeyType,
72    ) -> Result<
73        Wrap<
74            '_,
75            KvdbIterIterator<Item, KeyType, Tag>,
76            dyn FallibleIterator<Item = Item, Error = Error>,
77        >,
78    >;
79}
80
81pub trait KeyValueDbTraitSingleWriter: KeyValueDbTraitOwnedRead {
82    /// Return Some(maybe_old_value) or None if the db don't support reading the
83    /// old value at deletion.
84    fn delete(&mut self, key: &[u8])
85        -> Result<Option<Option<Self::ValueType>>>;
86    fn delete_with_number_key(
87        &mut self, key: i64,
88    ) -> Result<Option<Option<Self::ValueType>>> {
89        self.delete(key.to_string().as_bytes())
90    }
91    fn put(
92        &mut self, key: &[u8], value: &<Self::ValueType as DbValueType>::Type,
93    ) -> Result<Option<Option<Self::ValueType>>>;
94    fn put_with_number_key(
95        &mut self, key: i64, value: &<Self::ValueType as DbValueType>::Type,
96    ) -> Result<Option<Option<Self::ValueType>>> {
97        trace!(
98            "KeyValue:put: key={:?} {:?}",
99            key,
100            key.to_string().as_bytes()
101        );
102        self.put(key.to_string().as_bytes(), value)
103    }
104}
105
106pub trait KeyValueDbTraitSingleWriterMultiReader:
107    KeyValueDbTraitMultiReader + KeyValueDbTraitSingleWriter
108{
109}
110
111pub trait KeyValueDbTrait:
112    KeyValueDbTraitMultiReader + Send + Sync + MallocSizeOf
113{
114    /// Return Some(maybe_old_value) or None if the db don't support reading the
115    /// old value at deletion.
116    fn delete(&self, key: &[u8]) -> Result<Option<Option<Self::ValueType>>>;
117    fn delete_with_number_key(
118        &self, key: i64,
119    ) -> Result<Option<Option<Self::ValueType>>> {
120        self.delete(key.to_string().as_bytes())
121    }
122    fn put(
123        &self, key: &[u8], value: &<Self::ValueType as DbValueType>::Type,
124    ) -> Result<Option<Option<Self::ValueType>>>;
125    fn put_with_number_key(
126        &self, key: i64, value: &<Self::ValueType as DbValueType>::Type,
127    ) -> Result<Option<Option<Self::ValueType>>> {
128        self.put(key.to_string().as_bytes(), value)
129    }
130}
131
132// FIXME: Is it possible to detach SingleWriter from it, so that the
133// implementation doesn't look so ugly on KvdbSqliteTransaction?
134#[allow(drop_bounds)]
135pub trait KeyValueDbTransactionTrait:
136    KeyValueDbTraitSingleWriter + Drop
137{
138    /// Commit may be retried upon failure.
139    fn commit(&mut self, db: &dyn Any) -> Result<()>;
140    fn revert(&mut self) -> Result<()>;
141    /// When error occured within a transaction before commit, user may have to
142    /// revert the transaction and restart a new transaction.
143    ///
144    /// When restart fails, user may retry with no_revert set to true.
145    fn restart(&mut self, immediate_write: bool, no_revert: bool)
146        -> Result<()>;
147}
148
149/// This trait is to help with the committing of the transaction for which
150/// the db object should be provided for serialization.
151pub trait KeyValueDbAsAnyTrait: KeyValueDbTypes {
152    fn as_any(&self) -> &dyn Any;
153}
154
155impl<T: KeyValueDbTypes + Any> KeyValueDbAsAnyTrait for T {
156    fn as_any(&self) -> &dyn Any { self }
157}
158
159pub trait KeyValueDbTraitTransactional: KeyValueDbAsAnyTrait {
160    type TransactionType: KeyValueDbTransactionTrait<
161        ValueType = Self::ValueType,
162    >;
163
164    /// Immediate_write indicates whether the transaction should acquire a
165    /// write-lock immediately if any.
166    fn start_transaction(
167        &self, immediate_write: bool,
168    ) -> Result<Self::TransactionType>;
169}
170
171pub trait KeyValueDbTraitTransactionalDyn: KeyValueDbAsAnyTrait {
172    fn start_transaction_dyn(
173        &self, immediate_write: bool,
174    ) -> Result<Box<dyn KeyValueDbTransactionTrait<ValueType = Self::ValueType>>>;
175}
176
177impl<T: KeyValueDbTraitTransactional> KeyValueDbTraitTransactionalDyn for T
178where T::TransactionType: 'static
179{
180    fn start_transaction_dyn(
181        &self, immediate_write: bool,
182    ) -> Result<Box<dyn KeyValueDbTransactionTrait<ValueType = Self::ValueType>>>
183    {
184        Ok(Box::new(self.start_transaction(immediate_write)?))
185    }
186}
187
188pub trait KeyValueDbToOwnedReadTrait: KeyValueDbTypes {
189    fn to_owned_read(
190        &self,
191    ) -> Result<
192        Box<dyn '_ + KeyValueDbTraitOwnedRead<ValueType = Self::ValueType>>,
193    >;
194}
195
196impl<T: 'static + KeyValueDbTraitMultiReader> KeyValueDbToOwnedReadTrait for T
197where for<'a> &'a T: KeyValueDbTraitOwnedRead<ValueType = Self::ValueType>
198{
199    fn to_owned_read(
200        &self,
201    ) -> Result<
202        Box<dyn '_ + KeyValueDbTraitOwnedRead<ValueType = Self::ValueType>>,
203    > {
204        Ok(Box::new(self))
205    }
206}
207
208macro_rules! mark_kvdb_multi_reader {
209    ($type:ty) => {
210        impl KeyValueDbTraitMultiReader for $type {}
211        // Family dispatching
212        impl OwnedReadImplFamily for &$type {
213            type FamilyRepresentative = dyn KeyValueDbTraitMultiReader<
214                ValueType = <$type as KeyValueDbTypes>::ValueType,
215            >;
216        }
217    };
218}
219
220impl DbValueType for () {
221    type Type = ();
222}
223
224impl DbValueType for Box<[u8]> {
225    type Type = [u8];
226}
227
228impl DbValueType for i64 {
229    type Type = i64;
230}
231
232/// We implement the family dispatching for types which implements
233/// KeyValueDbTraitOwnedRead by different reasons:
234///
235/// a) Any type which implements KvdbSqliteAsReadOnlyAndIterableTrait can issue
236/// sql queries to load db; The feature is required by SnapshotDbSqlite where
237/// the sqlite connection is shared for MPT table and for KV table.
238///
239/// b) similar requirement may hold for any different database engine;
240///
241/// c) For a db engine which is by default KeyValueDbTraitMultiReader,
242/// KeyValueDbTraitOwnedRead is naturally read without explicit locking.
243impl<
244        T: OwnedReadImplFamily
245            + OwnedReadImplByFamily<
246                <T as OwnedReadImplFamily>::FamilyRepresentative,
247            >,
248    > KeyValueDbTraitOwnedRead for T
249{
250    fn get_mut(&mut self, key: &[u8]) -> Result<Option<Self::ValueType>> {
251        self.get_mut_impl(key)
252    }
253
254    fn get_mut_with_number_key(
255        &mut self, key: i64,
256    ) -> Result<Option<Self::ValueType>> {
257        trace!(
258            "KeyValue:get_impl: key={:?} {:?}",
259            key,
260            key.to_string().as_bytes()
261        );
262        self.get_mut_with_number_key_impl(key)
263    }
264}
265
266pub trait OwnedReadImplFamily {
267    type FamilyRepresentative: ?Sized;
268}
269
270pub trait OwnedReadImplByFamily<FamilyRepresentative: ?Sized>:
271    KeyValueDbTypes
272{
273    fn get_mut_impl(&mut self, key: &[u8]) -> Result<Option<Self::ValueType>>;
274    fn get_mut_with_number_key_impl(
275        &mut self, key: i64,
276    ) -> Result<Option<Self::ValueType>>;
277}
278
279impl<
280        T: SingleWriterImplFamily
281            + SingleWriterImplByFamily<
282                <T as SingleWriterImplFamily>::FamilyRepresentative,
283            > + KeyValueDbTraitOwnedRead,
284    > KeyValueDbTraitSingleWriter for T
285{
286    fn delete(
287        &mut self, key: &[u8],
288    ) -> Result<Option<Option<Self::ValueType>>> {
289        self.delete_impl(key)
290    }
291
292    fn delete_with_number_key(
293        &mut self, key: i64,
294    ) -> Result<Option<Option<Self::ValueType>>> {
295        self.delete_with_number_key_impl(key)
296    }
297
298    fn put(
299        &mut self, key: &[u8], value: &<Self::ValueType as DbValueType>::Type,
300    ) -> Result<Option<Option<Self::ValueType>>> {
301        self.put_impl(key, value)
302    }
303
304    fn put_with_number_key(
305        &mut self, key: i64, value: &<Self::ValueType as DbValueType>::Type,
306    ) -> Result<Option<Option<Self::ValueType>>> {
307        self.put_with_number_key_impl(key, value)
308    }
309}
310
311pub trait SingleWriterImplFamily {
312    type FamilyRepresentative: ?Sized;
313}
314
315pub trait SingleWriterImplByFamily<FamilyRepresentative: ?Sized>:
316    KeyValueDbTypes
317{
318    fn delete_impl(
319        &mut self, key: &[u8],
320    ) -> Result<Option<Option<Self::ValueType>>>;
321
322    fn delete_with_number_key_impl(
323        &mut self, key: i64,
324    ) -> Result<Option<Option<Self::ValueType>>>;
325
326    fn put_impl(
327        &mut self, key: &[u8], value: &<Self::ValueType as DbValueType>::Type,
328    ) -> Result<Option<Option<Self::ValueType>>>;
329
330    fn put_with_number_key_impl(
331        &mut self, key: i64, value: &<Self::ValueType as DbValueType>::Type,
332    ) -> Result<Option<Option<Self::ValueType>>>;
333}
334
335impl<
336        T: ReadImplFamily
337            + ReadImplByFamily<<T as ReadImplFamily>::FamilyRepresentative>,
338    > KeyValueDbTraitRead for T
339{
340    fn get(&self, key: &[u8]) -> Result<Option<Self::ValueType>> {
341        self.get_impl(key)
342    }
343
344    fn get_with_number_key(&self, key: i64) -> Result<Option<Self::ValueType>> {
345        self.get_with_number_key_impl(key)
346    }
347}
348
349pub trait ReadImplFamily {
350    type FamilyRepresentative: ?Sized;
351}
352
353pub trait ReadImplByFamily<FamilyRepresentative: ?Sized>:
354    KeyValueDbTypes
355{
356    fn get_impl(&self, key: &[u8]) -> Result<Option<Self::ValueType>>;
357
358    fn get_with_number_key_impl(
359        &self, key: i64,
360    ) -> Result<Option<Self::ValueType>>;
361}
362
363impl<
364        T: DbImplFamily
365            + DbImplByFamily<<T as DbImplFamily>::FamilyRepresentative>
366            + KeyValueDbTraitMultiReader
367            + Send
368            + Sync
369            + MallocSizeOf,
370    > KeyValueDbTrait for T
371{
372    fn delete(&self, key: &[u8]) -> Result<Option<Option<Self::ValueType>>> {
373        self.delete_impl(key)
374    }
375
376    fn delete_with_number_key(
377        &self, key: i64,
378    ) -> Result<Option<Option<Self::ValueType>>> {
379        self.delete_with_number_key_impl(key)
380    }
381
382    fn put(
383        &self, key: &[u8], value: &<Self::ValueType as DbValueType>::Type,
384    ) -> Result<Option<Option<Self::ValueType>>> {
385        self.put_impl(key, value)
386    }
387
388    fn put_with_number_key(
389        &self, key: i64, value: &<Self::ValueType as DbValueType>::Type,
390    ) -> Result<Option<Option<Self::ValueType>>> {
391        self.put_with_number_key_impl(key, value)
392    }
393}
394
395pub trait DbImplFamily {
396    type FamilyRepresentative: ?Sized;
397}
398
399pub trait DbImplByFamily<FamilyRepresentative: ?Sized>:
400    KeyValueDbTypes
401{
402    fn delete_impl(
403        &self, key: &[u8],
404    ) -> Result<Option<Option<Self::ValueType>>>;
405
406    fn delete_with_number_key_impl(
407        &self, key: i64,
408    ) -> Result<Option<Option<Self::ValueType>>>;
409
410    fn put_impl(
411        &self, key: &[u8], value: &<Self::ValueType as DbValueType>::Type,
412    ) -> Result<Option<Option<Self::ValueType>>>;
413
414    fn put_with_number_key_impl(
415        &self, key: i64, value: &<Self::ValueType as DbValueType>::Type,
416    ) -> Result<Option<Option<Self::ValueType>>>;
417}
418
419impl<ValueType: DbValueType> OwnedReadImplFamily
420    for dyn KeyValueDbTraitMultiReader<ValueType = ValueType>
421{
422    type FamilyRepresentative =
423        dyn KeyValueDbTraitMultiReader<ValueType = ValueType>;
424}
425
426/// Implement KeyValueDbTraitOwnedRead automatically for database engine which
427/// satisfies KeyValueDbTraitMultiReader.
428impl<
429        T: KeyValueDbTraitMultiReader<ValueType = ValueType>,
430        ValueType: DbValueType,
431    > KeyValueDbTypes for &T
432{
433    type ValueType = T::ValueType;
434}
435
436impl<
437        T: KeyValueDbTraitMultiReader<ValueType = ValueType>,
438        ValueType: DbValueType,
439    >
440    OwnedReadImplByFamily<dyn KeyValueDbTraitMultiReader<ValueType = ValueType>>
441    for &T
442{
443    fn get_mut_impl(&mut self, key: &[u8]) -> Result<Option<Self::ValueType>> {
444        self.get(key)
445    }
446
447    fn get_mut_with_number_key_impl(
448        &mut self, key: i64,
449    ) -> Result<Option<Self::ValueType>> {
450        self.get_with_number_key(key)
451    }
452}
453
454use crate::{
455    impls::errors::*,
456    utils::{
457        tuple::ElementSatisfy,
458        wrap::{Wrap, WrappedTrait},
459    },
460};
461use fallible_iterator::FallibleIterator;
462use malloc_size_of::MallocSizeOf;
463use std::any::Any;