@@ -851,6 +851,7 @@ impl TxMempoolEntry {
851851 self . parents . iter ( ) . copied ( ) ,
852852 RelativesKind :: Ancestors ,
853853 |_| Ok :: < _ , MempoolStoreInvariantError > ( ( ) ) ,
854+ Some ( self . count_with_ancestors - 1 ) ,
854855 ) ;
855856
856857 match result {
@@ -874,6 +875,7 @@ impl TxMempoolEntry {
874875 self . children . iter ( ) . copied ( ) ,
875876 RelativesKind :: Descendants ,
876877 |_| Ok :: < _ , MempoolStoreInvariantError > ( ( ) ) ,
878+ Some ( self . count_with_descendants - 1 ) ,
877879 ) ;
878880
879881 match result {
@@ -891,9 +893,13 @@ impl TxMempoolEntry {
891893 ///
892894 /// This function is mainly intended for testing purposes.
893895 pub fn collect_cluster ( & self , store : & MempoolStore ) -> Result < Cluster , MempoolPolicyError > {
894- let cluster = collect_relatives ( store, [ * self . tx_id ( ) ] , RelativesKind :: Cluster , |_| {
895- Ok :: < _ , MempoolPolicyError > ( ( ) )
896- } ) ?;
896+ let cluster = collect_relatives (
897+ store,
898+ [ * self . tx_id ( ) ] ,
899+ RelativesKind :: Cluster ,
900+ |_| Ok :: < _ , MempoolPolicyError > ( ( ) ) ,
901+ Some ( self . count_with_ancestors + self . count_with_descendants - 1 ) ,
902+ ) ?;
897903
898904 Ok ( Cluster :: new ( cluster) )
899905 }
@@ -940,6 +946,7 @@ impl TxMempoolEntryWithAncestors {
940946 |collected_size| {
941947 ensure_cluster_tx_count_limit ( & store. mempool_config , 1 + collected_size)
942948 } ,
949+ None ,
943950 ) ?) ;
944951 enforce_cluster_size_limit ( store, & entry, & cluster) ?;
945952
@@ -948,6 +955,7 @@ impl TxMempoolEntryWithAncestors {
948955 parents. iter ( ) . copied ( ) ,
949956 RelativesKind :: Ancestors ,
950957 |_| Ok :: < _ , MempoolPolicyError > ( ( ) ) ,
958+ None ,
951959 ) ?) ;
952960
953961 let ancestor_entries_iter = ancestors
@@ -995,17 +1003,26 @@ pub enum RelativesKind {
9951003///
9961004/// After each tx is added to the result, `on_new_tx_added` is called with the current size
9971005/// of the result as the argument.
1006+ ///
1007+ /// `expected_result_size`, if specified, is used to reserve the needed capacity in the result
1008+ /// to avoid redundant reallocations.
9981009pub fn collect_relatives < E > (
9991010 store : & MempoolStore ,
10001011 initial_tx_ids : impl IntoIterator < Item = Id < Transaction > > ,
10011012 kind : RelativesKind ,
10021013 mut on_new_tx_added : impl FnMut ( /*cur_result_size:*/ usize ) -> Result < ( ) , E > ,
1014+ expected_result_size : Option < usize > ,
10031015) -> Result < StoreHashSet < Id < Transaction > > , E >
10041016where
10051017 E : From < MempoolStoreInvariantError > ,
10061018{
1007- let mut stack = Vec :: new ( ) ;
1008- let mut result = StoreHashSet :: default ( ) ;
1019+ let initial_tx_ids = initial_tx_ids. into_iter ( ) ;
1020+ let initial_tx_ids_min_size_hint = initial_tx_ids. size_hint ( ) . 0 ;
1021+ let expected_result_size = expected_result_size. unwrap_or ( initial_tx_ids_min_size_hint) ;
1022+
1023+ let mut stack = Vec :: with_capacity ( initial_tx_ids_min_size_hint) ;
1024+ let mut result =
1025+ StoreHashSet :: with_capacity_and_hasher ( expected_result_size, Default :: default ( ) ) ;
10091026
10101027 let mut visit = |stack : & mut Vec < Id < Transaction > > , tx_id : & Id < Transaction > | -> Result < ( ) , E > {
10111028 if result. insert ( * tx_id) {
0 commit comments