@@ -10,9 +10,9 @@ struct blockcache {
1010 pointer is updated to the new item, and the new item is pointed to the previous head. */
1111 uint * pages ; /* A list of the txnpages containing the transactions for this blockcache. */
1212
13- uchar * descends ; /* Each fork can descend from other forks in the txncache, and this array contains one value
14- for each fork in the txncache. If this fork descends from the fork at position id,
15- then descends[ id ] will be 1, otherwise 1 . */
13+ descends_set_t * descends ; /* Each fork can descend from other forks in the txncache, and this bit vector contains one
14+ value for each fork in the txncache. If this fork descends from some other fork F, then
15+ the bit at index F in descends[] is set . */
1616};
1717
1818typedef struct blockcache blockcache_t ;
@@ -67,13 +67,19 @@ fd_txncache_new( void * ljoin,
6767 ushort _max_txnpages = fd_txncache_max_txnpages ( max_active_slots , shmem -> txn_per_slot_max );
6868 ushort _max_txnpages_per_blockhash = fd_txncache_max_txnpages_per_blockhash ( max_active_slots , shmem -> txn_per_slot_max );
6969
70+ ulong _descends_footprint = descends_set_footprint ( max_active_slots );
71+ if ( FD_UNLIKELY ( !_descends_footprint ) ) {
72+ FD_LOG_WARNING (( "invalid max_active_slots" ));
73+ return NULL ;
74+ }
75+
7076 FD_SCRATCH_ALLOC_INIT ( l , shmem );
7177 fd_txncache_shmem_t * tc = FD_SCRATCH_ALLOC_APPEND ( l , FD_TXNCACHE_SHMEM_ALIGN , sizeof (fd_txncache_shmem_t ) );
7278 void * _blockhash_map = FD_SCRATCH_ALLOC_APPEND ( l , blockhash_map_align (), blockhash_map_footprint ( blockhash_map_chains ) );
7379 void * _blockcache_pool = FD_SCRATCH_ALLOC_APPEND ( l , blockcache_pool_align (), blockcache_pool_footprint ( max_active_slots ) );
7480 void * _blockcache_pages = FD_SCRATCH_ALLOC_APPEND ( l , alignof(uint ), max_active_slots * _max_txnpages_per_blockhash * sizeof (uint ) );
7581 void * _blockcache_heads = FD_SCRATCH_ALLOC_APPEND ( l , alignof(uint ), max_active_slots * shmem -> txn_per_slot_max * sizeof (uint ) );
76- void * _blockcache_descends = FD_SCRATCH_ALLOC_APPEND ( l , alignof( uchar ), max_active_slots * max_active_slots * sizeof ( uchar ) );
82+ void * _blockcache_descends = FD_SCRATCH_ALLOC_APPEND ( l , descends_set_align ( ), max_active_slots * _descends_footprint );
7783 void * _txnpages_free = FD_SCRATCH_ALLOC_APPEND ( l , alignof(ushort ), _max_txnpages * sizeof (ushort ) );
7884 void * _txnpages = FD_SCRATCH_ALLOC_APPEND ( l , alignof(fd_txncache_txnpage_t ), _max_txnpages * sizeof (fd_txncache_txnpage_t ) );
7985
@@ -87,10 +93,11 @@ fd_txncache_new( void * ljoin,
8793 ltc -> blockcache_shmem_pool = blockcache_pool_join ( _blockcache_pool );
8894
8995 for ( ulong i = 0UL ; i < shmem -> active_slots_max ; i ++ ) {
90- ltc -> blockcache_pool [ i ].pages = (uint * )_blockcache_pages + i * _max_txnpages_per_blockhash ;
91- ltc -> blockcache_pool [ i ].heads = (uint * )_blockcache_heads + i * shmem -> txn_per_slot_max ;
92- ltc -> blockcache_pool [ i ].descends = (uchar * )_blockcache_descends + i * max_active_slots ;
93- ltc -> blockcache_pool [ i ].shmem = ltc -> blockcache_shmem_pool + i ;
96+ ltc -> blockcache_pool [ i ].pages = (uint * )_blockcache_pages + i * _max_txnpages_per_blockhash ;
97+ ltc -> blockcache_pool [ i ].heads = (uint * )_blockcache_heads + i * shmem -> txn_per_slot_max ;
98+ ltc -> blockcache_pool [ i ].descends = descends_set_join ( (uchar * )_blockcache_descends + i * _descends_footprint );
99+ ltc -> blockcache_pool [ i ].shmem = ltc -> blockcache_shmem_pool + i ;
100+ FD_TEST ( ltc -> blockcache_pool [ i ].shmem );
94101 }
95102
96103 FD_TEST ( ltc -> blockcache_shmem_pool );
@@ -231,7 +238,7 @@ fd_txncache_attach_child( fd_txncache_t * tc,
231238 fork -> shmem -> parent_id = (fd_txncache_fork_id_t ){ .val = USHORT_MAX };
232239 fork -> shmem -> sibling_id = (fd_txncache_fork_id_t ){ .val = USHORT_MAX };
233240
234- fd_memset ( fork -> descends , 0 , tc -> shmem -> active_slots_max * sizeof ( uchar ) );
241+ descends_set_null ( fork -> descends );
235242 root_slist_ele_push_tail ( tc -> shmem -> root_ll , fork -> shmem , tc -> blockcache_shmem_pool );
236243 } else {
237244 blockcache_t * parent = & tc -> blockcache_pool [ parent_fork_id .val ];
@@ -244,8 +251,8 @@ fd_txncache_attach_child( fd_txncache_t * tc,
244251 fork -> shmem -> parent_id = parent_fork_id ;
245252 parent -> shmem -> child_id = fork_id ;
246253
247- fd_memcpy ( fork -> descends , parent -> descends , tc -> shmem -> active_slots_max * sizeof ( uchar ) );
248- fork -> descends [ parent_fork_id .val ] = 1 ;
254+ descends_set_copy ( fork -> descends , parent -> descends );
255+ descends_set_insert ( fork -> descends , parent_fork_id .val ) ;
249256 }
250257
251258 fork -> shmem -> txnhash_offset = 0UL ;
@@ -301,7 +308,7 @@ remove_blockcache( fd_txncache_t * tc,
301308 tc -> shmem -> txnpages_free_cnt = (ushort )(tc -> shmem -> txnpages_free_cnt + blockcache -> shmem -> pages_cnt );
302309
303310 ulong idx = blockcache_pool_idx ( tc -> blockcache_shmem_pool , blockcache -> shmem );
304- for ( ulong i = 0UL ; i < tc -> shmem -> active_slots_max ; i ++ ) tc -> blockcache_pool [ i ].descends [ idx ] = 0 ;
311+ for ( ulong i = 0UL ; i < tc -> shmem -> active_slots_max ; i ++ ) descends_set_remove ( tc -> blockcache_pool [ i ].descends , idx ) ;
305312
306313 blockhash_map_ele_remove_fast ( tc -> blockhash_map , blockcache -> shmem , tc -> blockcache_shmem_pool );
307314 blockcache_pool_ele_release ( tc -> blockcache_shmem_pool , blockcache -> shmem );
@@ -377,7 +384,7 @@ blockhash_on_fork( fd_txncache_t * tc,
377384
378385 while ( candidate ) {
379386 ulong candidate_idx = blockcache_pool_idx ( tc -> blockcache_shmem_pool , candidate );
380- if ( FD_LIKELY ( fork -> descends [ candidate_idx ] ) ) return & tc -> blockcache_pool [ candidate_idx ];
387+ if ( FD_LIKELY ( descends_set_test ( fork -> descends , candidate_idx ) ) ) return & tc -> blockcache_pool [ candidate_idx ];
381388 candidate = blockhash_map_ele_next_const ( candidate , NULL , tc -> blockcache_shmem_pool );
382389 }
383390 return NULL ;
@@ -434,7 +441,7 @@ fd_txncache_query( fd_txncache_t * tc,
434441 for ( uint head = blockcache -> heads [ head_hash ]; head != UINT_MAX ; head = tc -> txnpages [ head /FD_TXNCACHE_TXNS_PER_PAGE ].txns [ head %FD_TXNCACHE_TXNS_PER_PAGE ]-> blockcache_next ) {
435442 fd_txncache_single_txn_t * txn = tc -> txnpages [ head /FD_TXNCACHE_TXNS_PER_PAGE ].txns [ head %FD_TXNCACHE_TXNS_PER_PAGE ];
436443
437- int descends = txn -> fork_id .val == fork_id .val || fork -> descends [ txn -> fork_id .val ] ;
444+ int descends = txn -> fork_id .val == fork_id .val || descends_set_test ( fork -> descends , txn -> fork_id .val ) ;
438445 if ( FD_LIKELY ( descends && !memcmp ( txnhash + txnhash_offset , txn -> txnhash , 20UL ) ) ) {
439446 found = 1 ;
440447 break ;
0 commit comments