示例#1
0
setval_t set_remove(set_t *s, setkey_t k)
{
    node_t *f, *w;
    qnode_t qn[4], *pqn[] = { qn+0, qn+1, qn+2, qn+3, qn+0, qn+1 };
    int dir;
    setval_t v = NULL;
    ptst_t *ptst;

    k = CALLER_TO_INTERNAL_KEY(k);

    ptst = critical_enter();

    f = find(&s->root, k, pqn[0], &dir);
    if ( (w = FOLLOW(f, dir)) != NULL )
    {
        LOCK(w, pqn[1]);
        v = w->v;
        w->v = NULL;
        assert(!IS_BLUE(w));
        delete_by_rotation(ptst, f, dir, pqn, 0);
    }
    else
    {
        UNLOCK(f, pqn[0]);
    }

    critical_exit(ptst);

    return v;
}
示例#2
0
setval_t set_remove(set_t *s, setkey_t k)
{
    ptst_t  *ptst;
    node_t  *y, *z;
    qnode_t  z_qn;
    setval_t ov = NULL;

    k = CALLER_TO_INTERNAL_KEY(k);

    ptst = critical_enter();

    z = &s->root;
    while ( (y = (k <= z->k) ? z->l : z->r) != NULL )
        z = y;

    if ( z->k == k ) 
    {
        mcs_lock(&z->lock, &z_qn);
        if ( !IS_GARBAGE(z) )
        {
            ov = GET_VALUE(z->v);

            SET_VALUE(z->v, NULL);
        }
        mcs_unlock(&z->lock, &z_qn);
    }

    if ( ov != NULL ) 
        delete_finish(ptst, z);

    critical_exit(ptst);

    return ov;
}
示例#3
0
setval_t set_lookup(set_t *s, setkey_t k)
{
    node_t *n;
    setval_t v = NULL;
    ptst_t *ptst;

    k = CALLER_TO_INTERNAL_KEY(k);

    ptst = critical_enter();

    n = weak_find(&s->root, k);
    if ( n != NULL ) v = GET_VALUE(n);

    critical_exit(ptst);
    return v;
}
示例#4
0
setval_t set_lookup(set_t *s, setkey_t k)
{
    ptst_t  *ptst;
    node_t  *m, *n;
    setval_t v;

    k = CALLER_TO_INTERNAL_KEY(k);

    ptst = critical_enter();

    n = &s->root;
    while ( (m = (k <= n->k) ? n->l : n->r) != NULL )
        n = m;

    v = (k == n->k) ? GET_VALUE(n->v) : NULL;
    if ( v == GARBAGE_VALUE ) v = NULL;

    critical_exit(ptst);

    return v;
}
示例#5
0
setval_t set_update(set_t *s, setkey_t k, setval_t v, int overwrite)
{
    node_t  *f, *w;
    qnode_t  f_qn, w_qn;
    int dir;
    setval_t ov = NULL;
    ptst_t  *ptst;

    k = CALLER_TO_INTERNAL_KEY(k);

    ptst = critical_enter();

retry:
    f = find(&s->root, k, &f_qn, &dir);

    if ( (w = FOLLOW(f, dir)) != NULL )
    {
        /* Protected by parent lock. */
        assert(!IS_BLUE(w));
        ov = w->v;
        if ( overwrite || (ov == NULL) ) w->v = v;
    }
    else
    {
        w = gc_alloc(ptst, gc_id);
        w->l = NULL;
        w->r = NULL;
        w->v = v;
        w->k = k;
        mcs_init(&w->lock);
        UPDATE(f, dir, w);
    }

    UNLOCK(f, &f_qn);

    critical_exit(ptst);

    return ov;
}
示例#6
0
    s->root.r = NULL;
    s->root.p = NULL;
    s->root.copy = 0;

    return s;
}


setval_t set_update(set_t *s, setkey_t k, setval_t v, int overwrite)
{
    node_t  *a, *new;
    qnode_t  qn;
    setval_t ov = NULL;
    ptst_t  *ptst;

    k = CALLER_TO_INTERNAL_KEY(k);

    ptst = critical_enter();

    a = strong_search(&s->root, k, &qn);
    if ( a->k != k )
    {
        new = gc_alloc(ptst, gc_id);
        mcs_init(&new->lock);
        new->k = k;
        new->v = v;
        new->l = NULL;
        new->r = NULL;
        new->p = a;
        new->copy = 0;
        if ( a->k < k ) a->r = new; else a->l = new;
示例#7
0
setval_t set_update(set_t *s, setkey_t k, setval_t v, int overwrite)
{
    ptst_t  *ptst;
    qnode_t  y_qn, z_qn;
    node_t  *y, *z, *new_internal, *new_leaf;
    int      fix_up = 0;
    setval_t ov = NULL;

    k = CALLER_TO_INTERNAL_KEY(k);

    ptst = critical_enter();

 retry:
    z = &s->root;
    while ( (y = (k <= z->k) ? z->l : z->r) != NULL )
        z = y;
    
    y = z->p;
    mcs_lock(&y->lock, &y_qn);
    if ( (((k <= y->k) ? y->l : y->r) != z) || IS_GARBAGE(y) )
    {
        mcs_unlock(&y->lock, &y_qn);
        goto retry;
    }

    mcs_lock(&z->lock, &z_qn);
    assert(!IS_GARBAGE(z) && IS_LEAF(z));

    if ( z->k == k )
    {
        ov = GET_VALUE(z->v);
        if ( overwrite || (ov == NULL) )
            SET_VALUE(z->v, v);
    }
    else
    {
        new_leaf     = gc_alloc(ptst, gc_id);
        new_internal = gc_alloc(ptst, gc_id);
        new_leaf->k = k;
        new_leaf->v = MK_BLACK(v);
        new_leaf->l = NULL;
        new_leaf->r = NULL;

        new_leaf->p = new_internal;
        mcs_init(&new_leaf->lock);
        if ( z->k < k )
        {
            new_internal->k = z->k;
            new_internal->l = z;
            new_internal->r = new_leaf;
        }
        else
        {
            new_internal->k = k;
            new_internal->l = new_leaf;
            new_internal->r = z;
        }
        new_internal->p = y;
        mcs_init(&new_internal->lock);

        if ( IS_UNBALANCED(z->v) )
        {
            z->v = MK_BALANCED(z->v);
            new_internal->v = MK_BLACK(INTERNAL_VALUE);
        }
        else if ( IS_RED(y->v) )
        {
            new_internal->v = MK_UNBALANCED(MK_RED(INTERNAL_VALUE));
            fix_up = 1;
        }
        else
        {
            new_internal->v = MK_RED(INTERNAL_VALUE);
        }

        WMB();

        z->p = new_internal;
        if ( y->l == z ) y->l = new_internal; else y->r = new_internal;
    }

    mcs_unlock(&y->lock, &y_qn);
    mcs_unlock(&z->lock, &z_qn);

    if ( fix_up ) 
        fix_unbalance_up(ptst, new_internal);

 out:
    critical_exit(ptst);

    return ov;
}