1
1
#include "fd_funk.h"
2
+ #include "fd_funk_txn.h"
2
3
3
4
/* Provide the actual record map implementation */
4
5
@@ -222,6 +223,7 @@ fd_funk_rec_prepare( fd_funk_t * funk,
222
223
return NULL ;
223
224
}
224
225
#endif
226
+ memset ( prepare , 0 , sizeof (fd_funk_rec_prepare_t ) );
225
227
226
228
if ( !txn ) { /* Modifying last published */
227
229
if ( FD_UNLIKELY ( fd_funk_last_publish_is_frozen ( funk ) ) ) {
@@ -239,30 +241,28 @@ fd_funk_rec_prepare( fd_funk_t * funk,
239
241
if ( opt_err && * opt_err == FD_POOL_ERR_CORRUPT ) {
240
242
FD_LOG_ERR (( "corrupt element returned from funk rec pool" ));
241
243
}
242
-
243
- if ( rec != NULL ) {
244
- fd_funk_val_init ( rec );
245
- if ( txn == NULL ) {
246
- fd_funk_txn_xid_set_root ( rec -> pair .xid );
247
- rec -> txn_cidx = fd_funk_txn_cidx ( FD_FUNK_TXN_IDX_NULL );
248
- prepare -> rec_head_idx = & funk -> shmem -> rec_head_idx ;
249
- prepare -> rec_tail_idx = & funk -> shmem -> rec_tail_idx ;
250
- prepare -> txn_lock = & funk -> shmem -> lock ;
251
- } else {
252
- fd_funk_txn_xid_copy ( rec -> pair .xid , & txn -> xid );
253
- rec -> txn_cidx = fd_funk_txn_cidx ( (ulong )( txn - funk -> txn_pool -> ele ) );
254
- prepare -> rec_head_idx = & txn -> rec_head_idx ;
255
- prepare -> rec_tail_idx = & txn -> rec_tail_idx ;
256
- prepare -> txn_lock = & txn -> lock ;
257
- }
258
- fd_funk_rec_key_copy ( rec -> pair .key , key );
259
- rec -> tag = 0 ;
260
- rec -> flags = 0 ;
261
- rec -> prev_idx = FD_FUNK_REC_IDX_NULL ;
262
- rec -> next_idx = FD_FUNK_REC_IDX_NULL ;
263
- } else {
244
+ if ( FD_UNLIKELY ( !rec ) ) {
264
245
fd_int_store_if ( !!opt_err , opt_err , FD_FUNK_ERR_REC );
246
+ return rec ;
265
247
}
248
+
249
+ fd_funk_val_init ( rec );
250
+ if ( txn == NULL ) {
251
+ fd_funk_txn_xid_set_root ( rec -> pair .xid );
252
+ rec -> txn_cidx = fd_funk_txn_cidx ( FD_FUNK_TXN_IDX_NULL );
253
+ prepare -> txn_lock = & funk -> shmem -> lock ;
254
+ } else {
255
+ fd_funk_txn_xid_copy ( rec -> pair .xid , & txn -> xid );
256
+ rec -> txn_cidx = fd_funk_txn_cidx ( (ulong )( txn - funk -> txn_pool -> ele ) );
257
+ prepare -> rec_head_idx = & txn -> rec_head_idx ;
258
+ prepare -> rec_tail_idx = & txn -> rec_tail_idx ;
259
+ prepare -> txn_lock = & txn -> lock ;
260
+ }
261
+ fd_funk_rec_key_copy ( rec -> pair .key , key );
262
+ rec -> tag = 0 ;
263
+ rec -> flags = 0 ;
264
+ rec -> prev_idx = FD_FUNK_REC_IDX_NULL ;
265
+ rec -> next_idx = FD_FUNK_REC_IDX_NULL ;
266
266
return rec ;
267
267
}
268
268
@@ -276,16 +276,17 @@ fd_funk_rec_publish( fd_funk_t * funk,
276
276
/* Lock the txn */
277
277
while ( FD_ATOMIC_CAS ( prepare -> txn_lock , 0 , 1 ) ) FD_SPIN_PAUSE ();
278
278
279
- uint rec_prev_idx ;
280
- uint rec_idx = (uint )( rec - funk -> rec_pool -> ele );
281
- rec_prev_idx = * rec_tail_idx ;
282
- * rec_tail_idx = rec_idx ;
283
- rec -> prev_idx = rec_prev_idx ;
284
- rec -> next_idx = FD_FUNK_REC_IDX_NULL ;
285
- if ( fd_funk_rec_idx_is_null ( rec_prev_idx ) ) {
286
- * rec_head_idx = rec_idx ;
287
- } else {
288
- funk -> rec_pool -> ele [ rec_prev_idx ].next_idx = rec_idx ;
279
+ if ( rec_head_idx ) {
280
+ uint rec_idx = (uint )( rec - funk -> rec_pool -> ele );
281
+ uint rec_prev_idx = * rec_tail_idx ;
282
+ * rec_tail_idx = rec_idx ;
283
+ rec -> prev_idx = rec_prev_idx ;
284
+ rec -> next_idx = FD_FUNK_REC_IDX_NULL ;
285
+ if ( fd_funk_rec_idx_is_null ( rec_prev_idx ) ) {
286
+ * rec_head_idx = rec_idx ;
287
+ } else {
288
+ funk -> rec_pool -> ele [ rec_prev_idx ].next_idx = rec_idx ;
289
+ }
289
290
}
290
291
291
292
if ( fd_funk_rec_map_insert ( funk -> rec_map , rec , FD_MAP_FLAG_BLOCKING ) ) {
@@ -601,7 +602,6 @@ fd_funk_rec_purify( fd_funk_t * funk ) {
601
602
fd_funk_rec_map_reset ( rec_map );
602
603
rec_pool -> pool -> ver_top = fd_funk_rec_pool_idx_null ();;
603
604
604
- uint prev_idx = FD_FUNK_REC_IDX_NULL ;
605
605
for ( ulong i = 0 ; i < rec_max ; ++ i ) {
606
606
fd_funk_rec_t * rec = rec_pool -> ele + i ;
607
607
if ( fd_funk_rec_pool_is_in_pool ( rec ) ||
@@ -619,21 +619,6 @@ fd_funk_rec_purify( fd_funk_t * funk ) {
619
619
rec_used_cnt ++ ;
620
620
621
621
fd_funk_rec_map_insert ( rec_map , rec , FD_MAP_FLAG_BLOCKING );
622
-
623
- rec -> prev_idx = prev_idx ;
624
- if ( prev_idx != FD_FUNK_REC_IDX_NULL ) {
625
- (rec_pool -> ele + prev_idx )-> next_idx = fd_funk_rec_map_private_cidx ( i );
626
- } else {
627
- funk -> shmem -> rec_head_idx = fd_funk_rec_map_private_cidx ( i );
628
- }
629
- prev_idx = fd_funk_rec_map_private_cidx ( i );
630
- }
631
-
632
- funk -> shmem -> rec_tail_idx = prev_idx ;
633
- if ( prev_idx != FD_FUNK_REC_IDX_NULL ) {
634
- (rec_pool -> ele + prev_idx )-> next_idx = FD_FUNK_REC_IDX_NULL ;
635
- } else {
636
- funk -> shmem -> rec_head_idx = FD_FUNK_REC_IDX_NULL ;
637
622
}
638
623
639
624
FD_LOG_NOTICE (( "funk records used after purify: %u, free: %u" , rec_used_cnt , rec_free_cnt ));
@@ -675,6 +660,9 @@ fd_funk_rec_verify( fd_funk_t * funk ) {
675
660
if ( fd_funk_txn_idx_is_null ( txn_idx ) ) { /* This is a record from the last published transaction */
676
661
677
662
TEST ( fd_funk_txn_xid_eq_root ( txn_xid ) );
663
+ /* No record linked list at the root txn */
664
+ TEST ( fd_funk_rec_idx_is_null ( rec -> prev_idx ) );
665
+ TEST ( fd_funk_rec_idx_is_null ( rec -> next_idx ) );
678
666
679
667
} else { /* This is a record from an in-prep transaction */
680
668
@@ -687,26 +675,20 @@ fd_funk_rec_verify( fd_funk_t * funk ) {
687
675
}
688
676
}
689
677
690
- /* Clear record tags and then verify the forward and reverse linkage */
678
+ /* Clear record tags and then verify membership */
691
679
692
680
for ( ulong rec_idx = 0UL ; rec_idx < rec_max ; rec_idx ++ ) rec_pool -> ele [ rec_idx ].tag = 0U ;
693
681
694
682
do {
695
- ulong txn_idx = FD_FUNK_TXN_IDX_NULL ;
696
- uint rec_idx = funk -> shmem -> rec_head_idx ;
697
- while ( !fd_funk_rec_idx_is_null ( rec_idx ) ) {
698
- TEST ( (rec_idx < rec_max ) && (fd_funk_txn_idx ( rec_pool -> ele [ rec_idx ].txn_cidx )== txn_idx ) && rec_pool -> ele [ rec_idx ].tag == 0U );
699
- rec_pool -> ele [ rec_idx ].tag = 1U ;
700
- fd_funk_rec_query_t query [1 ];
701
- fd_funk_rec_t const * rec2 = fd_funk_rec_query_try_global ( funk , NULL , rec_pool -> ele [ rec_idx ].pair .key , NULL , query );
702
- if ( FD_UNLIKELY ( rec_pool -> ele [ rec_idx ].flags & FD_FUNK_REC_FLAG_ERASE ) )
703
- TEST ( rec2 == NULL );
704
- else
705
- TEST ( rec2 == rec_pool -> ele + rec_idx );
706
- uint next_idx = rec_pool -> ele [ rec_idx ].next_idx ;
707
- if ( !fd_funk_rec_idx_is_null ( next_idx ) ) TEST ( rec_pool -> ele [ next_idx ].prev_idx == rec_idx );
708
- rec_idx = next_idx ;
683
+ fd_funk_all_iter_t iter [1 ];
684
+ for ( fd_funk_all_iter_new ( funk , iter ); !fd_funk_all_iter_done ( iter ); fd_funk_all_iter_next ( iter ) ) {
685
+ fd_funk_rec_t * rec = fd_funk_all_iter_ele ( iter );
686
+ if ( fd_funk_txn_xid_eq_root ( rec -> pair .xid ) ) {
687
+ TEST ( rec -> tag == 0U );
688
+ rec -> tag = 1U ;
689
+ }
709
690
}
691
+
710
692
fd_funk_txn_all_iter_t txn_iter [1 ];
711
693
for ( fd_funk_txn_all_iter_new ( funk , txn_iter ); !fd_funk_txn_all_iter_done ( txn_iter ); fd_funk_txn_all_iter_next ( txn_iter ) ) {
712
694
fd_funk_txn_t const * txn = fd_funk_txn_all_iter_ele_const ( txn_iter );
@@ -735,16 +717,6 @@ fd_funk_rec_verify( fd_funk_t * funk ) {
735
717
}
736
718
737
719
do {
738
- ulong txn_idx = FD_FUNK_TXN_IDX_NULL ;
739
- uint rec_idx = funk -> shmem -> rec_tail_idx ;
740
- while ( !fd_funk_rec_idx_is_null ( rec_idx ) ) {
741
- TEST ( (rec_idx < rec_max ) && (fd_funk_txn_idx ( rec_pool -> ele [ rec_idx ].txn_cidx )== txn_idx ) && rec_pool -> ele [ rec_idx ].tag == 1U );
742
- rec_pool -> ele [ rec_idx ].tag = 2U ;
743
- uint prev_idx = rec_pool -> ele [ rec_idx ].prev_idx ;
744
- if ( !fd_funk_rec_idx_is_null ( prev_idx ) ) TEST ( rec_pool -> ele [ prev_idx ].next_idx == rec_idx );
745
- rec_idx = prev_idx ;
746
- }
747
-
748
720
fd_funk_txn_all_iter_t txn_iter [1 ];
749
721
for ( fd_funk_txn_all_iter_new ( funk , txn_iter ); !fd_funk_txn_all_iter_done ( txn_iter ); fd_funk_txn_all_iter_next ( txn_iter ) ) {
750
722
fd_funk_txn_t const * txn = fd_funk_txn_all_iter_ele_const ( txn_iter );
0 commit comments