diff --git a/tools/state-viewer/src/commands.rs b/tools/state-viewer/src/commands.rs index 630c0069221..b9aa4a68be1 100644 --- a/tools/state-viewer/src/commands.rs +++ b/tools/state-viewer/src/commands.rs @@ -1107,11 +1107,13 @@ fn print_state_stats_for_shard_uid( let iter = get_state_stats_account_iter(&group_by); let mut current_size = ByteSize::default(); for state_stats_account in iter { - current_size += state_stats_account.size; - if 2 * current_size.as_u64() > state_stats.total_size.as_u64() { - state_stats.middle_state_record = Some(state_stats_account); + let new_size = current_size + state_stats_account.size; + if 2 * new_size.as_u64() > state_stats.total_size.as_u64() { + state_stats.middle_account = Some(state_stats_account); + state_stats.middle_account_leading_size = Some(current_size); break; } + current_size = new_size; } tracing::info!(target: "state_viewer", "{shard_uid:?}"); @@ -1209,7 +1211,12 @@ pub struct StateStats { pub total_size: ByteSize, pub total_count: usize, - pub middle_state_record: Option, + // The account that is in the middle of the state in respect to storage. + pub middle_account: Option, + // The total size of all accounts leading to the middle account. + // Can be used to determin how does the middle account split the state. + pub middle_account_leading_size: Option, + pub top_accounts: BinaryHeap, } @@ -1221,11 +1228,23 @@ impl core::fmt::Debug for StateStats { .checked_div(self.total_count as u64) .map(ByteSize::b) .unwrap_or_default(); + + let left_size = self.middle_account_leading_size.unwrap_or_default(); + let middle_size = self.middle_account.as_ref().map(|a| a.size).unwrap_or_default(); + let right_size = self.total_size.as_u64() - left_size.as_u64() - middle_size.as_u64(); + let right_size = ByteSize::b(right_size); + + let left_percent = 100 * left_size.as_u64() / self.total_size.as_u64(); + let middle_percent = 100 * middle_size.as_u64() / self.total_size.as_u64(); + let right_percent = 100 * right_size.as_u64() / self.total_size.as_u64(); + f.debug_struct("StateStats") .field("total_size", &self.total_size) .field("total_count", &self.total_count) .field("average_size", &average_size) - .field("middle_state_record", &self.middle_state_record.as_ref().unwrap()) + .field("middle_account", &self.middle_account.as_ref().unwrap()) + .field("split_size", &format!("{left_size:?} : {middle_size:?} : {right_size:?}")) + .field("split_percent", &format!("{left_percent}:{middle_percent}:{right_percent}")) .field("top_accounts", &self.top_accounts) .finish() } @@ -1286,7 +1305,7 @@ impl PartialOrd for StateStatsAccount { impl std::fmt::Debug for StateStatsAccount { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("StateStatsStateRecord") + f.debug_struct("StateStatsAccount") .field("account_id", &self.account_id.as_str()) .field("size", &self.size) .finish()