1use crate::{
2 cursor::{DbCursorRO, DbCursorRW, DbDupCursorRO, DbDupCursorRW},
3 transaction::{DbTx, DbTxMut},
4 DatabaseError,
5};
6use serde::{Deserialize, Serialize};
7use std::fmt::Debug;
8
9pub use reth_codecs::{Compress, Decompress};
10
11pub trait IntoVec: AsRef<[u8]> {
16 fn into_vec(self) -> Vec<u8>;
18}
19
20impl IntoVec for Vec<u8> {
21 #[inline]
22 fn into_vec(self) -> Vec<u8> {
23 self
24 }
25}
26
27impl<const N: usize> IntoVec for [u8; N] {
28 #[inline]
29 fn into_vec(self) -> Vec<u8> {
30 self.to_vec()
31 }
32}
33
34impl<const N: usize> IntoVec for arrayvec::ArrayVec<u8, N> {
35 #[inline]
36 fn into_vec(self) -> Vec<u8> {
37 self.to_vec()
38 }
39}
40
41pub trait Encode: Send + Sync + Sized + Debug {
43 type Encoded: AsRef<[u8]> + IntoVec + Send + Sync + Ord + Debug;
45
46 fn encode(self) -> Self::Encoded;
48}
49
50pub trait Decode: Send + Sync + Sized + Debug {
52 fn decode(value: &[u8]) -> Result<Self, DatabaseError>;
54
55 fn decode_owned(value: Vec<u8>) -> Result<Self, DatabaseError> {
57 Self::decode(&value)
58 }
59}
60
61pub trait Key: Encode + Decode + Ord + Clone + Serialize + for<'a> Deserialize<'a> {}
63
64impl<T> Key for T where T: Encode + Decode + Ord + Clone + Serialize + for<'a> Deserialize<'a> {}
65
66pub trait Value: Compress + Decompress + Serialize {}
68
69impl<T> Value for T where T: Compress + Decompress + Serialize {}
70
71pub trait Table: Send + Sync + Debug + 'static {
80 const NAME: &'static str;
82
83 const DUPSORT: bool;
85
86 type Key: Key;
90
91 type Value: Value;
93}
94
95pub trait TableInfo: Send + Sync + Debug + 'static {
97 fn name(&self) -> &'static str;
99
100 fn is_dupsort(&self) -> bool;
102}
103
104pub type TableRow<T> = (<T as Table>::Key, <T as Table>::Value);
106
107pub trait DupSort: Table {
111 type SubKey: Key;
117}
118
119pub trait TableImporter: DbTxMut {
121 fn import_table<T: Table, R: DbTx>(&self, source_tx: &R) -> Result<(), DatabaseError> {
123 let mut destination_cursor = self.cursor_write::<T>()?;
124
125 for kv in source_tx.cursor_read::<T>()?.walk(None)? {
126 let (k, v) = kv?;
127 destination_cursor.append(k, &v)?;
128 }
129
130 Ok(())
131 }
132
133 fn import_table_with_range<T: Table, R: DbTx>(
138 &self,
139 source_tx: &R,
140 from: Option<<T as Table>::Key>,
141 to: <T as Table>::Key,
142 ) -> Result<(), DatabaseError>
143 where
144 T::Key: Default,
145 {
146 let mut destination_cursor = self.cursor_write::<T>()?;
147 let mut source_cursor = source_tx.cursor_read::<T>()?;
148
149 let source_range = match from {
150 Some(from) => source_cursor.walk_range(from..=to),
151 None => source_cursor.walk_range(..=to),
152 };
153 for row in source_range? {
154 let (key, value) = row?;
155 destination_cursor.append(key, &value)?;
156 }
157
158 Ok(())
159 }
160
161 fn import_dupsort<T: DupSort, R: DbTx>(&self, source_tx: &R) -> Result<(), DatabaseError> {
163 let mut destination_cursor = self.cursor_dup_write::<T>()?;
164 let mut cursor = source_tx.cursor_dup_read::<T>()?;
165
166 while let Some((k, _)) = cursor.next_no_dup()? {
167 for kv in cursor.walk_dup(Some(k), None)? {
168 let (k, v) = kv?;
169 destination_cursor.append_dup(k, v)?;
170 }
171 }
172
173 Ok(())
174 }
175}