Line data Source code
1 : #ifndef HEADER_fd_src_funk_test_funk_common_h 2 : #define HEADER_fd_src_funk_test_funk_common_h 3 : 4 : /* "Mini-funk" implementation for reference and testing purposes */ 5 : 6 : #include "fd_funk_base.h" 7 : 8 : struct txn; 9 : typedef struct txn txn_t; 10 : 11 : struct rec; 12 : typedef struct rec rec_t; 13 : 14 : struct rec { 15 : txn_t * txn; 16 : ulong key; 17 : rec_t * prev; 18 : rec_t * next; 19 : rec_t * map_prev; 20 : rec_t * map_next; 21 : int erase; 22 : uint val; 23 : }; 24 : 25 : struct txn { 26 : ulong xid; 27 : txn_t * parent; 28 : txn_t * child_head; 29 : txn_t * child_tail; 30 : txn_t * sibling_prev; 31 : txn_t * sibling_next; 32 : txn_t * map_prev; 33 : txn_t * map_next; 34 : rec_t * rec_head; 35 : rec_t * rec_tail; 36 : }; 37 : 38 : struct funk { 39 : ulong last_publish; 40 : txn_t * child_head; 41 : txn_t * child_tail; 42 : txn_t * txn_map_head; 43 : txn_t * txn_map_tail; 44 : ulong txn_cnt; 45 : rec_t * rec_head; 46 : rec_t * rec_tail; 47 : rec_t * rec_map_head; 48 : rec_t * rec_map_tail; 49 : ulong rec_cnt; 50 : }; 51 : 52 : typedef struct funk funk_t; 53 : 54 : FD_PROTOTYPES_BEGIN 55 : 56 : /* Mini txn API */ 57 : 58 44651988 : FD_FN_PURE static inline int txn_is_frozen( txn_t * txn ) { return !!txn->child_head; } 59 : 60 146969397 : FD_FN_PURE static inline int txn_is_only_child( txn_t * txn ) { return !txn->sibling_prev && !txn->sibling_next; } 61 : 62 : FD_FN_PURE static inline txn_t * 63 42528654 : txn_ancestor( txn_t * txn ) { 64 56997111 : for(;;) { 65 56997111 : if( !txn_is_only_child( txn ) ) break; 66 15218796 : if( !txn->parent ) return NULL; 67 14468457 : txn = txn->parent; 68 14468457 : } 69 41778315 : return txn; 70 42528654 : } 71 : 72 : FD_FN_PURE static inline txn_t * 73 42528654 : txn_descendant( txn_t * txn ) { 74 42528654 : if( !txn_is_only_child( txn ) ) return NULL; 75 15218796 : for(;;) { 76 15218796 : if( !txn->child_head || !txn_is_only_child( txn->child_head ) ) break; 77 3350406 : txn = txn->child_head; 78 3350406 : } 79 11868390 : return txn; 80 42528654 : } 81 : 82 : txn_t * 83 : txn_prepare( funk_t * funk, 84 : txn_t * parent, 85 : ulong xid ); 86 : 87 : void 88 : txn_cancel( funk_t * funk, 89 : txn_t * txn ); 90 : 91 : ulong 92 : txn_publish( funk_t * funk, 93 : txn_t * txn, 94 : ulong cnt ); 95 : 96 : /* 97 : void 98 : txn_merge( funk_t * funk, 99 : txn_t * txn ); 100 : */ 101 : 102 : static inline txn_t * 103 : txn_cancel_children( funk_t * funk, 104 279372 : txn_t * txn ) { 105 279372 : txn_t * child = txn ? txn->child_head : funk->child_head; 106 458859 : while( child ) { 107 179487 : txn_t * next = child->sibling_next; 108 179487 : txn_cancel( funk, child ); 109 179487 : child = next; 110 179487 : } 111 279372 : return txn; 112 279372 : } 113 : 114 : static inline txn_t * 115 : txn_cancel_siblings( funk_t * funk, 116 49641 : txn_t * txn ) { 117 49641 : txn_t * child = txn->parent ? txn->parent->child_head : funk->child_head; 118 177276 : while( child ) { 119 127635 : txn_t * next = child->sibling_next; 120 127635 : if( child!=txn ) txn_cancel( funk, child ); 121 127635 : child = next; 122 127635 : } 123 49641 : return txn; 124 49641 : } 125 : 126 : /* Mini rec API */ 127 : 128 : FD_FN_PURE rec_t * 129 : rec_query( funk_t * funk, 130 : txn_t * txn, 131 : ulong key ); 132 : 133 : FD_FN_PURE rec_t * 134 : rec_query_global( funk_t * funk, 135 : txn_t * txn, 136 : ulong key ); 137 : 138 : rec_t * 139 : rec_insert( funk_t * funk, 140 : txn_t * txn, 141 : ulong key ); 142 : 143 : /* Mini funk API */ 144 : 145 : funk_t * 146 : funk_new( void ); 147 : 148 : void 149 : funk_delete( funk_t * funk ); 150 : 151 4553349 : static inline int funk_is_frozen( funk_t * funk ) { return !!funk->child_head; } 152 : 153 : FD_FN_PURE static inline txn_t * 154 0 : funk_descendant( funk_t * funk ) { 155 0 : return funk->child_head ? txn_descendant( funk->child_head ) : NULL; 156 0 : } 157 : 158 : /* Testing utilities */ 159 : 160 : ulong 161 : xid_unique( void ); 162 : 163 : __attribute__((noinline)) static fd_funk_txn_xid_t * 164 : xid_set( fd_funk_txn_xid_t * xid, 165 1438476000 : ulong _xid ) { 166 1438476000 : xid->ul[0] = _xid; xid->ul[1] = _xid; 167 1438476000 : return xid; 168 1438476000 : } 169 : 170 : FD_FN_PURE static inline int 171 : xid_eq( fd_funk_txn_xid_t const * xid, 172 756892938 : ulong _xid ) { 173 756892938 : fd_funk_txn_xid_t tmp[1]; 174 756892938 : return fd_funk_txn_xid_eq( xid, xid_set( tmp, _xid ) ); 175 756892938 : } 176 : 177 : __attribute__((noinline)) static FD_FN_UNUSED fd_funk_rec_key_t * 178 : key_set( fd_funk_rec_key_t * key, 179 1183655148 : ulong _key ) { 180 1183655148 : key->ul[0] = _key; key->ul[1] = _key+_key; key->ul[2] = _key*_key; key->ul[3] = -_key; 181 1183655148 : key->ul[4] = _key*3U; 182 1183655148 : return key; 183 1183655148 : } 184 : 185 : FD_FN_PURE int 186 : key_eq( fd_funk_rec_key_t const * key, 187 : ulong _key ); 188 : 189 : FD_PROTOTYPES_END 190 : 191 : #endif /* HEADER_fd_src_funk_test_funk_common_h */