solana_accounts_db/accounts_db/
stats.rs

1use {
2    crate::{accounts_index::AccountsIndexRootsStats, append_vec::APPEND_VEC_STATS},
3    solana_time_utils::AtomicInterval,
4    std::{
5        iter::Sum,
6        num::Saturating,
7        sync::atomic::{AtomicU64, AtomicUsize, Ordering},
8    },
9};
10
11#[derive(Debug, Default)]
12pub struct AccountsStats {
13    pub last_store_report: AtomicInterval,
14    pub store_accounts: AtomicU64,
15    pub store_update_index: AtomicU64,
16    pub store_handle_reclaims: AtomicU64,
17    pub store_append_accounts: AtomicU64,
18    pub stakes_cache_check_and_store_us: AtomicU64,
19    pub store_num_accounts: AtomicU64,
20    pub store_total_data: AtomicU64,
21    pub num_reclaims: AtomicU64,
22    pub create_store_count: AtomicU64,
23    pub dropped_stores: AtomicU64,
24    pub handle_dead_keys_us: AtomicU64,
25    pub purge_exact_us: AtomicU64,
26    pub purge_exact_count: AtomicU64,
27    pub num_obsolete_slots_removed: AtomicUsize,
28    pub num_obsolete_bytes_removed: AtomicU64,
29    pub add_zero_lamport_accounts_us: AtomicU64,
30    pub num_zero_lamport_accounts_added: AtomicU64,
31}
32
33#[derive(Debug, Default)]
34pub struct PurgeStats {
35    pub last_report: AtomicInterval,
36    pub safety_checks_elapsed: AtomicU64,
37    pub remove_cache_elapsed: AtomicU64,
38    pub remove_storage_entries_elapsed: AtomicU64,
39    pub drop_storage_entries_elapsed: AtomicU64,
40    pub num_cached_slots_removed: AtomicUsize,
41    pub num_stored_slots_removed: AtomicUsize,
42    pub total_removed_storage_entries: AtomicUsize,
43    pub total_removed_cached_bytes: AtomicU64,
44    pub total_removed_stored_bytes: AtomicU64,
45    pub scan_storages_elapsed: AtomicU64,
46    pub purge_accounts_index_elapsed: AtomicU64,
47    pub handle_reclaims_elapsed: AtomicU64,
48}
49
50impl PurgeStats {
51    pub fn report(&self, metric_name: &'static str, report_interval_ms: Option<u64>) {
52        let should_report = report_interval_ms
53            .map(|report_interval_ms| self.last_report.should_update(report_interval_ms))
54            .unwrap_or(true);
55
56        if should_report {
57            datapoint_info!(
58                metric_name,
59                (
60                    "safety_checks_elapsed",
61                    self.safety_checks_elapsed.swap(0, Ordering::Relaxed),
62                    i64
63                ),
64                (
65                    "remove_cache_elapsed",
66                    self.remove_cache_elapsed.swap(0, Ordering::Relaxed),
67                    i64
68                ),
69                (
70                    "remove_storage_entries_elapsed",
71                    self.remove_storage_entries_elapsed
72                        .swap(0, Ordering::Relaxed),
73                    i64
74                ),
75                (
76                    "drop_storage_entries_elapsed",
77                    self.drop_storage_entries_elapsed.swap(0, Ordering::Relaxed),
78                    i64
79                ),
80                (
81                    "num_cached_slots_removed",
82                    self.num_cached_slots_removed.swap(0, Ordering::Relaxed),
83                    i64
84                ),
85                (
86                    "num_stored_slots_removed",
87                    self.num_stored_slots_removed.swap(0, Ordering::Relaxed),
88                    i64
89                ),
90                (
91                    "total_removed_storage_entries",
92                    self.total_removed_storage_entries
93                        .swap(0, Ordering::Relaxed),
94                    i64
95                ),
96                (
97                    "total_removed_cached_bytes",
98                    self.total_removed_cached_bytes.swap(0, Ordering::Relaxed),
99                    i64
100                ),
101                (
102                    "total_removed_stored_bytes",
103                    self.total_removed_stored_bytes.swap(0, Ordering::Relaxed),
104                    i64
105                ),
106                (
107                    "scan_storages_elapsed",
108                    self.scan_storages_elapsed.swap(0, Ordering::Relaxed),
109                    i64
110                ),
111                (
112                    "purge_accounts_index_elapsed",
113                    self.purge_accounts_index_elapsed.swap(0, Ordering::Relaxed),
114                    i64
115                ),
116                (
117                    "handle_reclaims_elapsed",
118                    self.handle_reclaims_elapsed.swap(0, Ordering::Relaxed),
119                    i64
120                ),
121            );
122        }
123    }
124}
125
126#[derive(Default, Debug)]
127pub struct StoreAccountsTiming {
128    pub store_accounts_elapsed: u64,
129    pub update_index_elapsed: u64,
130    pub handle_reclaims_elapsed: u64,
131}
132
133impl StoreAccountsTiming {
134    pub fn accumulate(&mut self, other: &Self) {
135        self.store_accounts_elapsed += other.store_accounts_elapsed;
136        self.update_index_elapsed += other.update_index_elapsed;
137        self.handle_reclaims_elapsed += other.handle_reclaims_elapsed;
138    }
139}
140
141#[derive(Debug, Default)]
142pub struct FlushStats {
143    pub num_accounts_flushed: Saturating<usize>,
144    pub num_bytes_flushed: Saturating<u64>,
145    pub num_accounts_purged: Saturating<usize>,
146    pub num_bytes_purged: Saturating<u64>,
147    pub store_accounts_timing: StoreAccountsTiming,
148    pub store_accounts_total_us: Saturating<u64>,
149}
150
151impl FlushStats {
152    pub fn accumulate(&mut self, other: &Self) {
153        self.num_accounts_flushed += other.num_accounts_flushed;
154        self.num_bytes_flushed += other.num_bytes_flushed;
155        self.num_accounts_purged += other.num_accounts_purged;
156        self.num_bytes_purged += other.num_bytes_purged;
157        self.store_accounts_timing
158            .accumulate(&other.store_accounts_timing);
159        self.store_accounts_total_us += other.store_accounts_total_us;
160    }
161}
162
163#[derive(Debug, Default)]
164pub struct LatestAccountsIndexRootsStats {
165    pub roots_len: AtomicUsize,
166    pub uncleaned_roots_len: AtomicUsize,
167    pub roots_range: AtomicU64,
168    pub rooted_cleaned_count: AtomicUsize,
169    pub unrooted_cleaned_count: AtomicUsize,
170    pub clean_unref_from_storage_us: AtomicU64,
171    pub clean_dead_slot_us: AtomicU64,
172}
173
174impl LatestAccountsIndexRootsStats {
175    pub fn update(&self, accounts_index_roots_stats: &AccountsIndexRootsStats) {
176        if let Some(value) = accounts_index_roots_stats.roots_len {
177            self.roots_len.store(value, Ordering::Relaxed);
178        }
179        if let Some(value) = accounts_index_roots_stats.uncleaned_roots_len {
180            self.uncleaned_roots_len.store(value, Ordering::Relaxed);
181        }
182        if let Some(value) = accounts_index_roots_stats.roots_range {
183            self.roots_range.store(value, Ordering::Relaxed);
184        }
185        self.rooted_cleaned_count.fetch_add(
186            accounts_index_roots_stats.rooted_cleaned_count,
187            Ordering::Relaxed,
188        );
189        self.unrooted_cleaned_count.fetch_add(
190            accounts_index_roots_stats.unrooted_cleaned_count,
191            Ordering::Relaxed,
192        );
193        self.clean_unref_from_storage_us.fetch_add(
194            accounts_index_roots_stats.clean_unref_from_storage_us,
195            Ordering::Relaxed,
196        );
197        self.clean_dead_slot_us.fetch_add(
198            accounts_index_roots_stats.clean_dead_slot_us,
199            Ordering::Relaxed,
200        );
201    }
202
203    pub fn report(&self) {
204        datapoint_info!(
205            "accounts_index_roots_len",
206            ("roots_len", self.roots_len.load(Ordering::Relaxed), i64),
207            (
208                "uncleaned_roots_len",
209                self.uncleaned_roots_len.load(Ordering::Relaxed),
210                i64
211            ),
212            (
213                "roots_range_width",
214                self.roots_range.load(Ordering::Relaxed),
215                i64
216            ),
217            (
218                "unrooted_cleaned_count",
219                self.unrooted_cleaned_count.swap(0, Ordering::Relaxed),
220                i64
221            ),
222            (
223                "rooted_cleaned_count",
224                self.rooted_cleaned_count.swap(0, Ordering::Relaxed),
225                i64
226            ),
227            (
228                "clean_unref_from_storage_us",
229                self.clean_unref_from_storage_us.swap(0, Ordering::Relaxed),
230                i64
231            ),
232            (
233                "clean_dead_slot_us",
234                self.clean_dead_slot_us.swap(0, Ordering::Relaxed),
235                i64
236            ),
237            (
238                "append_vecs_open",
239                APPEND_VEC_STATS.files_open.load(Ordering::Relaxed),
240                i64
241            ),
242            (
243                "append_vecs_dirty",
244                APPEND_VEC_STATS.files_dirty.load(Ordering::Relaxed),
245                i64
246            ),
247            (
248                "append_vecs_open_as_mmap",
249                APPEND_VEC_STATS.open_as_mmap.load(Ordering::Relaxed),
250                i64
251            ),
252            (
253                "append_vecs_open_as_file_io",
254                APPEND_VEC_STATS.open_as_file_io.load(Ordering::Relaxed),
255                i64
256            )
257        );
258
259        // Don't need to reset since this tracks the latest updates, not a cumulative total
260    }
261}
262
263#[derive(Debug, Default)]
264pub struct CleanAccountsStats {
265    pub purge_stats: PurgeStats,
266    pub latest_accounts_index_roots_stats: LatestAccountsIndexRootsStats,
267
268    // stats held here and reported by clean_accounts
269    pub clean_old_root_us: AtomicU64,
270    pub clean_old_root_reclaim_us: AtomicU64,
271    pub remove_dead_accounts_remove_us: AtomicU64,
272    pub remove_dead_accounts_shrink_us: AtomicU64,
273    pub clean_stored_dead_slots_us: AtomicU64,
274    pub get_account_sizes_us: AtomicU64,
275    pub slots_cleaned: AtomicU64,
276}
277
278impl CleanAccountsStats {
279    pub fn report(&self) {
280        self.purge_stats.report("clean_purge_slots_stats", None);
281        self.latest_accounts_index_roots_stats.report();
282    }
283}
284
285#[derive(Debug, Default)]
286pub struct ShrinkAncientStats {
287    pub shrink_stats: ShrinkStats,
288    pub ancient_append_vecs_shrunk: AtomicU64,
289    pub total_us: AtomicU64,
290    pub random_shrink: AtomicU64,
291    pub slots_considered: AtomicU64,
292    pub ancient_scanned: AtomicU64,
293    pub bytes_ancient_created: AtomicU64,
294    pub bytes_from_must_shrink: AtomicU64,
295    pub bytes_from_smallest_storages: AtomicU64,
296    pub bytes_from_newest_storages: AtomicU64,
297    pub many_ref_slots_skipped: AtomicU64,
298    pub slots_cannot_move_count: AtomicU64,
299    pub many_refs_old_alive: AtomicU64,
300    pub slots_eligible_to_shrink: AtomicU64,
301    pub total_dead_bytes: AtomicU64,
302    pub total_alive_bytes: AtomicU64,
303    pub slot: AtomicU64,
304    pub ideal_storage_size: AtomicU64,
305}
306
307#[derive(Debug, Default)]
308pub struct ShrinkStatsSub {
309    pub store_accounts_timing: StoreAccountsTiming,
310    pub rewrite_elapsed_us: Saturating<u64>,
311    pub create_and_insert_store_elapsed_us: Saturating<u64>,
312    pub unpackable_slots_count: Saturating<usize>,
313    pub newest_alive_packed_count: Saturating<usize>,
314}
315
316impl ShrinkStatsSub {
317    pub fn accumulate(&mut self, other: &Self) {
318        self.store_accounts_timing
319            .accumulate(&other.store_accounts_timing);
320        self.rewrite_elapsed_us += other.rewrite_elapsed_us;
321        self.create_and_insert_store_elapsed_us += other.create_and_insert_store_elapsed_us;
322        self.unpackable_slots_count += other.unpackable_slots_count;
323        self.newest_alive_packed_count += other.newest_alive_packed_count;
324    }
325}
326#[derive(Debug, Default)]
327pub struct ShrinkStats {
328    pub last_report: AtomicInterval,
329    pub num_slots_shrunk: AtomicUsize,
330    pub storage_read_elapsed: AtomicU64,
331    pub num_duplicated_accounts: AtomicU64,
332    pub index_read_elapsed: AtomicU64,
333    pub create_and_insert_store_elapsed: AtomicU64,
334    pub store_accounts_elapsed: AtomicU64,
335    pub update_index_elapsed: AtomicU64,
336    pub handle_reclaims_elapsed: AtomicU64,
337    pub remove_old_stores_shrink_us: AtomicU64,
338    pub rewrite_elapsed: AtomicU64,
339    pub unpackable_slots_count: AtomicU64,
340    pub newest_alive_packed_count: AtomicU64,
341    pub drop_storage_entries_elapsed: AtomicU64,
342    pub accounts_removed: AtomicUsize,
343    pub bytes_removed: AtomicU64,
344    pub bytes_written: AtomicU64,
345    pub skipped_shrink: AtomicU64,
346    pub dead_accounts: AtomicU64,
347    pub alive_accounts: AtomicU64,
348    pub index_scan_returned_none: AtomicU64,
349    pub index_scan_returned_some: AtomicU64,
350    pub obsolete_accounts_filtered: AtomicU64,
351    pub accounts_loaded: AtomicU64,
352    pub initial_candidates_count: AtomicU64,
353    pub purged_zero_lamports: AtomicU64,
354    pub accounts_not_found_in_index: AtomicU64,
355    pub num_ancient_slots_shrunk: AtomicU64,
356    pub ancient_slots_added_to_shrink: AtomicU64,
357    pub ancient_bytes_added_to_shrink: AtomicU64,
358    pub num_dead_slots_added_to_clean: AtomicU64,
359    pub num_slots_with_zero_lamport_accounts_added_to_shrink: AtomicU64,
360    pub marking_zero_dead_accounts_in_non_shrinkable_store: AtomicU64,
361    pub num_zero_lamport_single_ref_accounts_found: AtomicU64,
362}
363
364impl ShrinkStats {
365    pub fn report(&self) {
366        if self.last_report.should_update(1000) {
367            datapoint_info!(
368                "shrink_stats",
369                (
370                    "ancient_slots_added_to_shrink",
371                    self.ancient_slots_added_to_shrink
372                        .swap(0, Ordering::Relaxed),
373                    i64
374                ),
375                (
376                    "ancient_bytes_added_to_shrink",
377                    self.ancient_bytes_added_to_shrink
378                        .swap(0, Ordering::Relaxed),
379                    i64
380                ),
381                (
382                    "num_slots_shrunk",
383                    self.num_slots_shrunk.swap(0, Ordering::Relaxed),
384                    i64
385                ),
386                (
387                    "obsolete_accounts_filtered",
388                    self.obsolete_accounts_filtered.swap(0, Ordering::Relaxed),
389                    i64
390                ),
391                (
392                    "index_scan_returned_none",
393                    self.index_scan_returned_none.swap(0, Ordering::Relaxed),
394                    i64
395                ),
396                (
397                    "index_scan_returned_some",
398                    self.index_scan_returned_some.swap(0, Ordering::Relaxed),
399                    i64
400                ),
401                (
402                    "storage_read_elapsed",
403                    self.storage_read_elapsed.swap(0, Ordering::Relaxed),
404                    i64
405                ),
406                (
407                    "num_duplicated_accounts",
408                    self.num_duplicated_accounts.swap(0, Ordering::Relaxed),
409                    i64
410                ),
411                (
412                    "index_read_elapsed",
413                    self.index_read_elapsed.swap(0, Ordering::Relaxed),
414                    i64
415                ),
416                (
417                    "create_and_insert_store_elapsed",
418                    self.create_and_insert_store_elapsed
419                        .swap(0, Ordering::Relaxed),
420                    i64
421                ),
422                (
423                    "store_accounts_elapsed",
424                    self.store_accounts_elapsed.swap(0, Ordering::Relaxed),
425                    i64
426                ),
427                (
428                    "update_index_elapsed",
429                    self.update_index_elapsed.swap(0, Ordering::Relaxed),
430                    i64
431                ),
432                (
433                    "handle_reclaims_elapsed",
434                    self.handle_reclaims_elapsed.swap(0, Ordering::Relaxed),
435                    i64
436                ),
437                (
438                    "remove_old_stores_shrink_us",
439                    self.remove_old_stores_shrink_us.swap(0, Ordering::Relaxed),
440                    i64
441                ),
442                (
443                    "rewrite_elapsed",
444                    self.rewrite_elapsed.swap(0, Ordering::Relaxed),
445                    i64
446                ),
447                (
448                    "drop_storage_entries_elapsed",
449                    self.drop_storage_entries_elapsed.swap(0, Ordering::Relaxed),
450                    i64
451                ),
452                (
453                    "accounts_removed",
454                    self.accounts_removed.swap(0, Ordering::Relaxed),
455                    i64
456                ),
457                (
458                    "bytes_removed",
459                    self.bytes_removed.swap(0, Ordering::Relaxed),
460                    i64
461                ),
462                (
463                    "bytes_written",
464                    self.bytes_written.swap(0, Ordering::Relaxed),
465                    i64
466                ),
467                (
468                    "skipped_shrink",
469                    self.skipped_shrink.swap(0, Ordering::Relaxed),
470                    i64
471                ),
472                (
473                    "alive_accounts",
474                    self.alive_accounts.swap(0, Ordering::Relaxed),
475                    i64
476                ),
477                (
478                    "dead_accounts",
479                    self.dead_accounts.swap(0, Ordering::Relaxed),
480                    i64
481                ),
482                (
483                    "accounts_loaded",
484                    self.accounts_loaded.swap(0, Ordering::Relaxed),
485                    i64
486                ),
487                (
488                    "purged_zero_lamports_count",
489                    self.purged_zero_lamports.swap(0, Ordering::Relaxed),
490                    i64
491                ),
492                (
493                    "num_ancient_slots_shrunk",
494                    self.num_ancient_slots_shrunk.swap(0, Ordering::Relaxed),
495                    i64
496                ),
497                (
498                    "accounts_not_found_in_index",
499                    self.accounts_not_found_in_index.swap(0, Ordering::Relaxed),
500                    i64
501                ),
502                (
503                    "initial_candidates_count",
504                    self.initial_candidates_count.swap(0, Ordering::Relaxed),
505                    i64
506                ),
507                (
508                    "num_dead_slots_added_to_clean",
509                    self.num_dead_slots_added_to_clean
510                        .swap(0, Ordering::Relaxed),
511                    i64
512                ),
513                (
514                    "num_slots_with_zero_lamport_accounts_added_to_shrink",
515                    self.num_slots_with_zero_lamport_accounts_added_to_shrink
516                        .swap(0, Ordering::Relaxed),
517                    i64
518                ),
519                (
520                    "marking_zero_dead_accounts_in_non_shrinkable_store",
521                    self.marking_zero_dead_accounts_in_non_shrinkable_store
522                        .swap(0, Ordering::Relaxed),
523                    i64
524                ),
525                (
526                    "num_zero_lamport_single_ref_accounts_found",
527                    self.num_zero_lamport_single_ref_accounts_found
528                        .swap(0, Ordering::Relaxed),
529                    i64
530                ),
531            );
532        }
533    }
534}
535
536impl ShrinkAncientStats {
537    pub fn report(&self) {
538        datapoint_info!(
539            "shrink_ancient_stats",
540            (
541                "num_slots_shrunk",
542                self.shrink_stats
543                    .num_slots_shrunk
544                    .swap(0, Ordering::Relaxed),
545                i64
546            ),
547            (
548                "index_scan_returned_none",
549                self.shrink_stats
550                    .index_scan_returned_none
551                    .swap(0, Ordering::Relaxed),
552                i64
553            ),
554            (
555                "index_scan_returned_some",
556                self.shrink_stats
557                    .index_scan_returned_some
558                    .swap(0, Ordering::Relaxed),
559                i64
560            ),
561            (
562                "storage_read_elapsed",
563                self.shrink_stats
564                    .storage_read_elapsed
565                    .swap(0, Ordering::Relaxed),
566                i64
567            ),
568            (
569                "num_duplicated_accounts",
570                self.shrink_stats
571                    .num_duplicated_accounts
572                    .swap(0, Ordering::Relaxed),
573                i64
574            ),
575            (
576                "index_read_elapsed",
577                self.shrink_stats
578                    .index_read_elapsed
579                    .swap(0, Ordering::Relaxed),
580                i64
581            ),
582            (
583                "create_and_insert_store_elapsed",
584                self.shrink_stats
585                    .create_and_insert_store_elapsed
586                    .swap(0, Ordering::Relaxed),
587                i64
588            ),
589            (
590                "store_accounts_elapsed",
591                self.shrink_stats
592                    .store_accounts_elapsed
593                    .swap(0, Ordering::Relaxed),
594                i64
595            ),
596            (
597                "update_index_elapsed",
598                self.shrink_stats
599                    .update_index_elapsed
600                    .swap(0, Ordering::Relaxed),
601                i64
602            ),
603            (
604                "handle_reclaims_elapsed",
605                self.shrink_stats
606                    .handle_reclaims_elapsed
607                    .swap(0, Ordering::Relaxed),
608                i64
609            ),
610            (
611                "remove_old_stores_shrink_us",
612                self.shrink_stats
613                    .remove_old_stores_shrink_us
614                    .swap(0, Ordering::Relaxed),
615                i64
616            ),
617            (
618                "rewrite_elapsed",
619                self.shrink_stats.rewrite_elapsed.swap(0, Ordering::Relaxed),
620                i64
621            ),
622            (
623                "unpackable_slots_count",
624                self.shrink_stats
625                    .unpackable_slots_count
626                    .swap(0, Ordering::Relaxed),
627                i64
628            ),
629            (
630                "newest_alive_packed_count",
631                self.shrink_stats
632                    .newest_alive_packed_count
633                    .swap(0, Ordering::Relaxed),
634                i64
635            ),
636            (
637                "drop_storage_entries_elapsed",
638                self.shrink_stats
639                    .drop_storage_entries_elapsed
640                    .swap(0, Ordering::Relaxed),
641                i64
642            ),
643            (
644                "accounts_removed",
645                self.shrink_stats
646                    .accounts_removed
647                    .swap(0, Ordering::Relaxed),
648                i64
649            ),
650            (
651                "bytes_removed",
652                self.shrink_stats.bytes_removed.swap(0, Ordering::Relaxed),
653                i64
654            ),
655            (
656                "bytes_written",
657                self.shrink_stats.bytes_written.swap(0, Ordering::Relaxed),
658                i64
659            ),
660            (
661                "alive_accounts",
662                self.shrink_stats.alive_accounts.swap(0, Ordering::Relaxed),
663                i64
664            ),
665            (
666                "dead_accounts",
667                self.shrink_stats.dead_accounts.swap(0, Ordering::Relaxed),
668                i64
669            ),
670            (
671                "accounts_loaded",
672                self.shrink_stats.accounts_loaded.swap(0, Ordering::Relaxed),
673                i64
674            ),
675            (
676                "ancient_append_vecs_shrunk",
677                self.ancient_append_vecs_shrunk.swap(0, Ordering::Relaxed),
678                i64
679            ),
680            ("random", self.random_shrink.swap(0, Ordering::Relaxed), i64),
681            (
682                "slots_eligible_to_shrink",
683                self.slots_eligible_to_shrink.swap(0, Ordering::Relaxed),
684                i64
685            ),
686            (
687                "total_dead_bytes",
688                self.total_dead_bytes.swap(0, Ordering::Relaxed),
689                i64
690            ),
691            (
692                "total_alive_bytes",
693                self.total_alive_bytes.swap(0, Ordering::Relaxed),
694                i64
695            ),
696            (
697                "slots_considered",
698                self.slots_considered.swap(0, Ordering::Relaxed),
699                i64
700            ),
701            (
702                "ancient_scanned",
703                self.ancient_scanned.swap(0, Ordering::Relaxed),
704                i64
705            ),
706            ("total_us", self.total_us.swap(0, Ordering::Relaxed), i64),
707            (
708                "bytes_ancient_created",
709                self.bytes_ancient_created.swap(0, Ordering::Relaxed),
710                i64
711            ),
712            (
713                "bytes_from_must_shrink",
714                self.bytes_from_must_shrink.swap(0, Ordering::Relaxed),
715                i64
716            ),
717            (
718                "bytes_from_smallest_storages",
719                self.bytes_from_smallest_storages.swap(0, Ordering::Relaxed),
720                i64
721            ),
722            (
723                "bytes_from_newest_storages",
724                self.bytes_from_newest_storages.swap(0, Ordering::Relaxed),
725                i64
726            ),
727            (
728                "many_ref_slots_skipped",
729                self.many_ref_slots_skipped.swap(0, Ordering::Relaxed),
730                i64
731            ),
732            (
733                "slots_cannot_move_count",
734                self.slots_cannot_move_count.swap(0, Ordering::Relaxed),
735                i64
736            ),
737            (
738                "many_refs_old_alive",
739                self.many_refs_old_alive.swap(0, Ordering::Relaxed),
740                i64
741            ),
742            (
743                "purged_zero_lamports_count",
744                self.shrink_stats
745                    .purged_zero_lamports
746                    .swap(0, Ordering::Relaxed),
747                i64
748            ),
749            (
750                "accounts_not_found_in_index",
751                self.shrink_stats
752                    .accounts_not_found_in_index
753                    .swap(0, Ordering::Relaxed),
754                i64
755            ),
756            ("slot", self.slot.load(Ordering::Relaxed), i64),
757            (
758                "ideal_storage_size",
759                self.ideal_storage_size.swap(0, Ordering::Relaxed),
760                i64
761            ),
762        );
763    }
764}
765
766#[derive(Debug, Default)]
767pub struct ObsoleteAccountsStats {
768    pub accounts_marked_obsolete: u64,
769    pub slots_removed: u64,
770}
771
772impl Sum<Self> for ObsoleteAccountsStats {
773    fn sum<I>(iter: I) -> Self
774    where
775        I: Iterator<Item = Self>,
776    {
777        iter.fold(Self::default(), |mut accumulated_stats, item| {
778            accumulated_stats.accounts_marked_obsolete += item.accounts_marked_obsolete;
779            accumulated_stats.slots_removed += item.slots_removed;
780            accumulated_stats
781        })
782    }
783}