Beispiel #1
0
// x must be already open for writing
// x must have a parent
static void _right_rotate(ptst_t *ptst, stm_tx *tx, stm_blk *sb, stm_blk *xb, node_t *x) {
    stm_blk *lb, *lrb, *pb;
    node_t *l, *lr, *p;

    lb = GET_LEFT(x);
    pb = GET_PARENT(x);

    l = WRITE_OBJ(lb);
    p = WRITE_OBJ(pb);
    lrb = GET_RIGHT(l);

    x = WRITE_OBJ(xb);
    SET_LEFT(x, lrb);
    if (lrb != NULL ) {
        lr = WRITE_OBJ(lrb);
        SET_PARENT(lr, xb);
    }

    SET_PARENT(l, pb);
    if(pb == NULL) {
        set_t * s = (set_t*) WRITE_OBJ(sb);
        SET_ROOT(s, lb);
    } else if ( xb == GET_RIGHT(p) ) {
        SET_RIGHT(p, lb);
    } else {
        SET_LEFT(p, lb);
    }
    SET_RIGHT(l, xb);
    SET_PARENT(x, lb);
}//right_rotate
Beispiel #2
0
// x must be already open for writing
// x must have a parent
static void _left_rotate(ptst_t *ptst, stm_tx *tx, stm_blk *sb, stm_blk *xb, node_t *x) {
    stm_blk *rb, *rlb, *pb;
    node_t *r, *rl, *p;

    rb = GET_RIGHT(x);
    pb = GET_PARENT(x);

    r = WRITE_OBJ(rb);
    p = WRITE_OBJ(pb);
    rlb = GET_LEFT(r);

    x = WRITE_OBJ(xb);
    SET_RIGHT(x, rlb);
    if ( rlb != NULL ) {
        rl = WRITE_OBJ(rlb);
        SET_PARENT(rl, xb);
    }

    SET_PARENT(r, pb);
    if(pb == NULL) {
        set_t * s = (set_t*) WRITE_OBJ(sb);
        SET_ROOT(s, rb);
    } else if ( GET_LEFT(p) == xb ) {
        SET_LEFT(p, rb);
    } else {
        SET_RIGHT(p, rb);
    }
    SET_LEFT(r, xb);
    SET_PARENT(x, rb);
}//left_rotate
Beispiel #3
0
off_t brtr_delete(brtr_t *b, off_t r, void *k, size_t ks)
{
    struct brtr_node *n;

    if ((n = brtr_node(b, r)) != NULL) {
        int c;

        c = brtr_cmp(k, ks, brtr_node_key(n), n->ksize);

        if (c < 0)
            r = SET_LEFT(b, r, brtr_delete(b, n->left, k, ks));
        else
        if (c > 0)
            r = SET_RIGHT(b, r, brtr_delete(b, n->right, k, ks));
        else {
            off_t nr;

            nr = merge_nodes(b, n->left, n->right);
            brtr_free(b, r);
            r = nr;
        }
    }

    return r;
}
Beispiel #4
0
/**
 * brtr_set_n - Sets a node in a Borodin Tree by subscript
 * @b: the borotree handler
 * @r: the root of the tree
 * @i: the subscript
 * @v: the value
 * @vs: value size in bytes
 * @f: flags
 *
 * Updates a node in a Borodin Tree. The node is described by the @i
 * subscript (so the tree is treated as an array), and it's replaced
 * if it already exists (no insertion is possible). The @r value is
 * the identifier of the root node of the tree, the @v value a pointer
 * to the value and @vs the value size in bytes.
 *
 * The value returned is the identifier of the new root of the tree, or 0
 * if the node couldn't be set because there is no #i node in the tree.
 *
 * For an explanation of @flags, please see brtr_set() documentation
 * (but take note that flags implying insertion do not apply).
 *
 * [API]
 */
