// 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
// 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
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; }
/** * 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; }
//------------------------------------------------ // 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 } }
/** * 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; }