// 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));
}
Example #2
0
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;
        }
    }
}