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 1794396 : FD_FN_PURE static inline int txn_is_frozen( txn_t * txn ) { return !!txn->child_head; } 59 : 60 0 : 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 0 : txn_ancestor( txn_t * txn ) { 64 0 : for(;;) { 65 0 : if( !txn_is_only_child( txn ) ) break; 66 0 : if( !txn->parent ) return NULL; 67 0 : txn = txn->parent; 68 0 : } 69 0 : return txn; 70 0 : } 71 : 72 : FD_FN_PURE static inline txn_t * 73 0 : txn_descendant( txn_t * txn ) { 74 0 : if( !txn_is_only_child( txn ) ) return NULL; 75 0 : for(;;) { 76 0 : if( !txn->child_head || !txn_is_only_child( txn->child_head ) ) break; 77 0 : txn = txn->child_head; 78 0 : } 79 0 : return txn; 80 0 : } 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 347049 : txn_t * txn ) { 105 347049 : txn_t * child = txn ? txn->child_head : funk->child_head; 106 516840 : while( child ) { 107 169791 : txn_t * next = child->sibling_next; 108 169791 : txn_cancel( funk, child ); 109 169791 : child = next; 110 169791 : } 111 347049 : return txn; 112 347049 : } 113 : 114 : static inline txn_t * 115 : txn_cancel_siblings( funk_t * funk, 116 224664 : txn_t * txn ) { 117 224664 : txn_t * child = txn->parent ? txn->parent->child_head : funk->child_head; 118 626583 : while( child ) { 119 401919 : txn_t * next = child->sibling_next; 120 401919 : if( child!=txn ) txn_cancel( funk, child ); 121 401919 : child = next; 122 401919 : } 123 224664 : return txn; 124 224664 : } 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 0 : 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 2438109 : ulong _xid ) { 166 2438109 : xid->ul[0] = _xid; xid->ul[1] = _xid; 167 2438109 : return xid; 168 2438109 : } 169 : 170 : FD_FN_PURE static inline int 171 : xid_eq( fd_funk_txn_xid_t const * xid, 172 0 : ulong _xid ) { 173 0 : fd_funk_txn_xid_t tmp[1]; 174 0 : return fd_funk_txn_xid_eq( xid, xid_set( tmp, _xid ) ); 175 0 : } 176 : 177 : __attribute__((noinline)) static FD_FN_UNUSED fd_funk_rec_key_t * 178 : key_set( fd_funk_rec_key_t * key, 179 1324404 : ulong _key ) { 180 1324404 : key->ul[0] = _key; key->ul[1] = _key+_key; key->ul[2] = _key*_key; key->ul[3] = -_key; 181 1324404 : return key; 182 1324404 : } 183 : 184 : FD_FN_PURE int 185 : key_eq( fd_funk_rec_key_t const * key, 186 : ulong _key ); 187 : 188 : FD_PROTOTYPES_END 189 : 190 : #endif /* HEADER_fd_src_funk_test_funk_common_h */