2 #define LFDS700_HASH_A_GET_KEY_FROM_ELEMENT( hash_a_element ) ( (hash_a_element).key )
3 #define LFDS700_HASH_A_SET_KEY_IN_ELEMENT( hash_a_element, new_key ) ( (hash_a_element).key = (void *) (lfds700_pal_uint_t) (new_key) )
4 #define LFDS700_HASH_A_GET_VALUE_FROM_ELEMENT( hash_a_element ) ( LFDS700_MISC_BARRIER_LOAD, (hash_a_element).value )
5 #define LFDS700_HASH_A_SET_VALUE_IN_ELEMENT( hash_a_element, new_value ) { void *local_new_value = (void *) (lfds700_pal_uint_t) (new_value); LFDS700_PAL_ATOMIC_EXCHANGE( &(hash_a_element).value, &local_new_value ); }
6 #define LFDS700_HASH_A_GET_USER_STATE_FROM_STATE( hash_a_state ) ( (hash_a_state).user_state )
8 #define LFDS700_HASH_A_32BIT_HASH_FUNCTION( data, data_length_in_bytes, hash ) { \
12 for( loop = 0 ; loop < (data_length_in_bytes) ; loop++ ) \
14 (hash) += *( (char unsigned *) (data) + loop ); \
15 (hash) += ((hash) << 10); \
16 (hash) ^= ((hash) >> 6); \
19 (hash) += ((hash) << 3); \
20 (hash) ^= ((hash) >> 11); \
21 (hash) += ((hash) << 15); \
23 /* TRD : this is the Jenkins one-at-a-time hash
24 it produces a 32 bit hash
25 http://en.wikipedia.org/wiki/Jenkins_hash_function
27 we ourselves do *not* initialize the value of *hash, so that
28 our caller has the option to call us multiple times, each
29 time with for example a different member of a struct, which is
30 then hashed into the existing, built-up-so-far hash value, and
31 so build up a quality hash
35 enum lfds700_hash_a_existing_key
37 LFDS700_HASH_A_EXISTING_KEY_OVERWRITE,
38 LFDS700_HASH_A_EXISTING_KEY_FAIL
41 enum lfds700_hash_a_insert_result
43 LFDS700_HASH_A_PUT_RESULT_FAILURE_EXISTING_KEY,
44 LFDS700_HASH_A_PUT_RESULT_SUCCESS_OVERWRITE,
45 LFDS700_HASH_A_PUT_RESULT_SUCCESS
48 enum lfds700_hash_a_query
50 LFDS700_HASH_A_QUERY_GET_POTENTIALLY_INACCURATE_COUNT,
51 LFDS700_HASH_A_QUERY_SINGLETHREADED_VALIDATE
55 struct lfds700_hash_a_element
57 struct lfds700_btree_au_element
63 void LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
67 struct lfds700_hash_a_iterate
69 struct lfds700_btree_au_element
72 struct lfds700_btree_au_state
77 struct lfds700_hash_a_state
79 enum lfds700_hash_a_existing_key
83 (*key_compare_function)( void const *new_key, void const *existing_key );
88 struct lfds700_btree_au_state
92 (*element_cleanup_callback)( struct lfds700_hash_a_state *has, struct lfds700_hash_a_element *hae ),
93 (*key_hash_function)( void const *key, lfds700_pal_uint_t *hash ),
97 /***** public prototypes *****/
98 void lfds700_hash_a_init_valid_on_current_logical_core( struct lfds700_hash_a_state *has,
99 struct lfds700_btree_au_state *baus_array,
100 lfds700_pal_uint_t array_size,
101 int (*key_compare_function)(void const *new_key, void const *existing_key),
102 void (*key_hash_function)(void const *key, lfds700_pal_uint_t *hash),
103 enum lfds700_hash_a_existing_key existing_key,
105 // TRD : used in conjunction with the #define LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE
107 void lfds700_hash_a_cleanup( struct lfds700_hash_a_state *has,
108 void (*element_cleanup_function)(struct lfds700_hash_a_state *has, struct lfds700_hash_a_element *hae) );
110 enum lfds700_hash_a_insert_result lfds700_hash_a_insert( struct lfds700_hash_a_state *has,
111 struct lfds700_hash_a_element *hae,
112 struct lfds700_hash_a_element **existing_hae,
113 struct lfds700_misc_prng_state *ps );
114 // TRD : if existing_value is not NULL and the key exists, existing_value is set to the value of the existing key
116 int lfds700_hash_a_get_by_key( struct lfds700_hash_a_state *has,
118 struct lfds700_hash_a_element **hae );
120 void lfds700_hash_a_iterate_init( struct lfds700_hash_a_state *has, struct lfds700_hash_a_iterate *hai );
121 int lfds700_hash_a_iterate( struct lfds700_hash_a_iterate *hai, struct lfds700_hash_a_element **hae );
123 void lfds700_hash_a_query( struct lfds700_hash_a_state *has,
124 enum lfds700_hash_a_query query_type,
126 void *query_output );