@@ -30,15 +30,17 @@ fd_policy_new( void * shmem, ulong dedup_max, ulong peer_max, ulong seed ) {
3030  void  *         dedup_lru    =  FD_SCRATCH_ALLOC_APPEND ( l , fd_policy_dedup_lru_align (),  fd_policy_dedup_lru_footprint  (             ) );
3131  void  *         peers        =  FD_SCRATCH_ALLOC_APPEND ( l , fd_policy_peer_map_align (),   fd_policy_peer_map_footprint   ( lg_peer_max  ) );
3232  void  *         peers_pool   =  FD_SCRATCH_ALLOC_APPEND ( l , fd_peer_pool_align (),         fd_peer_pool_footprint         ( peer_max     ) );
33-   void  *         peers_dlist  =  FD_SCRATCH_ALLOC_APPEND ( l , fd_peer_dlist_align (),        fd_peer_dlist_footprint        (             ) );
33+   void  *         peers_best   =  FD_SCRATCH_ALLOC_APPEND ( l , fd_peer_dlist_align (),        fd_peer_dlist_footprint        (             ) );
34+   void  *         peers_worst  =  FD_SCRATCH_ALLOC_APPEND ( l , fd_peer_dlist_align (),        fd_peer_dlist_footprint        (             ) );
3435  FD_TEST ( FD_SCRATCH_ALLOC_FINI ( l , fd_policy_align () ) ==  (ulong )shmem  +  footprint  );
3536
3637  policy -> dedup .map      =  fd_policy_dedup_map_new  ( dedup_map ,  dedup_max , seed  );
3738  policy -> dedup .pool     =  fd_policy_dedup_pool_new ( dedup_pool , dedup_max        );
3839  policy -> dedup .lru      =  fd_policy_dedup_lru_new  ( dedup_lru                    );
3940  policy -> peers .map      =  fd_policy_peer_map_new   ( peers ,      lg_peer_max      );
4041  policy -> peers .pool     =  fd_peer_pool_new         ( peers_pool , peer_max         );
41-   policy -> peers .dlist    =  fd_peer_dlist_new        ( peers_dlist                  );
42+   policy -> peers .best     =  fd_peer_dlist_new        ( peers_best                   );
43+   policy -> peers .worst    =  fd_peer_dlist_new        ( peers_worst                  );
4244  policy -> iterf .ele_idx  =  ULONG_MAX ;
4345  policy -> turbine_slot0  =  ULONG_MAX ;
4446  policy -> tsreset        =  0 ;
@@ -72,8 +74,11 @@ fd_policy_join( void * shpolicy ) {
7274  policy -> dedup .lru    =  fd_policy_dedup_lru_join  ( policy -> dedup .lru    );
7375  policy -> peers .map    =  fd_policy_peer_map_join   ( policy -> peers .map    );
7476  policy -> peers .pool   =  fd_peer_pool_join         ( policy -> peers .pool   );
75-   policy -> peers .dlist  =  fd_peer_dlist_join        ( policy -> peers .dlist  );
76-   policy -> peers .iter   =  fd_peer_dlist_iter_fwd_init ( policy -> peers .dlist , policy -> peers .pool  );
77+   policy -> peers .best   =  fd_peer_dlist_join        ( policy -> peers .best   );
78+   policy -> peers .worst  =  fd_peer_dlist_join        ( policy -> peers .worst  );
79+ 
80+   policy -> peers .select .iter   =  fd_peer_dlist_iter_fwd_init ( policy -> peers .worst , policy -> peers .pool  );
81+   policy -> peers .select .stage  =  0 ;
7782
7883  return  policy ;
7984}
@@ -127,7 +132,7 @@ dedup_next( fd_policy_t * policy, ulong key, long now ) {
127132    fd_policy_dedup_map_ele_insert    ( dedup -> map , ele , dedup -> pool  );
128133    fd_policy_dedup_lru_ele_push_tail ( dedup -> lru , ele , dedup -> pool  );
129134  }
130-   if ( FD_LIKELY ( now  <  ele -> req_ts  +  (long )80e6  ) ) {
135+   if ( FD_LIKELY ( now  <  ele -> req_ts  +  (long )FD_POLICY_DEDUP_TIMEOUT  ) ) {
131136    return  1 ;
132137  }
133138  ele -> req_ts  =  now ;
@@ -156,13 +161,19 @@ passes_throttle_threshold( fd_policy_t * policy, fd_forest_blk_t * ele ) {
156161
157162fd_pubkey_t  const  * 
158163fd_policy_peer_select ( fd_policy_t  *  policy  ) {
159-   fd_peer_dlist_t  *  dlist  =  policy -> peers .dlist ;
160-   fd_peer_t        *  pool   =  policy -> peers .pool ;
161-   if ( FD_UNLIKELY ( fd_peer_dlist_iter_done ( policy -> peers .iter , dlist , pool  ) ) ) {
162-     policy -> peers .iter  =  fd_peer_dlist_iter_fwd_init ( dlist , pool  );
164+   fd_peer_dlist_t  *  best_dlist   =  policy -> peers .best ;
165+   fd_peer_dlist_t  *  worst_dlist  =  policy -> peers .worst ;
166+   fd_peer_t        *  pool         =  policy -> peers .pool ;
167+ 
168+   fd_peer_dlist_t  *  dlist  =  bucket_stages [policy -> peers .select .stage ] ==  FD_POLICY_LATENCY_BEST  ? best_dlist  : worst_dlist ;
169+ 
170+   while ( FD_UNLIKELY ( fd_peer_dlist_iter_done ( policy -> peers .select .iter , dlist , pool  ) ) ) {
171+     policy -> peers .select .stage  =  (policy -> peers .select .stage  +  1 ) % (sizeof (bucket_stages ) / sizeof (uint ));
172+     dlist  =  bucket_stages [policy -> peers .select .stage ] ==  FD_POLICY_LATENCY_BEST  ? best_dlist  : worst_dlist ;
173+     policy -> peers .select .iter  =  fd_peer_dlist_iter_fwd_init ( dlist , pool  );
163174  }
164-   fd_peer_t  *  select  =  fd_peer_dlist_iter_ele ( policy -> peers .iter , dlist , pool  );
165-   policy -> peers .iter  =  fd_peer_dlist_iter_fwd_next ( policy -> peers .iter , dlist , pool  );
175+   fd_peer_t  *  select  =  fd_peer_dlist_iter_ele ( policy -> peers .select . iter , dlist , pool  );
176+   policy -> peers .select . iter  =  fd_peer_dlist_iter_fwd_next ( policy -> peers . select .iter , dlist , pool  );
166177  return  & select -> identity ;
167178}
168179
@@ -294,7 +305,7 @@ fd_policy_peer_insert( fd_policy_t * policy, fd_pubkey_t const * key, fd_ip4_por
294305    fd_peer_t  *  peer_ele  =  fd_peer_pool_ele_acquire ( policy -> peers .pool  );
295306    peer -> pool_idx  =  fd_peer_pool_idx ( policy -> peers .pool , peer_ele  );
296307    peer_ele -> identity  =  * key ;
297-     fd_peer_dlist_ele_push_tail ( policy -> peers .dlist , peer_ele , policy -> peers .pool  );
308+     fd_peer_dlist_ele_push_tail ( policy -> peers .worst , peer_ele , policy -> peers .pool  );
298309    return  peer ;
299310  }
300311  return  NULL ;
@@ -312,11 +323,14 @@ fd_policy_peer_remove( fd_policy_t * policy, fd_pubkey_t const * key ) {
312323  fd_peer_t  *  peer_ele  =  fd_peer_pool_ele ( policy -> peers .pool , peer -> pool_idx  );
313324  fd_policy_peer_map_remove ( policy -> peers .map , peer  );
314325
315-   if ( FD_UNLIKELY ( policy -> peers .iter  ==  fd_peer_pool_idx ( policy -> peers .pool , peer_ele  ) ) ) {
326+   if ( FD_UNLIKELY ( policy -> peers .select . iter  ==  fd_peer_pool_idx ( policy -> peers .pool , peer_ele  ) ) ) {
316327    /* In general removal during iteration is safe, except when the iterator is on the peer to be removed. */ 
317-     policy -> peers .iter  =  fd_peer_dlist_iter_fwd_next ( policy -> peers .iter , policy -> peers .dlist , policy -> peers .pool  );
328+     fd_peer_dlist_t  *  dlist  =  policy -> peers .select .stage  ==  FD_POLICY_LATENCY_BEST  ? policy -> peers .best  : policy -> peers .worst ;
329+     policy -> peers .select .iter  =  fd_peer_dlist_iter_fwd_next ( policy -> peers .select .iter , dlist , policy -> peers .pool  );
318330  }
319-   fd_peer_dlist_ele_remove ( policy -> peers .dlist , peer_ele , policy -> peers .pool  );
331+ 
332+   fd_peer_dlist_t  *  bucket  =  fd_policy_peer_latency_bucket ( policy , peer -> total_lat , peer -> res_cnt  );
333+   fd_peer_dlist_ele_remove ( bucket , peer_ele , policy -> peers .pool  );
320334  fd_peer_pool_ele_release ( policy -> peers .pool , peer_ele  );
321335  return  1 ;
322336}
@@ -332,14 +346,22 @@ fd_policy_peer_request_update( fd_policy_t * policy, fd_pubkey_t const * to ) {
332346}
333347
334348void 
335- fd_policy_peer_response_update ( fd_policy_t  *  policy , fd_pubkey_t  const  *  to , long  rtt  ) {
349+ fd_policy_peer_response_update ( fd_policy_t  *  policy , fd_pubkey_t  const  *  to , long  rtt  /* ns */   ) {
336350  fd_policy_peer_t  *  peer  =  fd_policy_peer_query ( policy , to  );
337351  if ( FD_LIKELY ( peer  ) ) {
338352    long  now  =  fd_tickcount ();
353+     fd_peer_dlist_t  *  prev_bucket  =  fd_policy_peer_latency_bucket ( policy , peer -> total_lat , peer -> res_cnt  );
339354    peer -> res_cnt ++ ;
340355    if ( FD_UNLIKELY ( peer -> first_resp_ts  ==  0  ) ) peer -> first_resp_ts  =  now ;
341356    peer -> last_resp_ts  =  now ;
342357    peer -> total_lat    +=  rtt ;
358+     fd_peer_dlist_t  *  new_bucket  =  fd_policy_peer_latency_bucket ( policy , peer -> total_lat , peer -> res_cnt   );
359+ 
360+     if ( prev_bucket  !=  new_bucket  ) {
361+       fd_peer_t  *  peer_ele  =  fd_peer_pool_ele ( policy -> peers .pool , peer -> pool_idx  );
362+       fd_peer_dlist_ele_remove    ( prev_bucket , peer_ele , policy -> peers .pool  );
363+       fd_peer_dlist_ele_push_tail ( new_bucket ,  peer_ele , policy -> peers .pool  );
364+     }
343365  }
344366}
345367
0 commit comments