Skip to content

Commit ec9c7f8

Browse files
authored
perf(db): use ArrayVec for StoredNibbles key encoding (paradigmxyz#21279)
1 parent dbdaf06 commit ec9c7f8

File tree

7 files changed

+44
-15
lines changed

7 files changed

+44
-15
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/storage/db-api/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ serde = { workspace = true, default-features = false }
4040
metrics.workspace = true
4141

4242
# misc
43+
arrayvec.workspace = true
4344
derive_more.workspace = true
4445
bytes.workspace = true
4546

crates/storage/db-api/src/models/mod.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,10 @@ impl Decode for String {
126126
}
127127

128128
impl Encode for StoredNibbles {
129-
type Encoded = Vec<u8>;
129+
type Encoded = arrayvec::ArrayVec<u8, 64>;
130130

131-
// Delegate to the Compact implementation
132131
fn encode(self) -> Self::Encoded {
133-
// NOTE: This used to be `to_compact`, but all it does is append the bytes to the buffer,
134-
// so we can just use the implementation of `Into<Vec<u8>>` to reuse the buffer.
135-
self.0.to_vec()
132+
self.0.iter().collect()
136133
}
137134
}
138135

crates/storage/db-api/src/table.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,40 @@ pub trait Decompress: Send + Sync + Sized + Debug {
4646
}
4747
}
4848

49+
/// Trait for converting encoded types to `Vec<u8>`.
50+
///
51+
/// This is implemented for all `AsRef<[u8]>` types. For `Vec<u8>` this is a no-op,
52+
/// for other types like `ArrayVec` or fixed arrays it performs a copy.
53+
pub trait IntoVec: AsRef<[u8]> {
54+
/// Convert to a `Vec<u8>`.
55+
fn into_vec(self) -> Vec<u8>;
56+
}
57+
58+
impl IntoVec for Vec<u8> {
59+
#[inline]
60+
fn into_vec(self) -> Vec<u8> {
61+
self
62+
}
63+
}
64+
65+
impl<const N: usize> IntoVec for [u8; N] {
66+
#[inline]
67+
fn into_vec(self) -> Vec<u8> {
68+
self.to_vec()
69+
}
70+
}
71+
72+
impl<const N: usize> IntoVec for arrayvec::ArrayVec<u8, N> {
73+
#[inline]
74+
fn into_vec(self) -> Vec<u8> {
75+
self.to_vec()
76+
}
77+
}
78+
4979
/// Trait that will transform the data to be saved in the DB.
5080
pub trait Encode: Send + Sync + Sized + Debug {
5181
/// Encoded type.
52-
type Encoded: AsRef<[u8]> + Into<Vec<u8>> + Send + Sync + Ord + Debug;
82+
type Encoded: AsRef<[u8]> + IntoVec + Send + Sync + Ord + Debug;
5383

5484
/// Encodes data going into the database.
5585
fn encode(self) -> Self::Encoded;

crates/storage/db-api/src/tables/raw.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
table::{Compress, Decode, Decompress, DupSort, Encode, Key, Table, Value},
2+
table::{Compress, Decode, Decompress, DupSort, Encode, IntoVec, Key, Table, Value},
33
DatabaseError,
44
};
55
use serde::{Deserialize, Serialize};
@@ -52,7 +52,7 @@ pub struct RawKey<K: Key> {
5252
impl<K: Key> RawKey<K> {
5353
/// Create new raw key.
5454
pub fn new(key: K) -> Self {
55-
Self { key: K::encode(key).into(), _phantom: std::marker::PhantomData }
55+
Self { key: K::encode(key).into_vec(), _phantom: std::marker::PhantomData }
5656
}
5757

5858
/// Creates a raw key from an existing `Vec`. Useful when we already have the encoded

crates/storage/db/src/implementation/mdbx/cursor.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use reth_db_api::{
1111
DbCursorRO, DbCursorRW, DbDupCursorRO, DbDupCursorRW, DupWalker, RangeWalker,
1212
ReverseWalker, Walker,
1313
},
14-
table::{Compress, Decode, Decompress, DupSort, Encode, Table},
14+
table::{Compress, Decode, Decompress, DupSort, Encode, IntoVec, Table},
1515
};
1616
use reth_libmdbx::{Error as MDBXError, TransactionKind, WriteFlags, RO, RW};
1717
use reth_storage_errors::db::{DatabaseErrorInfo, DatabaseWriteError, DatabaseWriteOperation};
@@ -268,7 +268,7 @@ impl<T: Table> DbCursorRW<T> for Cursor<RW, T> {
268268
info: e.into(),
269269
operation: DatabaseWriteOperation::CursorUpsert,
270270
table_name: T::NAME,
271-
key: key.into(),
271+
key: key.into_vec(),
272272
}
273273
.into()
274274
})
@@ -290,7 +290,7 @@ impl<T: Table> DbCursorRW<T> for Cursor<RW, T> {
290290
info: e.into(),
291291
operation: DatabaseWriteOperation::CursorInsert,
292292
table_name: T::NAME,
293-
key: key.into(),
293+
key: key.into_vec(),
294294
}
295295
.into()
296296
})
@@ -314,7 +314,7 @@ impl<T: Table> DbCursorRW<T> for Cursor<RW, T> {
314314
info: e.into(),
315315
operation: DatabaseWriteOperation::CursorAppend,
316316
table_name: T::NAME,
317-
key: key.into(),
317+
key: key.into_vec(),
318318
}
319319
.into()
320320
})
@@ -350,7 +350,7 @@ impl<T: DupSort> DbDupCursorRW<T> for Cursor<RW, T> {
350350
info: e.into(),
351351
operation: DatabaseWriteOperation::CursorAppendDup,
352352
table_name: T::NAME,
353-
key: key.into(),
353+
key: key.into_vec(),
354354
}
355355
.into()
356356
})

crates/storage/db/src/implementation/mdbx/tx.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
DatabaseError,
77
};
88
use reth_db_api::{
9-
table::{Compress, DupSort, Encode, Table, TableImporter},
9+
table::{Compress, DupSort, Encode, IntoVec, Table, TableImporter},
1010
transaction::{DbTx, DbTxMut},
1111
};
1212
use reth_libmdbx::{ffi::MDBX_dbi, CommitLatency, Transaction, TransactionKind, WriteFlags, RW};
@@ -387,7 +387,7 @@ impl Tx<RW> {
387387
info: e.into(),
388388
operation: write_operation,
389389
table_name: T::NAME,
390-
key: key.into(),
390+
key: key.into_vec(),
391391
}
392392
.into()
393393
})

0 commit comments

Comments
 (0)