@@ -701,6 +701,75 @@ impl AccountsDB {
701
701
accounts_index. uncleaned_roots . clear ( ) ;
702
702
}
703
703
704
+ fn inc_store_counts (
705
+ id : AppendVecId ,
706
+ purges : & HashMap < Pubkey , Vec < ( Slot , AccountInfo ) > > ,
707
+ store_counts : & mut HashMap < AppendVecId , usize > ,
708
+ already_counted : & mut HashSet < AppendVecId > ,
709
+ ) {
710
+ if already_counted. contains ( & id) {
711
+ return ;
712
+ }
713
+ * store_counts. get_mut ( & id) . unwrap ( ) += 1 ;
714
+ info ! ( "inc_store_counts: {}" , id) ;
715
+ let mut keys = HashSet :: new ( ) ;
716
+ for ( key, account_infos) in purges {
717
+ for ( _slot, account_info) in account_infos {
718
+ if account_info. store_id == id {
719
+ keys. insert ( key) ;
720
+ }
721
+ }
722
+ }
723
+ already_counted. insert ( id) ;
724
+ for key in keys {
725
+ for ( slot, account_info) in purges. get ( & key) . unwrap ( ) {
726
+ Self :: inc_store_counts (
727
+ account_info. store_id ,
728
+ purges,
729
+ store_counts,
730
+ already_counted,
731
+ ) ;
732
+ }
733
+ }
734
+ }
735
+
736
+ fn calc_delete_dependencies (
737
+ accounts_index : & AccountsIndex < AccountInfo > ,
738
+ purges : & HashMap < Pubkey , Vec < ( Slot , AccountInfo ) > > ,
739
+ store_counts : & mut HashMap < AppendVecId , usize > ,
740
+ ) {
741
+ // Another pass to check if there are some filtered accounts which
742
+ // do not match the criteria of deleting all appendvecs which contain them
743
+ // then increment their storage count.
744
+ let mut already_counted = HashSet :: new ( ) ;
745
+ for ( pubkey, account_infos) in purges. iter ( ) {
746
+ let no_delete =
747
+ if account_infos. len ( ) as u64 != accounts_index. ref_count_from_storage ( & pubkey) {
748
+ true
749
+ } else {
750
+ let mut no_delete = false ;
751
+ for ( _slot, account_info) in account_infos {
752
+ if * store_counts. get ( & account_info. store_id ) . unwrap ( ) != 0 {
753
+ no_delete = true ;
754
+ break ;
755
+ }
756
+ }
757
+ no_delete
758
+ } ;
759
+ if no_delete {
760
+ for ( _slot_id, account_info) in account_infos {
761
+ * store_counts. get_mut ( & account_info. store_id ) . unwrap ( ) += 1 ;
762
+ Self :: inc_store_counts (
763
+ account_info. store_id ,
764
+ & purges,
765
+ store_counts,
766
+ & mut already_counted,
767
+ ) ;
768
+ }
769
+ }
770
+ }
771
+ }
772
+
704
773
// Purge zero lamport accounts and older rooted account states as garbage
705
774
// collection
706
775
// Only remove those accounts where the entire rooted history of the account
@@ -777,29 +846,8 @@ impl AccountsDB {
777
846
}
778
847
}
779
848
780
- // Another pass to check if there are some filtered accounts which
781
- // do not match the criteria of deleting all appendvecs which contain them
782
- // then increment their storage count.
783
- for ( pubkey, account_infos) in & purges {
784
- let no_delete =
785
- if account_infos. len ( ) as u64 != accounts_index. ref_count_from_storage ( & pubkey) {
786
- true
787
- } else {
788
- let mut no_delete = false ;
789
- for ( _slot, account_info) in account_infos {
790
- if * store_counts. get ( & account_info. store_id ) . unwrap ( ) != 0 {
791
- no_delete = true ;
792
- break ;
793
- }
794
- }
795
- no_delete
796
- } ;
797
- if no_delete {
798
- for ( _slot, account_info) in account_infos {
799
- * store_counts. get_mut ( & account_info. store_id ) . unwrap ( ) += 1 ;
800
- }
801
- }
802
- }
849
+ Self :: calc_delete_dependencies ( & accounts_index, & purges, & mut store_counts) ;
850
+
803
851
store_counts_time. stop ( ) ;
804
852
805
853
// Only keep purges where the entire history of the account in the root set
@@ -3842,4 +3890,51 @@ pub mod tests {
3842
3890
accounts. all_account_count_in_append_vec( shrink_slot)
3843
3891
) ;
3844
3892
}
3893
+
3894
+ #[ test]
3895
+ fn test_delete_dependencies ( ) {
3896
+ let mut accounts_index = AccountsIndex :: default ( ) ;
3897
+ let key0 = Pubkey :: new_rand ( ) ;
3898
+ let key1 = Pubkey :: new_rand ( ) ;
3899
+ let key2 = Pubkey :: new_rand ( ) ;
3900
+ let info0 = AccountInfo {
3901
+ store_id : 0 ,
3902
+ offset : 0 ,
3903
+ lamports : 0 ,
3904
+ } ;
3905
+ let info1 = AccountInfo {
3906
+ store_id : 1 ,
3907
+ offset : 0 ,
3908
+ lamports : 0 ,
3909
+ } ;
3910
+ let info2 = AccountInfo {
3911
+ store_id : 2 ,
3912
+ offset : 0 ,
3913
+ lamports : 0 ,
3914
+ } ;
3915
+ let info3 = AccountInfo {
3916
+ store_id : 3 ,
3917
+ offset : 0 ,
3918
+ lamports : 0 ,
3919
+ } ;
3920
+ let mut reclaims = vec ! [ ] ;
3921
+ accounts_index. insert ( 0 , & key0, info0. clone ( ) , & mut reclaims) ;
3922
+ accounts_index. insert ( 1 , & key0, info1. clone ( ) , & mut reclaims) ;
3923
+ accounts_index. insert ( 1 , & key1, info1. clone ( ) , & mut reclaims) ;
3924
+ accounts_index. insert ( 2 , & key1, info2. clone ( ) , & mut reclaims) ;
3925
+ accounts_index. insert ( 2 , & key2, info2. clone ( ) , & mut reclaims) ;
3926
+ accounts_index. insert ( 3 , & key2, info3. clone ( ) , & mut reclaims) ;
3927
+ let mut purges = HashMap :: new ( ) ;
3928
+ purges. insert ( key0, vec ! [ ( 0 , info0) ] ) ;
3929
+ purges. insert ( key1, vec ! [ ( 1 , info1) ] ) ;
3930
+ purges. insert ( key2, vec ! [ ( 2 , info2) ] ) ;
3931
+ let mut store_counts = HashMap :: new ( ) ;
3932
+ store_counts. insert ( 0 , 2 ) ;
3933
+ store_counts. insert ( 1 , 2 ) ;
3934
+ store_counts. insert ( 2 , 2 ) ;
3935
+ store_counts. insert ( 3 , 2 ) ;
3936
+ AccountsDB :: calc_delete_dependencies ( & accounts_index, & purges, & mut store_counts) ;
3937
+ info ! ( "store_counts: {:?}" , store_counts) ;
3938
+ assert_eq ! ( store_counts[ & 0 ] , 4 ) ;
3939
+ }
3845
3940
}
0 commit comments