12
12
} ,
13
13
solana_program:: pubkey:: Pubkey ,
14
14
std:: {
15
- cmp:: Ordering ,
15
+ cmp:: { self , Ordering } ,
16
16
fs:: { self , File , Metadata } ,
17
17
io:: { self , BufReader , Read } ,
18
18
mem:: size_of,
@@ -181,11 +181,32 @@ fn do_inspect(file: impl AsRef<Path>, force: bool) -> Result<(), String> {
181
181
}
182
182
183
183
fn do_diff_files ( file1 : impl AsRef < Path > , file2 : impl AsRef < Path > ) -> Result < ( ) , String > {
184
- let entries1 = extract_latest_entries_in ( & file1)
184
+ let LatestEntriesInfo {
185
+ latest_entries : entries1,
186
+ capitalization : capitalization1,
187
+ } = extract_latest_entries_in ( & file1)
185
188
. map_err ( |err| format ! ( "failed to extract entries from file 1: {err}" ) ) ?;
186
- let entries2 = extract_latest_entries_in ( & file2)
189
+ let LatestEntriesInfo {
190
+ latest_entries : entries2,
191
+ capitalization : capitalization2,
192
+ } = extract_latest_entries_in ( & file2)
187
193
. map_err ( |err| format ! ( "failed to extract entries from file 2: {err}" ) ) ?;
188
194
195
+ let num_accounts1 = entries1. len ( ) ;
196
+ let num_accounts2 = entries2. len ( ) ;
197
+ let num_accounts_width = {
198
+ let width1 = ( num_accounts1 as f64 ) . log10 ( ) . ceil ( ) as usize ;
199
+ let width2 = ( num_accounts2 as f64 ) . log10 ( ) . ceil ( ) as usize ;
200
+ cmp:: max ( width1, width2)
201
+ } ;
202
+ let lamports_width = {
203
+ let width1 = ( capitalization1 as f64 ) . log10 ( ) . ceil ( ) as usize ;
204
+ let width2 = ( capitalization2 as f64 ) . log10 ( ) . ceil ( ) as usize ;
205
+ cmp:: max ( width1, width2)
206
+ } ;
207
+ println ! ( "File 1: number of accounts: {num_accounts1:num_accounts_width$}, capitalization: {capitalization1:lamports_width$} lamports" ) ;
208
+ println ! ( "File 2: number of accounts: {num_accounts2:num_accounts_width$}, capitalization: {capitalization2:lamports_width$} lamports" ) ;
209
+
189
210
// compute the differences between the files
190
211
let do_compute = |lhs : & HashMap < _ , ( _ , _ ) > , rhs : & HashMap < _ , ( _ , _ ) > | {
191
212
let mut unique_entries = Vec :: new ( ) ;
@@ -231,7 +252,7 @@ fn do_diff_files(file1: impl AsRef<Path>, file2: impl AsRef<Path>) -> Result<(),
231
252
for ( i, entry) in entries. iter ( ) . enumerate ( ) {
232
253
total_lamports += entry. lamports ;
233
254
println ! (
234
- "{i:count_width$}: pubkey: {:44}, hash: {:44}, lamports: {}" ,
255
+ "{i:count_width$}: pubkey: {:44}, hash: {:44}, lamports: {:lamports_width$ }" ,
235
256
entry. pubkey. to_string( ) ,
236
257
entry. hash. 0 . to_string( ) ,
237
258
entry. lamports,
@@ -252,13 +273,13 @@ fn do_diff_files(file1: impl AsRef<Path>, file2: impl AsRef<Path>) -> Result<(),
252
273
} else {
253
274
for ( i, ( lhs, rhs) ) in mismatch_entries. iter ( ) . enumerate ( ) {
254
275
println ! (
255
- "{i:count_width$}: pubkey: {:44}, hash: {:44}, lamports: {}" ,
276
+ "{i:count_width$}: pubkey: {:44}, hash: {:44}, lamports: {:lamports_width$ }" ,
256
277
lhs. pubkey. to_string( ) ,
257
278
lhs. hash. 0 . to_string( ) ,
258
279
lhs. lamports,
259
280
) ;
260
281
println ! (
261
- "{i:count_width$}: file 2: {:44}, hash: {:44}, lamports: {}" ,
282
+ "{i:count_width$}: file 2: {:44}, hash: {:44}, lamports: {:lamports_width$ }" ,
262
283
"(same)" . to_string( ) ,
263
284
rhs. hash. 0 . to_string( ) ,
264
285
rhs. lamports,
@@ -465,12 +486,10 @@ fn get_cache_files_in(dir: impl AsRef<Path>) -> Result<Vec<CacheFileInfo>, io::E
465
486
Ok ( cache_files)
466
487
}
467
488
468
- /// Returns the entries in `file`
489
+ /// Returns the entries in `file`, and the capitalization
469
490
///
470
491
/// If there are multiple entries for a pubkey, only the latest is returned.
471
- fn extract_latest_entries_in (
472
- file : impl AsRef < Path > ,
473
- ) -> Result < HashMap < Pubkey , ( AccountHash , /* lamports */ u64 ) > , String > {
492
+ fn extract_latest_entries_in ( file : impl AsRef < Path > ) -> Result < LatestEntriesInfo , String > {
474
493
let force = false ; // skipping sanity checks is not supported when extracting entries
475
494
let ( reader, header) = open_file ( & file, force) . map_err ( |err| {
476
495
format ! (
@@ -481,12 +500,21 @@ fn extract_latest_entries_in(
481
500
482
501
// entries in the file are sorted by pubkey then slot,
483
502
// so we want to keep the *last* entry (if there are duplicates)
503
+ let mut capitalization = Saturating ( 0 ) ;
484
504
let mut entries = HashMap :: default ( ) ;
485
505
scan_file ( reader, header. count , |entry| {
486
- entries. insert ( entry. pubkey , ( entry. hash , entry. lamports ) ) ;
506
+ capitalization += entry. lamports ;
507
+ let old_value = entries. insert ( entry. pubkey , ( entry. hash , entry. lamports ) ) ;
508
+ if let Some ( ( _, old_lamports) ) = old_value {
509
+ // back out the old value's lamports, so we only keep the latest's for capitalization
510
+ capitalization -= old_lamports;
511
+ }
487
512
} ) ?;
488
513
489
- Ok ( entries)
514
+ Ok ( LatestEntriesInfo {
515
+ latest_entries : entries,
516
+ capitalization : capitalization. 0 ,
517
+ } )
490
518
}
491
519
492
520
/// Scans file with `reader` and applies `user_fn` to each entry
@@ -578,6 +606,12 @@ struct CacheFileInfo {
578
606
parsed : ParsedCacheHashDataFilename ,
579
607
}
580
608
609
+ #[ derive( Debug ) ]
610
+ struct LatestEntriesInfo {
611
+ latest_entries : HashMap < Pubkey , ( AccountHash , /* lamports */ u64 ) > ,
612
+ capitalization : u64 , // lamports
613
+ }
614
+
581
615
#[ derive( Debug ) ]
582
616
struct ElapsedOnDrop {
583
617
message : String ,
0 commit comments