Skip to content

Commit

Permalink
hash-cache-tool: Prints capitalization and num accounts when diffing …
Browse files Browse the repository at this point in the history
…files (#2462)
  • Loading branch information
brooksprumo authored Aug 6, 2024
1 parent 427a18b commit 44f6e03
Showing 1 changed file with 46 additions and 12 deletions.
58 changes: 46 additions & 12 deletions accounts-db/accounts-hash-cache-tool/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use {
},
solana_program::pubkey::Pubkey,
std::{
cmp::Ordering,
cmp::{self, Ordering},
fs::{self, File, Metadata},
io::{self, BufReader, Read},
mem::size_of,
Expand Down Expand Up @@ -181,11 +181,32 @@ fn do_inspect(file: impl AsRef<Path>, force: bool) -> Result<(), String> {
}

fn do_diff_files(file1: impl AsRef<Path>, file2: impl AsRef<Path>) -> Result<(), String> {
let entries1 = extract_latest_entries_in(&file1)
let LatestEntriesInfo {
latest_entries: entries1,
capitalization: capitalization1,
} = extract_latest_entries_in(&file1)
.map_err(|err| format!("failed to extract entries from file 1: {err}"))?;
let entries2 = extract_latest_entries_in(&file2)
let LatestEntriesInfo {
latest_entries: entries2,
capitalization: capitalization2,
} = extract_latest_entries_in(&file2)
.map_err(|err| format!("failed to extract entries from file 2: {err}"))?;

let num_accounts1 = entries1.len();
let num_accounts2 = entries2.len();
let num_accounts_width = {
let width1 = (num_accounts1 as f64).log10().ceil() as usize;
let width2 = (num_accounts2 as f64).log10().ceil() as usize;
cmp::max(width1, width2)
};
let lamports_width = {
let width1 = (capitalization1 as f64).log10().ceil() as usize;
let width2 = (capitalization2 as f64).log10().ceil() as usize;
cmp::max(width1, width2)
};
println!("File 1: number of accounts: {num_accounts1:num_accounts_width$}, capitalization: {capitalization1:lamports_width$} lamports");
println!("File 2: number of accounts: {num_accounts2:num_accounts_width$}, capitalization: {capitalization2:lamports_width$} lamports");

// compute the differences between the files
let do_compute = |lhs: &HashMap<_, (_, _)>, rhs: &HashMap<_, (_, _)>| {
let mut unique_entries = Vec::new();
Expand Down Expand Up @@ -231,7 +252,7 @@ fn do_diff_files(file1: impl AsRef<Path>, file2: impl AsRef<Path>) -> Result<(),
for (i, entry) in entries.iter().enumerate() {
total_lamports += entry.lamports;
println!(
"{i:count_width$}: pubkey: {:44}, hash: {:44}, lamports: {}",
"{i:count_width$}: pubkey: {:44}, hash: {:44}, lamports: {:lamports_width$}",
entry.pubkey.to_string(),
entry.hash.0.to_string(),
entry.lamports,
Expand All @@ -252,13 +273,13 @@ fn do_diff_files(file1: impl AsRef<Path>, file2: impl AsRef<Path>) -> Result<(),
} else {
for (i, (lhs, rhs)) in mismatch_entries.iter().enumerate() {
println!(
"{i:count_width$}: pubkey: {:44}, hash: {:44}, lamports: {}",
"{i:count_width$}: pubkey: {:44}, hash: {:44}, lamports: {:lamports_width$}",
lhs.pubkey.to_string(),
lhs.hash.0.to_string(),
lhs.lamports,
);
println!(
"{i:count_width$}: file 2: {:44}, hash: {:44}, lamports: {}",
"{i:count_width$}: file 2: {:44}, hash: {:44}, lamports: {:lamports_width$}",
"(same)".to_string(),
rhs.hash.0.to_string(),
rhs.lamports,
Expand Down Expand Up @@ -465,12 +486,10 @@ fn get_cache_files_in(dir: impl AsRef<Path>) -> Result<Vec<CacheFileInfo>, io::E
Ok(cache_files)
}

/// Returns the entries in `file`
/// Returns the entries in `file`, and the capitalization
///
/// If there are multiple entries for a pubkey, only the latest is returned.
fn extract_latest_entries_in(
file: impl AsRef<Path>,
) -> Result<HashMap<Pubkey, (AccountHash, /* lamports */ u64)>, String> {
fn extract_latest_entries_in(file: impl AsRef<Path>) -> Result<LatestEntriesInfo, String> {
let force = false; // skipping sanity checks is not supported when extracting entries
let (reader, header) = open_file(&file, force).map_err(|err| {
format!(
Expand All @@ -481,12 +500,21 @@ fn extract_latest_entries_in(

// entries in the file are sorted by pubkey then slot,
// so we want to keep the *last* entry (if there are duplicates)
let mut capitalization = Saturating(0);
let mut entries = HashMap::default();
scan_file(reader, header.count, |entry| {
entries.insert(entry.pubkey, (entry.hash, entry.lamports));
capitalization += entry.lamports;
let old_value = entries.insert(entry.pubkey, (entry.hash, entry.lamports));
if let Some((_, old_lamports)) = old_value {
// back out the old value's lamports, so we only keep the latest's for capitalization
capitalization -= old_lamports;
}
})?;

Ok(entries)
Ok(LatestEntriesInfo {
latest_entries: entries,
capitalization: capitalization.0,
})
}

/// Scans file with `reader` and applies `user_fn` to each entry
Expand Down Expand Up @@ -578,6 +606,12 @@ struct CacheFileInfo {
parsed: ParsedCacheHashDataFilename,
}

#[derive(Debug)]
struct LatestEntriesInfo {
latest_entries: HashMap<Pubkey, (AccountHash, /* lamports */ u64)>,
capitalization: u64, // lamports
}

#[derive(Debug)]
struct ElapsedOnDrop {
message: String,
Expand Down

0 comments on commit 44f6e03

Please sign in to comment.