use crate::interface::*;
use radix_common::prelude::*;
use radix_rust::copy_u8_array;
pub trait DatabaseKeyMapper: 'static {
fn to_db_partition_key(node_id: &NodeId, partition_num: PartitionNumber) -> DbPartitionKey {
DbPartitionKey {
node_key: Self::to_db_node_key(node_id),
partition_num: Self::to_db_partition_num(partition_num),
}
}
fn from_db_partition_key(partition_key: &DbPartitionKey) -> (NodeId, PartitionNumber) {
(
Self::from_db_node_key(&partition_key.node_key),
Self::from_db_partition_num(partition_key.partition_num),
)
}
fn to_db_node_key(node_id: &NodeId) -> DbNodeKey;
fn from_db_node_key(db_node_key: &DbNodeKey) -> NodeId;
fn to_db_partition_num(partition_num: PartitionNumber) -> DbPartitionNum;
fn from_db_partition_num(db_partition_num: DbPartitionNum) -> PartitionNumber;
fn to_db_sort_key(key: &SubstateKey) -> DbSortKey {
match key {
SubstateKey::Field(fields_key) => Self::field_to_db_sort_key(fields_key),
SubstateKey::Map(map_key) => Self::map_to_db_sort_key(map_key),
SubstateKey::Sorted(sorted_key) => Self::sorted_to_db_sort_key(sorted_key),
}
}
fn to_db_sort_key_from_ref(key: SubstateKeyRef) -> DbSortKey {
match key {
SubstateKeyRef::Field(fields_key) => Self::field_to_db_sort_key(fields_key),
SubstateKeyRef::Map(map_key) => Self::map_to_db_sort_key(map_key),
SubstateKeyRef::Sorted(sorted_key) => Self::sorted_to_db_sort_key(sorted_key),
}
}
fn from_db_sort_key<K: SubstateKeyContent>(db_sort_key: &DbSortKey) -> SubstateKey {
K::from_db_key::<Self>(db_sort_key).into_typed_key()
}
fn from_db_sort_key_to_inner<K: SubstateKeyContent>(db_sort_key: &DbSortKey) -> K {
K::from_db_key::<Self>(db_sort_key)
}
fn field_to_db_sort_key(field_key: &FieldKey) -> DbSortKey;
fn field_from_db_sort_key(db_sort_key: &DbSortKey) -> FieldKey;
fn map_to_db_sort_key(map_key: &MapKey) -> DbSortKey;
fn map_from_db_sort_key(db_sort_key: &DbSortKey) -> MapKey;
fn sorted_to_db_sort_key(sorted_key: &SortedKey) -> DbSortKey;
fn sorted_from_db_sort_key(db_sort_key: &DbSortKey) -> SortedKey;
}
pub struct SpreadPrefixKeyMapper;
impl DatabaseKeyMapper for SpreadPrefixKeyMapper {
fn to_db_node_key(node_id: &NodeId) -> DbNodeKey {
SpreadPrefixKeyMapper::to_hash_prefixed(node_id.as_bytes())
}
fn from_db_node_key(db_node_key: &DbNodeKey) -> NodeId {
NodeId(copy_u8_array(SpreadPrefixKeyMapper::from_hash_prefixed(
db_node_key,
)))
}
fn to_db_partition_num(partition_num: PartitionNumber) -> DbPartitionNum {
partition_num.0
}
fn from_db_partition_num(db_partition_num: DbPartitionNum) -> PartitionNumber {
PartitionNumber(db_partition_num)
}
fn field_to_db_sort_key(fields_key: &FieldKey) -> DbSortKey {
DbSortKey(vec![*fields_key])
}
fn field_from_db_sort_key(db_sort_key: &DbSortKey) -> FieldKey {
db_sort_key.0[0]
}
fn map_to_db_sort_key(map_key: &MapKey) -> DbSortKey {
DbSortKey(SpreadPrefixKeyMapper::to_hash_prefixed(map_key))
}
fn map_from_db_sort_key(db_sort_key: &DbSortKey) -> MapKey {
SpreadPrefixKeyMapper::from_hash_prefixed(&db_sort_key.0).to_vec()
}
fn sorted_to_db_sort_key(sorted_key: &SortedKey) -> DbSortKey {
DbSortKey(
[
sorted_key.0.as_slice(),
&SpreadPrefixKeyMapper::to_hash_prefixed(&sorted_key.1),
]
.concat(),
)
}
fn sorted_from_db_sort_key(db_sort_key: &DbSortKey) -> SortedKey {
(
copy_u8_array(&db_sort_key.0[..2]),
SpreadPrefixKeyMapper::from_hash_prefixed(&db_sort_key.0[2..]).to_vec(),
)
}
}
impl SpreadPrefixKeyMapper {
const HASHED_PREFIX_LENGTH: usize = 20;
fn to_hash_prefixed(plain_bytes: &[u8]) -> Vec<u8> {
let hashed_prefix = &hash(plain_bytes).0[..Self::HASHED_PREFIX_LENGTH];
[hashed_prefix, plain_bytes].concat()
}
fn from_hash_prefixed(prefixed_bytes: &[u8]) -> &[u8] {
&prefixed_bytes[Self::HASHED_PREFIX_LENGTH..]
}
}
pub trait SubstateKeyContent: Sized + 'static {
fn from_db_key<M: DatabaseKeyMapper + ?Sized>(db_sort_key: &DbSortKey) -> Self;
fn into_typed_key(self) -> SubstateKey;
}
impl SubstateKeyContent for MapKey {
fn from_db_key<M: DatabaseKeyMapper + ?Sized>(db_sort_key: &DbSortKey) -> Self {
M::map_from_db_sort_key(db_sort_key)
}
fn into_typed_key(self) -> SubstateKey {
SubstateKey::Map(self)
}
}
impl SubstateKeyContent for FieldKey {
fn from_db_key<M: DatabaseKeyMapper + ?Sized>(db_sort_key: &DbSortKey) -> Self {
M::field_from_db_sort_key(db_sort_key)
}
fn into_typed_key(self) -> SubstateKey {
SubstateKey::Field(self)
}
}
impl SubstateKeyContent for SortedKey {
fn from_db_key<M: DatabaseKeyMapper + ?Sized>(db_sort_key: &DbSortKey) -> Self {
M::sorted_from_db_sort_key(db_sort_key)
}
fn into_typed_key(self) -> SubstateKey {
SubstateKey::Sorted(self)
}
}