Line data Source code
1 : #include "fd_vote_tracker.h" 2 : 3 0 : #define VOTE_TRACKER_MAX (512UL) 4 : 5 : struct fd_vote_tracker_ele { 6 : fd_signature_t vote_sig; 7 : ulong next_; /* Internal pool/map use */ 8 : }; 9 : typedef struct fd_vote_tracker_ele fd_vote_tracker_ele_t; 10 : 11 : #define DEQUE_NAME fd_vote_tracker_deq 12 0 : #define DEQUE_T fd_vote_tracker_ele_t 13 0 : #define DEQUE_MAX 512 /* must be a power of 2 */ 14 : #include "../../util/tmpl/fd_deque.c" 15 : 16 : #define MAP_NAME fd_vote_tracker_map 17 : #define MAP_ELE_T fd_vote_tracker_ele_t 18 : #define MAP_KEY_T fd_signature_t 19 0 : #define MAP_KEY vote_sig 20 0 : #define MAP_NEXT next_ 21 0 : #define MAP_KEY_EQ(k0,k1) fd_signature_eq( (k0), (k1) ) 22 0 : #define MAP_KEY_HASH(k,s) fd_hash( s, (k)->uc, sizeof(fd_signature_t) ) 23 : #include "../../util/tmpl/fd_map_chain.c" 24 : 25 : struct fd_vote_tracker { 26 : ulong magic; 27 : ulong deq_offset; 28 : ulong map_offset; 29 : }; 30 : typedef struct fd_vote_tracker fd_vote_tracker_t; 31 : 32 : static inline fd_vote_tracker_ele_t * 33 0 : fd_vote_tracker_deq_get( fd_vote_tracker_t * vote_tracker ) { 34 0 : return fd_vote_tracker_deq_join( (uchar *)vote_tracker + vote_tracker->deq_offset ); 35 0 : } 36 : 37 : static inline fd_vote_tracker_map_t * 38 0 : fd_vote_tracker_map_get( fd_vote_tracker_t * vote_tracker ) { 39 0 : return fd_vote_tracker_map_join( (uchar *)vote_tracker + vote_tracker->map_offset ); 40 0 : } 41 : 42 : ulong 43 0 : fd_vote_tracker_align( void ) { 44 0 : return fd_ulong_max( fd_ulong_max( fd_vote_tracker_map_align(), fd_vote_tracker_deq_align() ), alignof(fd_vote_tracker_t) ); 45 0 : } 46 : 47 : ulong 48 0 : fd_vote_tracker_footprint( void ) { 49 0 : ulong map_chain_cnt = fd_vote_tracker_map_chain_cnt_est( VOTE_TRACKER_MAX ); 50 0 : ulong l = FD_LAYOUT_INIT; 51 0 : l = FD_LAYOUT_APPEND( l, fd_vote_tracker_align(), sizeof(fd_vote_tracker_t) ); 52 0 : l = FD_LAYOUT_APPEND( l, fd_vote_tracker_deq_align(), fd_vote_tracker_deq_footprint() ); 53 0 : l = FD_LAYOUT_APPEND( l, fd_vote_tracker_map_align(), fd_vote_tracker_map_footprint( map_chain_cnt ) ); 54 0 : return FD_LAYOUT_FINI( l, fd_vote_tracker_align() ); 55 0 : } 56 : 57 : void * 58 0 : fd_vote_tracker_new( void * mem, ulong seed ) { 59 0 : if( FD_UNLIKELY( !mem ) ) { 60 0 : FD_LOG_WARNING(( "NULL mem" )); 61 0 : return NULL; 62 0 : } 63 : 64 0 : if( FD_UNLIKELY( !fd_ulong_is_aligned( (ulong)mem, fd_vote_tracker_align() ) ) ) { 65 0 : FD_LOG_WARNING(( "misaligned mem" )); 66 0 : return NULL; 67 0 : } 68 : 69 0 : ulong map_chain_cnt = fd_vote_tracker_map_chain_cnt_est( VOTE_TRACKER_MAX ); 70 : 71 0 : FD_SCRATCH_ALLOC_INIT( l, mem ); 72 0 : fd_vote_tracker_t * vote_tracker = FD_SCRATCH_ALLOC_APPEND( l, fd_vote_tracker_align(), sizeof(fd_vote_tracker_t) ); 73 0 : void * deq_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_vote_tracker_deq_align(), fd_vote_tracker_deq_footprint() ); 74 0 : void * map_mem = FD_SCRATCH_ALLOC_APPEND( l, fd_vote_tracker_map_align(), fd_vote_tracker_map_footprint( map_chain_cnt ) ); 75 : 76 0 : if( FD_UNLIKELY( FD_SCRATCH_ALLOC_FINI( l, fd_vote_tracker_align() )!=(ulong)mem+fd_vote_tracker_footprint() ) ) { 77 0 : FD_LOG_WARNING(( "fd_vote_tracker_new: bad layout" )); 78 0 : return NULL; 79 0 : } 80 : 81 0 : if( FD_UNLIKELY( !fd_vote_tracker_deq_new( deq_mem ) ) ) { 82 0 : FD_LOG_WARNING(( "fd_vote_tracker_new: bad deq" )); 83 0 : return NULL; 84 0 : } 85 : 86 0 : if( FD_UNLIKELY( !fd_vote_tracker_map_new( map_mem, map_chain_cnt, seed ) ) ) { 87 0 : FD_LOG_WARNING(( "fd_vote_tracker_new: bad map" )); 88 0 : return NULL; 89 0 : } 90 : 91 0 : vote_tracker->deq_offset = (ulong)deq_mem - (ulong)mem; 92 0 : vote_tracker->map_offset = (ulong)map_mem - (ulong)mem; 93 : 94 0 : return vote_tracker; 95 : 96 0 : } 97 : 98 : fd_vote_tracker_t * 99 0 : fd_vote_tracker_join( void * mem ) { 100 0 : return (fd_vote_tracker_t *)mem; 101 0 : } 102 : 103 : void 104 : fd_vote_tracker_insert( fd_vote_tracker_t * vote_tracker, 105 0 : fd_signature_t const * vote_sig ) { 106 0 : fd_vote_tracker_ele_t * deq = fd_vote_tracker_deq_get( vote_tracker ); 107 0 : fd_vote_tracker_map_t * map = fd_vote_tracker_map_get( vote_tracker ); 108 0 : if( fd_vote_tracker_deq_full( deq ) ) { 109 0 : fd_vote_tracker_ele_t * ele = fd_vote_tracker_deq_pop_head_nocopy( deq ); 110 0 : fd_vote_tracker_map_ele_remove( map, &ele->vote_sig, NULL, deq ); 111 0 : } 112 0 : fd_vote_tracker_ele_t * ele = fd_vote_tracker_deq_push_tail_nocopy( deq ); 113 0 : ele->vote_sig = *vote_sig; 114 0 : fd_vote_tracker_map_ele_insert( map, ele, deq ); 115 0 : } 116 : 117 : int 118 : fd_vote_tracker_query_sig( fd_vote_tracker_t * vote_tracker, 119 0 : fd_signature_t const * vote_sig ) { 120 0 : fd_vote_tracker_ele_t * deq = fd_vote_tracker_deq_get( vote_tracker ); 121 0 : fd_vote_tracker_map_t * map = fd_vote_tracker_map_get( vote_tracker ); 122 0 : return fd_vote_tracker_map_ele_query( map, vote_sig, NULL, deq )!=NULL; 123 0 : }