// old public method static inline void qt_hash_destroy(qt_hash h) { marked_ptr_t cursor; assert(h); assert(h->B); cursor = h->B[0]; while (PTR_OF(cursor) != NULL) { marked_ptr_t tmp = cursor; assert(MARK_OF(tmp) == 0); cursor = (marked_ptr_t)((PTR_OF(cursor)->next)); if (h->op_cleanup && ((PTR_OF(tmp)->key || PTR_OF(tmp)->value))) { // only call the cleanup function on non-place-holders h->op_cleanup(PTR_OF(tmp)->key, PTR_OF(tmp)->value); } qpool_free(hash_entry_pool, PTR_OF(tmp)); } FREE(h->B, hard_max_buckets * sizeof(marked_ptr_t)); FREE(h, sizeof(qt_hash)); }
void* lf_table_find(marked_ptr_t* head, hash_key_t key, marked_ptr_t** prev, marked_ptr_t* cur) { marked_ptr_t* tp_prev; marked_ptr_t tp_cur; marked_ptr_t* tp_next; hash_key_t cur_key; void* cur_value; if(PTR_OF(*head) == NULL) { if(prev) {*prev = head;}; if(cur){*cur = *head;}; return NULL; } while(1) { tp_prev = head; tp_cur = *head; while(1) { if (PTR_OF(tp_cur) == NULL) { if(prev){*prev = tp_prev;}; if(cur){*cur = tp_cur;}; return NULL; } tp_next = &PTR_OF(tp_cur)->next; cur_key = PTR_OF(tp_cur)->key; cur_value = PTR_OF(tp_cur)->value; if(*tp_prev != tp_cur) { break; // someone has mucked with the list, start over } if(MARK_OF(tp_cur)) { if (CAS(tp_prev, CONSTRUCT(1, tp_cur), tp_next) == CONSTRUCT(1, tp_cur)) { free(PTR_OF(tp_cur)); tp_cur = *tp_next; continue; } else { break; //start over } } if (key >= cur_key) { if(prev){*prev = tp_prev;}; if(cur){*cur = tp_cur;}; return key == cur_key ? cur_value : NULL; } tp_prev = tp_next; tp_cur = *tp_next; } } }
static void *qt_lf_list_find(marked_ptr_t *head, so_key_t hashed_key, qt_key_t key, marked_ptr_t **oprev, marked_ptr_t *ocur, marked_ptr_t *onext, qt_dict_key_equals_f op_equals) { so_key_t ckey; qt_key_t okey; void *cval; marked_ptr_t *prev = NULL; marked_ptr_t cur = UNINITIALIZED; marked_ptr_t next = UNINITIALIZED; // int foundInsertPos = 0; while (1) { prev = head; cur = *prev; while (1) { if (PTR_OF(cur) == NULL) { if (oprev) { *oprev = prev; } if (ocur) { *ocur = cur; } if (onext) { *onext = next; } return 0; } next = (marked_ptr_t)(PTR_OF(cur)->next); ckey = PTR_OF(cur)->hashed_key; cval = PTR_OF(cur)->value; okey = PTR_OF(cur)->key; if (*prev != CONSTRUCT(0, cur)) { break; // this means someone mucked with the list; start over } if (!MARK_OF(next)) { // if next pointer is not marked if (ckey >= hashed_key) { // if current key > hashed_key, the key isn't in the list; if current key == hashed_key, the key IS in the list // if (foundInsertPos == 0) { if (oprev) { *oprev = prev; } if (ocur) { *ocur = cur; } if (onext) { *onext = next; } // foundInsertPos = 1; // } if(ckey == hashed_key) { if((okey != NULL) && op_equals(okey, key)) { /* * if (oprev) { *oprev = prev; } * if (ocur) { *ocur = cur; } * if (onext) { *onext = next; } */ return cval; } // else, keep looking } else { return NULL; } } // but if current key < hashed_key, the we don't know yet, keep looking prev = (marked_ptr_t *)&(PTR_OF(cur)->next); } else { if (qthread_cas(prev, CONSTRUCT(0, cur), CONSTRUCT(0, next)) == CONSTRUCT(0, cur)) { qpool_free(hash_entry_pool, PTR_OF(cur)); } else { break; } } cur = next; } } }