cfx_storage/impls/storage_db/
kvdb_rocksdb.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#[derive(MallocSizeOfDerive, Clone)]
6pub struct KvdbRocksdb {
7    pub kvdb: Arc<Database>,
8    pub col: u32,
9}
10
11pub struct KvdbRocksDbTransaction {
12    pending: DBTransaction,
13    col: u32,
14}
15
16impl KeyValueDbTraitRead for KvdbRocksdb {
17    fn get(&self, key: &[u8]) -> Result<Option<Box<[u8]>>> {
18        Ok(self
19            .kvdb
20            .get(self.col, key)?
21            .map(|db_value| db_value.into_boxed_slice()))
22    }
23}
24
25mark_kvdb_multi_reader!(KvdbRocksdb);
26
27impl KeyValueDbTypes for KvdbRocksdb {
28    type ValueType = Box<[u8]>;
29}
30
31impl KeyValueDbTrait for KvdbRocksdb {
32    fn delete(&self, key: &[u8]) -> Result<Option<Option<Box<[u8]>>>> {
33        random_crash_if_enabled("rocksdb delete");
34        let mut transaction = self.kvdb.transaction();
35        transaction.delete(self.col, key);
36        self.kvdb.write(transaction)?;
37        Ok(None)
38    }
39
40    fn put(
41        &self, key: &[u8], value: &[u8],
42    ) -> Result<Option<Option<Box<[u8]>>>> {
43        random_crash_if_enabled("rocksdb put");
44        let mut transaction = self.kvdb.transaction();
45        transaction.put(self.col, key, value);
46        self.kvdb.write(transaction)?;
47        Ok(None)
48    }
49}
50
51impl KeyValueDbTypes for KvdbRocksDbTransaction {
52    type ValueType = Box<[u8]>;
53}
54
55impl KeyValueDbTraitSingleWriter for KvdbRocksDbTransaction {
56    fn delete(&mut self, key: &[u8]) -> Result<Option<Option<Box<[u8]>>>> {
57        self.pending.delete(self.col, key);
58        Ok(None)
59    }
60
61    fn put(
62        &mut self, key: &[u8], value: &[u8],
63    ) -> Result<Option<Option<Box<[u8]>>>> {
64        self.pending.put(self.col, key, value);
65        Ok(None)
66    }
67}
68
69impl KeyValueDbTraitOwnedRead for KvdbRocksDbTransaction {
70    fn get_mut(&mut self, _key: &[u8]) -> Result<Option<Box<[u8]>>> {
71        // DBTransaction doesn't implement get method, so the user shouldn't
72        // rely on this method.
73        unreachable!()
74    }
75}
76
77impl KeyValueDbTransactionTrait for KvdbRocksDbTransaction {
78    fn commit(&mut self, db: &dyn Any) -> Result<()> {
79        random_crash_if_enabled("rocksdb commit");
80        match db.downcast_ref::<KvdbRocksdb>() {
81            Some(as_kvdb_rocksdb) => {
82                let wrapped_ops = DBTransaction {
83                    ops: self.pending.ops.clone(),
84                };
85                let result = as_kvdb_rocksdb.kvdb.write(wrapped_ops);
86                match result {
87                    Ok(_) => {
88                        self.pending.ops.clear();
89                        Ok(())
90                    }
91                    Err(e) => bail!(e),
92                }
93            }
94            None => {
95                unreachable!();
96            }
97        }
98    }
99
100    fn revert(&mut self) -> Result<()> {
101        self.pending.ops = vec![];
102        Ok(())
103    }
104
105    fn restart(
106        &mut self, _immediate_write: bool, no_revert: bool,
107    ) -> Result<()> {
108        if !no_revert {
109            self.revert()?;
110        }
111        Ok(())
112    }
113}
114
115impl Drop for KvdbRocksDbTransaction {
116    fn drop(&mut self) {
117        // No-op
118    }
119}
120
121impl KeyValueDbTraitTransactional for KvdbRocksdb {
122    type TransactionType = KvdbRocksDbTransaction;
123
124    fn start_transaction(
125        &self, _immediate_write: bool,
126    ) -> Result<Self::TransactionType> {
127        Ok(KvdbRocksDbTransaction {
128            pending: self.kvdb.transaction(),
129            col: self.col,
130        })
131    }
132}
133
134impl DeltaDbTrait for KvdbRocksdb {}
135
136use super::super::{
137    super::storage_db::{delta_db_manager::DeltaDbTrait, key_value_db::*},
138    errors::*,
139};
140use kvdb::DBTransaction;
141use kvdb_rocksdb::Database;
142use malloc_size_of_derive::MallocSizeOf as MallocSizeOfDerive;
143use random_crash::random_crash_if_enabled;
144use std::{any::Any, sync::Arc};