off_t brtr_set_n(brtr_t *b, off_t r, off_t i, void *v, size_t vs, int32_t f)
{
    struct brtr_node *n;
    off_t nr = 0;

    if ((n = brtr_node(b, r)) != NULL) {
        if (i < n->c) {
            off_t c = brtr_count(b, n->left);

            if (i < c)
                nr = SET_LEFT(b, r, brtr_set_n(b, n->left, i, v, vs, f));
            else
            if (i > c)
                nr = SET_RIGHT(b, r, brtr_set_n(b, n->right, i - c - 1, v, vs, f));
            else {
                /* replace */
                nr = brtr_alloc(b, NULL, 0, v, vs, n->left, n->right, f);

                /* keep stored stree? NODE_MODIFY */
                if (f & BRTR_SET_KSTREE)
                    n->f &= ~(BRTR_FLAG_STREE);

                brtr_free(b, r);
            }
        }
    }

    return nr;
}
Beispiel #5
0
//------------------------------------------------
// net_stream_init_v4
// keep key consistent, irregardless of which direction packet has
// sport > dport || (sport==dport && srcip < dstip)
//------------------------------------------------
int net_stream_init_v4(stream_key_t *key, int8_t ipproto, uint32_t srcip, uint32_t dstip, uint16_t sport, uint16_t dport)
{
  memset(key, 0, sizeof(*key));
  key->v4.ipproto = ipproto;
  
  if (sport > dport || (sport == dport && srcip < dstip))
  {
    key->v4.lport = sport;
    key->v4.rport = dport;
    SET_LEFT(key, srcip);
    SET_RIGHT(key, dstip);

    return 0; // not flipped
  }
  else
  {
    key->v4.lport = dport;
    key->v4.rport = sport;
    SET_LEFT(key, dstip);
    SET_RIGHT(key, srcip);

    return 1; // flipped
  }
}
Beispiel #6
0
/**
 * brtr_set - Sets a node in a Borodin Tree by key
 * @b: the borotree handler
 * @r: the root of the tree
 * @k: the key
 * @ks: key size in bytes
 * @v: the value
 * @vs: value size in bytes
 * @f: flags
 *
 * Inserts or updates a node in a Borodin Tree. The node is described
 * by the @k key, and is replaced if it exists and inserted if it doesn't
 * (but see the description of the @flags argument). The @r value is the
 * identifier of the root node of the tree, the @v value a pointer to
 * the value and @vs the value size in bytes.
 *
 * The value returned is the identifier of the new root of the tree, or 0
 * if the node couldn't be set (see below for possible causes).
 *
 * The @flags argument is an OR combination of the constants explained
 * below. There are node flags and brtr_set() ("behavioural") flags.
 * The node flags are the following:
 * 
 * BRTR_FLAG_STREE: the value to be inserted is itself an identifier of
 * the root of a subtree, so it's a pointer to an off_t value. The value
 * size should be set to sizeof(off_t).
 *
 * BRTR_FLAG_ARRAY: to be always used in combination of BRTR_FLAG_STREE.
 * It hints that the subtree stored in this node is to be treated as an
 * array instead of a set of value/key pairs (for example, its output
 * will be between square brackets when dumping it in JSON format).
 *
 * Behavioural flags:
 *
 * BRTR_SET_INSERT: Commands brtr_set() to fail if the key already
 * exists (insert-only mode).
 *
 * BRTR_SET_UPDATE: The opposite of BRTR_SET_INSERT, fail if the
 * key does not exist (update-only mode).
 *
 * BRTR_SET_KSTREE: To be used in combination of BRTR_FLAG_STREE. It
 * instructs brtr_set() that the subtree to be stored is the same as (or
 * is an update of) the subtree currently stored in the node (it basically
 * means the stored subtree is not destroyed when replaced).
 *
 * [API]
 */
off_t brtr_set(brtr_t *b, off_t r, void *k, size_t ks, void *v, size_t vs, int32_t f)
{
    struct brtr_node *n;
    off_t nr;

    if ((n = brtr_node(b, r)) != NULL) {
        int c;

        c = brtr_cmp(k, ks, brtr_node_key(n), n->ksize);

        if (c < 0)
            nr = SET_LEFT(b, r, brtr_set(b, n->left, k, ks, v, vs, f));
        else
        if (c > 0)
            nr = SET_RIGHT(b, r, brtr_set(b, n->right, k, ks, v, vs, f));
        else {
            /* key exists */
            if (f & BRTR_SET_INSERT) {
                /* if insert-only mode, fail */
                nr = 0;
            }
            else {
                /* create new node cloning current one as possible */
                nr = brtr_alloc(b, k, ks, v, vs, n->left, n->right, f);

                /* keep stored stree? NODE_MODIFY */
                if (f & BRTR_SET_KSTREE)
                    n->f &= ~(BRTR_FLAG_STREE);

                /* destroy current node */
                brtr_free(b, r);
            }
        }
    }
    else {
        /* key does not exist */
        if (f & BRTR_SET_UPDATE) {
            /* if update-only mode, fail */
            nr = 0;
        }
        else {
            /* insert */
            nr = brtr_alloc(b, k, ks, v, vs, 0, 0, f);
        }
    }

    return nr;
}