Skip to content

Commit 55e7412

Browse files
committed
Add missed BoundedDbCodec impls for Entity-listing codecs (for fast delete_all()).
1 parent 3b4353f commit 55e7412

File tree

2 files changed

+82
-19
lines changed

2 files changed

+82
-19
lines changed

core-rust/state-manager/src/store/codecs.rs

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
* permissions under this License.
6363
*/
6464

65+
use std::mem::size_of;
6566
use std::ops::Range;
6667

6768
use crate::engine_prelude::*;
@@ -316,6 +317,22 @@ impl DbCodec<NodeId> for NodeIdDbCodec {
316317
#[derive(Default)]
317318
pub struct TypeAndCreationIndexKeyDbCodec {}
318319

320+
impl TypeAndCreationIndexKeyDbCodec {
321+
/// An extracted "how are parts encoded together" knowledge, to be shared with the
322+
/// [`BoundedDbCodec`] implementation.
323+
fn encode_parts(
324+
entity_byte: u8,
325+
state_version_bytes: &[u8; StateVersion::BYTE_LEN],
326+
index_within_txn_bytes: &[u8; size_of::<u32>()],
327+
) -> Vec<u8> {
328+
let mut bytes = Vec::new();
329+
bytes.push(entity_byte);
330+
bytes.extend_from_slice(state_version_bytes);
331+
bytes.extend_from_slice(index_within_txn_bytes);
332+
bytes
333+
}
334+
}
335+
319336
impl DbCodec<(EntityType, CreationId)> for TypeAndCreationIndexKeyDbCodec {
320337
fn encode(&self, value: &(EntityType, CreationId)) -> Vec<u8> {
321338
let (
@@ -325,11 +342,11 @@ impl DbCodec<(EntityType, CreationId)> for TypeAndCreationIndexKeyDbCodec {
325342
index_within_txn,
326343
},
327344
) = value;
328-
let mut bytes = Vec::new();
329-
bytes.push(*entity_type as u8);
330-
bytes.extend_from_slice(&state_version.to_be_bytes());
331-
bytes.extend_from_slice(&index_within_txn.to_be_bytes());
332-
bytes
345+
Self::encode_parts(
346+
*entity_type as u8,
347+
&state_version.to_be_bytes(),
348+
&index_within_txn.to_be_bytes(),
349+
)
333350
}
334351

335352
fn decode(&self, bytes: &[u8]) -> (EntityType, CreationId) {
@@ -350,6 +367,16 @@ impl DbCodec<(EntityType, CreationId)> for TypeAndCreationIndexKeyDbCodec {
350367
}
351368
}
352369

370+
impl BoundedDbCodec for TypeAndCreationIndexKeyDbCodec {
371+
fn upper_bound_encoding(&self) -> Vec<u8> {
372+
Self::encode_parts(
373+
u8::MAX,
374+
&[u8::MAX; StateVersion::BYTE_LEN],
375+
&[u8::MAX; size_of::<u32>()],
376+
)
377+
}
378+
}
379+
353380
impl GroupPreservingDbCodec for TypeAndCreationIndexKeyDbCodec {
354381
type Group = EntityType;
355382

@@ -372,6 +399,24 @@ impl IntraGroupOrderPreservingDbCodec<(EntityType, CreationId)> for TypeAndCreat
372399
#[derive(Default)]
373400
pub struct BlueprintAndCreationIndexKeyDbCodec {}
374401

402+
impl BlueprintAndCreationIndexKeyDbCodec {
403+
/// An extracted "how are parts encoded together" knowledge, to be shared with the
404+
/// [`BoundedDbCodec`] implementation.
405+
fn encode_parts(
406+
package_address_bytes: &[u8; NodeId::LENGTH],
407+
blueprint_name_hash_bytes: &[u8; Hash::LENGTH],
408+
state_version_bytes: &[u8; StateVersion::BYTE_LEN],
409+
index_within_txn_bytes: &[u8; size_of::<u32>()],
410+
) -> Vec<u8> {
411+
let mut bytes = Vec::new();
412+
bytes.extend_from_slice(package_address_bytes);
413+
bytes.extend_from_slice(blueprint_name_hash_bytes);
414+
bytes.extend_from_slice(state_version_bytes);
415+
bytes.extend_from_slice(index_within_txn_bytes);
416+
bytes
417+
}
418+
}
419+
375420
impl DbCodec<(PackageAddress, Hash, CreationId)> for BlueprintAndCreationIndexKeyDbCodec {
376421
fn encode(&self, value: &(PackageAddress, Hash, CreationId)) -> Vec<u8> {
377422
let (
@@ -382,12 +427,12 @@ impl DbCodec<(PackageAddress, Hash, CreationId)> for BlueprintAndCreationIndexKe
382427
index_within_txn,
383428
},
384429
) = value;
385-
let mut bytes = Vec::new();
386-
bytes.extend_from_slice(&package_address.as_node_id().0);
387-
bytes.extend_from_slice(&blueprint_name_hash.0);
388-
bytes.extend_from_slice(&state_version.to_be_bytes());
389-
bytes.extend_from_slice(&index_within_txn.to_be_bytes());
390-
bytes
430+
Self::encode_parts(
431+
&package_address.as_node_id().0,
432+
&blueprint_name_hash.0,
433+
&state_version.to_be_bytes(),
434+
&index_within_txn.to_be_bytes(),
435+
)
391436
}
392437

393438
fn decode(&self, bytes: &[u8]) -> (PackageAddress, Hash, CreationId) {
@@ -413,6 +458,17 @@ impl DbCodec<(PackageAddress, Hash, CreationId)> for BlueprintAndCreationIndexKe
413458
}
414459
}
415460

461+
impl BoundedDbCodec for BlueprintAndCreationIndexKeyDbCodec {
462+
fn upper_bound_encoding(&self) -> Vec<u8> {
463+
Self::encode_parts(
464+
&[u8::MAX; NodeId::LENGTH],
465+
&[u8::MAX; Hash::LENGTH],
466+
&[u8::MAX; StateVersion::BYTE_LEN],
467+
&[u8::MAX; size_of::<u32>()],
468+
)
469+
}
470+
}
471+
416472
impl GroupPreservingDbCodec for BlueprintAndCreationIndexKeyDbCodec {
417473
type Group = (PackageAddress, Hash);
418474

core-rust/state-manager/src/store/rocks_db.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ use crate::store::traits::gc::{
9494
LedgerProofsGcProgress, LedgerProofsGcStore, StateTreeGcStore, VersionedLedgerProofsGcProgress,
9595
};
9696
use crate::store::traits::indices::{
97-
CreationId, EntityBlueprintId, ObjectBlueprintName, ObjectBlueprintNameV1, EntityListingIndex,
97+
CreationId, EntityBlueprintId, EntityListingIndex, ObjectBlueprintName, ObjectBlueprintNameV1,
9898
VersionedEntityBlueprintId, VersionedObjectBlueprintName,
9999
};
100100
use crate::store::traits::measurement::{CategoryDbVolumeStatistic, MeasurableDatabase};
@@ -2079,12 +2079,16 @@ impl<R: WriteableRocks> StateManagerDatabase<R> {
20792079
// that we care about (package address and blueprint name) are effectively
20802080
// immutable - we can thus safely ignore all updates to this substate.
20812081
continue;
2082-
},
2082+
}
20832083
SubstateChangeAction::Delete { .. } => {
2084-
panic!("type info substate should not be deleted: {:?}", type_info_change)
2085-
},
2084+
panic!(
2085+
"type info substate should not be deleted: {:?}",
2086+
type_info_change
2087+
)
2088+
}
20862089
};
2087-
let type_info = scrypto_decode::<TypeInfoSubstate>(created_type_info_value).expect("decode type info");
2090+
let type_info = scrypto_decode::<TypeInfoSubstate>(created_type_info_value)
2091+
.expect("decode type info");
20882092

