@@ -701,6 +701,73 @@ impl AccountsDB {
701
701
accounts_index. uncleaned_roots . clear ( ) ;
702
702
}
703
703
704
+ fn inc_store_counts (
705
+ no_delete_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 ( & no_delete_id) {
711
+ return ;
712
+ }
713
+ * store_counts. get_mut ( & no_delete_id) . unwrap ( ) += 1 ;
714
+ already_counted. insert ( no_delete_id) ;
715
+ let mut affected_pubkeys = HashSet :: new ( ) ;
716
+ for ( key, account_infos) in purges {
717
+ for ( _slot, account_info) in account_infos {
718
+ if account_info. store_id == no_delete_id {
719
+ affected_pubkeys. insert ( key) ;
720
+ }
721
+ }
722
+ }
723
+ for key in affected_pubkeys {
724
+ for ( _slot, account_info) in purges. get ( & key) . unwrap ( ) {
725
+ Self :: inc_store_counts (
726
+ account_info. store_id ,
727
+ purges,
728
+ store_counts,
729
+ already_counted,
730
+ ) ;
731
+ }
732
+ }
733
+ }
734
+
735
+ fn calc_delete_dependencies (
736
+ accounts_index : & AccountsIndex < AccountInfo > ,
737
+ purges : & HashMap < Pubkey , Vec < ( Slot , AccountInfo ) > > ,
738
+ store_counts : & mut HashMap < AppendVecId , usize > ,
739
+ ) {
740
+ // Another pass to check if there are some filtered accounts which
741
+ // do not match the criteria of deleting all appendvecs which contain them
742
+ // then increment their storage count.
743
+ let mut already_counted = HashSet :: new ( ) ;
744
+ for ( pubkey, account_infos) in purges. iter ( ) {
745
+ let no_delete =
746
+ if account_infos. len ( ) as u64 != accounts_index. ref_count_from_storage ( & pubkey) {
747
+ true
748
+ } else {
749
+ let mut no_delete = false ;
750
+ for ( _slot, account_info) in account_infos {
751
+ if * store_counts. get ( & account_info. store_id ) . unwrap ( ) != 0 {
752
+ no_delete = true ;
753
+ break ;
754
+ }
755
+ }
756
+ no_delete
757
+ } ;
758
+ if no_delete {
759
+ for ( _slot_id, account_info) in account_infos {
760
+ Self :: inc_store_counts (
761
+ account_info. store_id ,
762
+ & purges,
763
+ store_counts,
764
+ & mut already_counted,
765
+ ) ;
766
+ }
767
+ }
768
+ }
769
+ }
770
+
704
771
// Purge zero lamport accounts and older rooted account states as garbage
705
772
// collection
706
773
// Only remove those accounts where the entire rooted history of the account
@@ -777,29 +844,8 @@ impl AccountsDB {
777
844
}
778
845
}
779
846
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
- }
847
+ Self :: calc_delete_dependencies ( & accounts_index, & purges, & mut store_counts) ;
848
+
803
849
store_counts_time. stop ( ) ;
804
850
805
851
// Only keep purges where the entire history of the account in the root set
@@ -3842,4 +3888,69 @@ pub mod tests {
3842
3888
accounts. all_account_count_in_append_vec( shrink_slot)
3843
3889
) ;
3844
3890
}
3891
+
3892
+ #[ test]
3893
+ fn test_delete_dependencies ( ) {
3894
+ solana_logger:: setup ( ) ;
3895
+ let mut accounts_index = AccountsIndex :: default ( ) ;
3896
+ let key0 = Pubkey :: new_from_array ( [ 0u8 ; 32 ] ) ;
3897
+ let key1 = Pubkey :: new_from_array ( [ 1u8 ; 32 ] ) ;
3898
+ let key2 = Pubkey :: new_from_array ( [ 2u8 ; 32 ] ) ;
3899
+ let info0 = AccountInfo {
3900
+ store_id : 0 ,
3901
+ offset : 0 ,
3902
+ lamports : 0 ,
3903
+ } ;
3904
+ let info1 = AccountInfo {
3905
+ store_id : 1 ,
3906
+ offset : 0 ,
3907
+ lamports : 0 ,
3908
+ } ;
3909
+ let info2 = AccountInfo {
3910
+ store_id : 2 ,
3911
+ offset : 0 ,
3912
+ lamports : 0 ,
3913
+ } ;
3914
+ let info3 = AccountInfo {
3915
+ store_id : 3 ,
3916
+ offset : 0 ,
3917
+ lamports : 0 ,
3918
+ } ;
3919
+ let mut reclaims = vec ! [ ] ;
3920
+ accounts_index. insert ( 0 , & key0, info0. clone ( ) , & mut reclaims) ;
3921
+ accounts_index. insert ( 1 , & key0, info1. clone ( ) , & mut reclaims) ;
3922
+ accounts_index. insert ( 1 , & key1, info1. clone ( ) , & mut reclaims) ;
3923
+ accounts_index. insert ( 2 , & key1, info2. clone ( ) , & mut reclaims) ;
3924
+ accounts_index. insert ( 2 , & key2, info2. clone ( ) , & mut reclaims) ;
3925
+ accounts_index. insert ( 3 , & key2, info3. clone ( ) , & mut reclaims) ;
3926
+ accounts_index. add_root ( 0 ) ;
3927
+ accounts_index. add_root ( 1 ) ;
3928
+ accounts_index. add_root ( 2 ) ;
3929
+ accounts_index. add_root ( 3 ) ;
3930
+ let mut purges = HashMap :: new ( ) ;
3931
+ purges. insert ( key0, accounts_index. would_purge ( & key0) ) ;
3932
+ purges. insert ( key1, accounts_index. would_purge ( & key1) ) ;
3933
+ purges. insert ( key2, accounts_index. would_purge ( & key2) ) ;
3934
+ for ( key, list) in & purges {
3935
+ info ! ( " purge {} =>" , key) ;
3936
+ for x in list {
3937
+ info ! ( " {:?}" , x) ;
3938
+ }
3939
+ }
3940
+
3941
+ let mut store_counts = HashMap :: new ( ) ;
3942
+ store_counts. insert ( 0 , 0 ) ;
3943
+ store_counts. insert ( 1 , 0 ) ;
3944
+ store_counts. insert ( 2 , 0 ) ;
3945
+ store_counts. insert ( 3 , 1 ) ;
3946
+ AccountsDB :: calc_delete_dependencies ( & accounts_index, & purges, & mut store_counts) ;
3947
+ let mut stores: Vec < _ > = store_counts. keys ( ) . cloned ( ) . collect ( ) ;
3948
+ stores. sort ( ) ;
3949
+ for store in & stores {
3950
+ info ! ( "store: {:?} : {}" , store, store_counts. get( & store) . unwrap( ) ) ;
3951
+ }
3952
+ for x in 0 ..3 {
3953
+ assert ! ( store_counts[ & x] >= 1 ) ;
3954
+ }
3955
+ }
3845
3956
}
0 commit comments