3 /***********************************************************/
4 /* H A S H T A B L E U T I L I T Y F U N C T I O N S */
5 /***********************************************************/
10 * sets all pointers of the array table of the hash table to NULL
11 * and init the mutex (if a multithreaded service thread has
14 * possible return values:
16 * false (something wrong with the mutex)
18 static bool contract_hash_init()
22 #ifdef FRSH_CONFIG_ENABLE_SERVICE_TH_MULTITHREAD
23 if (fosa_mutex_init(&contract_hash_table.mutex, 0) != 0)
26 for (i = 0; i < HASH_N_ELEMENTS; i++)
27 contract_hash_table.table[i] = NULL;
35 * obtains the hash (int) value associated to the (string) key provided
36 * simply accessing each character as an integer value and summing them all
38 * always returns the hash value (no room for errors!)
40 static unsigned int contract_hash_hash(const char *key_str)
42 int i, step = CHAR_PER_INT;
43 unsigned int hash = 0;
44 unsigned int key_val = 0;
45 char *key_val_ptr = (char*) &key_val;
47 for (i = 0; i < strlen(key_str); i += step) {
48 strncpy(key_val_ptr, (key_str + i), step);
52 return hash % HASH_N_ELEMENTS;
58 * calculates the hash value, accesses the hash table element and
59 * follows the linked list if needed
60 * data_ptr can be used to access/modify the element data field
62 * possible return values:
64 * HASH_ERR_LABEL_NOT_FOUND
66 static int contract_hash_find(const char *key, contract_hash_data_t **data_ptr)
68 contract_hash_entry_t *curr_entry;
69 unsigned int hash_value;
72 /* hash value of the the key */
73 hash_value = contract_hash_hash(key);
74 #ifdef frsh_enable_service_th_multithread
76 fosa_mutex_lock(&contract_hash_table.mutex);
78 /* start traversing the linked list (if needed) */
79 curr_entry = contract_hash_table.table[hash_value];
80 while (curr_entry != NULL) {
81 if (strncmp(key, curr_entry->contract_label, HASH_KEY_LENGTH) == 0) {
83 *data_ptr = &(curr_entry->contract_data);
84 result = HASH_LABEL_FOUND;
87 /* not found yet, let's try the next element */
88 curr_entry = curr_entry->next;
90 #ifdef FRSH_CONFIG_ENABLE_SERVICE_TH_MULTITHREAD
91 /* unlock the table */
92 fosa_mutex_unlock(&contract_hash_table.mutex);
101 * calculates the hash function and adds the new element at the end
102 * of the linked list of the hash table entry, unless one with the same
103 * key value already exists
104 * data_ptr can be used to access/modify the element data field
106 * possible return values:
108 * HASH_ERR_LABEL_FOUND
110 static int contract_hash_add(const char *key, contract_hash_data_t **data_ptr)
112 contract_hash_entry_t *new_entry, **curr_entry;
113 unsigned int hash_value;
116 /* hash value of the key */
117 hash_value = contract_hash_hash(key);
118 #ifdef FRSH_CONFIG_ENABLE_SERVICE_TH_MULTITHREAD
120 fosa_mutex_lock(&contract_hash_table.mutex);
122 /* traverse the linked list till the end
123 * (stop if the key already exists) */
124 curr_entry = &contract_hash_table.table[hash_value];
125 result = HASH_NO_ERROR;
126 while (*curr_entry != NULL) {
127 if (strncmp(key, (*curr_entry)->contract_label, HASH_KEY_LENGTH) == 0) {
128 result = HASH_ERR_LABEL_FOUND;
131 curr_entry = &(*curr_entry)->next;
133 if (result == HASH_NO_ERROR) {
134 /* create the new element */
135 new_entry = (contract_hash_entry_t*) malloc(sizeof(contract_hash_entry_t));
136 strncpy(new_entry->contract_label, key, HASH_KEY_LENGTH);
137 /* add it (we're already at the end of the linked list) */
138 *data_ptr = &(new_entry->contract_data);
139 *curr_entry = new_entry;
140 new_entry->next = NULL;
142 #ifdef FRSH_CONFIG_ENABLE_SERVICE_TH_MULTITHREAD
143 /* unlock the table */
144 fosa_mutex_unlock(&contract_hash_table.mutex);
153 * calculates the hash function, searches the element in the linked
156 * possible return values:
158 * HASH_ERR_LABEL_NOT_FOUND
160 static int contract_hash_del(const char *key)
162 contract_hash_entry_t *curr_entry, *curr_entry_prev;
163 unsigned int hash_value;
166 /* hash value of the key */
167 hash_value = contract_hash_hash(key);
168 #ifdef FRSH_CONFIG_ENABLE_SERVICE_TH_MULTITHREAD
170 fosa_mutex_lock(&contract_hash_table.mutex);
172 /* traverse the list searching for the key */
173 curr_entry_prev = NULL;
174 curr_entry = contract_hash_table.table[hash_value];
175 result = HASH_ERR_LABEL_NOT_FOUND;
176 while (curr_entry != NULL) {
177 if (strncmp(key, curr_entry->contract_label, HASH_KEY_LENGTH) == 0) {
178 /* update the list and remove the element */
179 if (curr_entry_prev == NULL)
180 contract_hash_table.table[hash_value] = curr_entry->next;
182 curr_entry_prev->next = curr_entry->next;
183 free((void*) curr_entry);
184 result = HASH_NO_ERROR;
187 curr_entry_prev = curr_entry;
188 curr_entry = curr_entry->next;
190 #ifdef FRSH_CONFIG_ENABLE_SERVICE_TH_MULTITHREAD
191 /* unlock the table */
192 fosa_mutex_unlock(&contract_hash_table.mutex);