20892093
let entity_type = node_id.entity_type().expect("type of upserted Entity");
20902094
let creation_id = CreationId::new(state_version, index_within_txn);
@@ -2132,8 +2136,11 @@ impl<R: WriteableRocks> StateManagerDatabase<R> {
21322136
info!("Entity listing indices are disabled.");
21332137
// We remove the indices' data and metadata in a single, cheap write batch:
21342138
db_context.cf(TypeAndCreationIndexedEntitiesCf).delete_all();
2135-
db_context.cf(BlueprintAndCreationIndexedObjectsCf).delete_all();
2136-
db_context.cf(ExtensionsDataCf)
2139+
db_context
2140+
.cf(BlueprintAndCreationIndexedObjectsCf)
2141+
.delete_all();
2142+
db_context
2143+
.cf(ExtensionsDataCf)
21372144
.delete(&ExtensionsDataKey::EntityListingIndicesLastProcessedStateVersion);
21382145
info!("Deleted entity listing indices.");
21392146
return;
@@ -2161,7 +2168,7 @@ impl<R: WriteableRocks> StateManagerDatabase<R> {
21612168
);
21622169
if state_version.number() % TXN_FLUSH_INTERVAL == 0 || receipts_iter.peek().is_none() {
21632170
if state_version.number() % PROGRESS_LOG_INTERVAL == 0 {
2164-
info!("Entity listing indices updated to {}",state_version);
2171+
info!("Entity listing indices updated to {}", state_version);
21652172
}
21662173
db_context.cf(ExtensionsDataCf).put(
21672174
&ExtensionsDataKey::EntityListingIndicesLastProcessedStateVersion,

0 commit comments

Comments
 (0)