1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use crate::types::AccountId;
use borsh::{BorshDeserialize, BorshSerialize};
/// The result of splitting a memtrie into two possibly even parts, according to `memory_usage`
/// stored in the trie nodes.
///
/// **NOTE: This is an artificial value calculated according to `TRIE_COST`. Hence, it does not
/// represent actual memory allocation, but the split ratio should be roughly consistent with that.**
#[derive(
Debug,
Clone,
Eq,
PartialEq,
serde::Serialize,
serde::Deserialize,
BorshSerialize,
BorshDeserialize,
)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct TrieSplit {
/// Account ID representing the split path
pub boundary_account: AccountId,
/// Total `memory_usage` of the left part (excluding the split path)
pub left_memory: u64,
/// Total `memory_usage` of the right part (including the split path)
pub right_memory: u64,
}
impl TrieSplit {
pub fn new(boundary_account: AccountId, left_memory: u64, right_memory: u64) -> Self {
Self { boundary_account, left_memory, right_memory }
}
/// Dummy split that will be worse than any actual trie split
pub fn dummy() -> Self {
let account_id = "dummy".parse().unwrap();
Self::new(account_id, 0, u64::MAX)
}
pub fn is_dummy(&self) -> bool {
self.mem_diff() == u64::MAX
}
/// Get the split path as bytes
pub fn split_path_bytes(&self) -> &[u8] {
self.boundary_account.as_bytes()
}
/// Get absolute difference between right and left memory
pub fn mem_diff(&self) -> u64 {
self.right_memory.abs_diff(self.left_memory)
}
pub fn total_memory(&self) -> u64 {
self.left_memory.saturating_add(self.right_memory)
}
}