Line data Source code
1 : #ifndef HEADER_fd_src_funkier_test_funkier_common_h 2 : #define HEADER_fd_src_funkier_test_funkier_common_h 3 : 4 : /* "Mini-funk" implementation for reference and testing purposes */ 5 : 6 : #include "fd_funkier_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 0 : 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 0 : txn_t * txn ) { 105 0 : txn_t * child = txn ? txn->child_head : funk->child_head; 106 0 : while( child ) { 107 0 : txn_t * next = child->sibling_next; 108 0 : txn_cancel( funk, child ); 109 0 : child = next; 110 0 : } 111 0 : return txn; 112 0 : } 113 : 114 : static inline txn_t * 115 : txn_cancel_siblings( funk_t * funk, 116 0 : txn_t * txn ) { 117 0 : txn_t * child = txn->parent ? txn->parent->child_head : funk->child_head; 118 0 : while( child ) { 119 0 : txn_t * next = child->sibling_next; 120 0 : if( child!=txn ) txn_cancel( funk, child ); 121 0 : child = next; 122 0 : } 123 0 : return txn; 124 0 : } 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 : void 144 : rec_remove( funk_t * funk, 145 : rec_t * rec ); 146 : 147 : /* Mini funk API */ 148 : 149 : funk_t * 150 : funk_new( void ); 151 : 152 : void 153 : funk_delete( funk_t * funk ); 154 : 155 0 : static inline int funk_is_frozen( funk_t * funk ) { return !!funk->child_head; } 156 : 157 : FD_FN_PURE static inline txn_t * 158 0 : funk_descendant( funk_t * funk ) { 159 0 : return funk->child_head ? txn_descendant( funk->child_head ) : NULL; 160 0 : } 161 : 162 : /* Testing utilities */ 163 : 164 : ulong 165 : xid_unique( void ); 166 : 167 : static inline fd_funkier_txn_xid_t * 168 : xid_set( fd_funkier_txn_xid_t * xid, 169 0 : ulong _xid ) { 170 0 : xid->ul[0] = _xid; xid->ul[1] = _xid+_xid; 171 0 : return xid; 172 0 : } 173 : 174 : FD_FN_PURE static inline int 175 : xid_eq( fd_funkier_txn_xid_t const * xid, 176 0 : ulong _xid ) { 177 0 : fd_funkier_txn_xid_t tmp[1]; 178 0 : return fd_funkier_txn_xid_eq( xid, xid_set( tmp, _xid ) ); 179 0 : } 180 : 181 : static inline fd_funkier_rec_key_t * 182 : key_set( fd_funkier_rec_key_t * key, 183 0 : ulong _key ) { 184 0 : key->ul[0] = _key; key->ul[1] = _key+_key; key->ul[2] = _key*_key; key->ul[3] = -_key; 185 0 : key->ul[4] = _key*3U; 186 0 : return key; 187 0 : } 188 : 189 : FD_FN_PURE int 190 : key_eq( fd_funkier_rec_key_t const * key, 191 : ulong _key ); 192 : 193 : FD_PROTOTYPES_END 194 : 195 : #endif /* HEADER_fd_src_funkier_test_funkier_common_h */