static stm_blk * _successor_non_stm(ptst_t *ptst, stm_tx *tx, stm_blk * tb) { stm_blk *chb, *pb, *plb; node_t *t, *ch, *p; if(tb == NULL) { return NULL; } else { t = init_stm_blk__(ptst, MEMORY, tb); if(GET_RIGHT(t) != NULL) { pb = GET_RIGHT(t); p = init_stm_blk__(ptst, MEMORY, pb); while ( (plb=GET_LEFT(p)) != NULL ) { pb = plb; p = init_stm_blk__(ptst, MEMORY, pb); } return pb; } else {//GET_RIGHT(t) == NULLL pb = GET_PARENT(t); p = init_stm_blk__(ptst, MEMORY, pb); chb = tb; ch = t; while(pb != NULL && chb == GET_RIGHT(p)) { chb = pb; ch = p; pb = GET_PARENT(p); p = init_stm_blk__(ptst, MEMORY, pb); } return pb; } } }
// 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
bool Cube::CheckR() { CubeColor centre = GET_RIGHT(subCubes[2][1][1]); return GET_RIGHT(subCubes[2][0][0]) == centre && GET_RIGHT(subCubes[2][0][1]) == centre && GET_RIGHT(subCubes[2][0][2]) == centre && GET_RIGHT(subCubes[2][1][0]) == centre && GET_RIGHT(subCubes[2][1][1]) == centre && GET_RIGHT(subCubes[2][1][2]) == centre && GET_RIGHT(subCubes[2][2][0]) == centre && GET_RIGHT(subCubes[2][2][1]) == centre && GET_RIGHT(subCubes[2][2][2]) == centre; }
// 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
/*delete_node function divide the delete operation into three situations by the size of the block the pointer points to. 1. the size = 8. Delete it from the list_for_8 single direction linked list 2. the size = 16. Delete it from the list_for_16 double directions linked list 3. Others. Call the function delete to delete a node in the Binary Search Tree*/ inline static void delete_node(void *bp) { SET_PREALLOC_INFO(GET_NEXT(bp)); if (GET_SIZE(bp) == 8) { /*the previous free block condition can be judged by the third bit*/ RESET_PRE_8_INFO(GET_NEXT(bp)); if (bp == list_for_8) { list_for_8 = (void *)GET_LEFT(bp); return; } /*search the position of bp when bp is not the first node*/ void * finder = list_for_8; void * before = finder; while (finder != bp) { before = finder; finder = (void *)GET_LEFT(finder); } PUT_LEFT(before, GET_LEFT(finder)); } else if (GET_SIZE(bp) == 16) { if (bp == list_for_16) { list_for_16 = (void *)GET_RIGHT(bp); PUT_LEFT(list_for_16, NULL_POINTER); return; } void * bpleft = (void *)GET_LEFT(bp); void * bpright = (void *)GET_RIGHT(bp); PUT_RIGHT(GET_LEFT(bp), bpright); PUT_LEFT(GET_RIGHT(bp), bpleft); return; } else { /*delete a node in the BST*/ delete(bp); } }
/*this is used by the first node of a size*/ inline static int get_direction(void * bp) { void * parent = (void *)GET_PARENT(bp); if (parent == NULL_POINTER) { return 0; } if ((void *)GET_LEFT(parent) == bp) { return 1; } if ((void *)GET_RIGHT(parent) == bp) { return 2; } return -1; }
static void *match( size_t asize ) { if(asize == 8 && list_for_8 != NULL_POINTER) return list_for_8; if(asize <= 16 && list_for_16 != NULL_POINTER) return list_for_16; /* the most fit block */ void *fit = NULL_POINTER; /* temporary location of the search */ void *temp = root; /* use tree to implement a comparative best fit search */ while(temp != NULL_POINTER){ if( asize <= GET_SIZE(temp) ){ fit = temp; temp = (void *)GET_LEFT(temp); } else temp = (void *)GET_RIGHT(temp); } return fit; }
static stm_blk * _lookup(ptst_t *ptst, stm_tx *tx, stm_blk *sb, setkey_t k) { stm_blk *pb; node_t *p; set_t * s = (set_t*) READ_OBJ(sb); pb = GET_ROOT(s); while ( pb != NULL ) { p = READ_OBJ(pb); //assert(GET_KEY(p)+100==GET_VALUE(p)); int cmp = k - GET_KEY(p); if (cmp == 0) { return pb; } pb = (cmp < 0) ? GET_LEFT(p) : GET_RIGHT(p); } return NULL; }
//----------------------------------------------- // to_s //----------------------------------------------- char* streamkey_to_s(char *dest, stream_key_t *key) { uint16_t sport, dport; if (0) //pkt_is_v6(pkt)) { sprintf(dest, "IPV6 STREAM HERE"); //sprintf(dest, "%s_%s_%d_%s_%d", get_proto_name(pkt->ip6.ip_p),"?:?:?",sport, "?:?:?", dport); return dest; } else { char leftip[16], rightip[16]; ip2string(leftip, GET_LEFT(key)); ip2string(rightip, GET_RIGHT(key)); sprintf(dest, "%s_%s_%d_%s_%d", get_proto_name(key->v4.ipproto), leftip, key->v4.lport, rightip, key->v4.rport); return dest; } }
string Cube::Serialize() { string data; for (int z = 0; z < 3; ++z) { for (int y = 0; y < 3; ++y) { for (int x = 0; x < 3; ++x) { cube_t subcube = subCubes[x][y][z]; data += ColorCharMap[GET_FRONT(subcube)]; data += ColorCharMap[GET_BACK(subcube)]; data += ColorCharMap[GET_LEFT(subcube)]; data += ColorCharMap[GET_RIGHT(subcube)]; data += ColorCharMap[GET_UP(subcube)]; data += ColorCharMap[GET_DOWN(subcube)]; } } } return data; }
//-------------------------------------------- // compute simple hash on stream key (for HashTable) //-------------------------------------------- uint32_t hash_stream_key(const void *_key) { stream_key_t *key = (stream_key_t *)_key; uint32_t val = *(uint32_t *)key; val = GET_LEFT(key) ^ GET_RIGHT(key); val *= key->v4.rport; val = val ^ key->v4.lport; //char pbuf[80]; //printf ("HASH: %s %u\n", streamkey_to_s(pbuf, key), val); if (!net_stream_is_v6(key)) return val; val = val ^ *(uint32_t *)key->addrs2; val = val ^ *(uint32_t*)(key->addrs2+4); val = val ^ *(uint32_t*)(key->addrs2+8); val = val ^ *(uint32_t*)(key->addrs2+12); val = val ^ *(uint32_t*)(key->addrs2+16); return val; }
static void _fix_after_insertion(ptst_t *ptst, stm_tx *tx, stm_blk *sb, stm_blk *xb, node_t *x) { stm_blk *pb, *gpb, *yb, *lub; node_t *p, *gp, *y; SET_COLOUR(x, RED); // rebalance tree set_t * s = (set_t*)READ_OBJ(sb); while (xb != NULL && GET_PARENT(x) != NULL) { pb = GET_PARENT(x); p = READ_OBJ(pb); if (IS_BLACK(p)) // case 2 - parent is black break; gpb = GET_PARENT(p); gp = READ_OBJ(gpb); lub = GET_LEFT(gp); if (pb == lub) { // parent is red, p=GET_LEFT(g) yb = GET_RIGHT(gp); // y (uncle) y = READ_OBJ(yb); if (IS_RED(y)) { // case 3 - parent is red, uncle is red (p = GET_LEFT(gp)) p = WRITE_OBJ(pb); y = WRITE_OBJ(yb); gp = WRITE_OBJ(gpb); SET_COLOUR(p, BLACK); SET_COLOUR(y, BLACK); SET_COLOUR(gp, RED); xb = gpb; x = gp; } else { // parent is red, uncle is black (p = GET_LEFT(gp)) if ( xb == GET_RIGHT(p) ) { // case 4 - parent is red, uncle is black, x = GET_RIGHT(p), p = GET_LEFT(gp) xb = pb; x = WRITE_OBJ(pb); _left_rotate(ptst, tx, sb, xb, x); pb=GET_PARENT(x); } // case 5 - parent is red, uncle is black, x = GET_LEFT(p), p = GET_LEFT(gp) p = WRITE_OBJ(pb); gpb = GET_PARENT(p); gp = WRITE_OBJ(gpb); SET_COLOUR(p, BLACK); SET_COLOUR(gp, RED); if (gp != NULL) { _right_rotate(ptst, tx, sb, gpb, gp); } } } else { // parent is red, p = GET_RIGHT(gp) yb = lub; y = READ_OBJ(yb); if (IS_RED(y)) { // case 3 - parent is red, uncle is red (p = GET_RIGHT(gp)) p = WRITE_OBJ(pb); y = WRITE_OBJ(yb); gp = WRITE_OBJ(gpb); SET_COLOUR(p, BLACK); SET_COLOUR(y, BLACK); SET_COLOUR(gp, RED); xb = gpb; x = gp; } else { // parent is red, uncle is black (p = GET_RIGHT(gp)) if ( xb == GET_LEFT(p) ) { // case 4 - parent is red, uncle is black, x = GET_LEFT(p), p = GET_RIGHT(gp) xb = pb; x = WRITE_OBJ(pb); _right_rotate(ptst, tx, sb, xb, x); pb = GET_PARENT(x); } // case 5 - parent is red, uncle is black, x = GET_RIGHT(p), p = GET_RIGHT(gp) p = WRITE_OBJ(pb); gpb = GET_PARENT(p); gp = WRITE_OBJ(gpb); SET_COLOUR(p, BLACK); SET_COLOUR(gp, RED); if(gp != NULL) { _left_rotate(ptst, tx, sb, gpb, gp); } } } } s = (set_t*)READ_OBJ(sb); stm_blk * rob = GET_ROOT(s); node_t * ro = READ_OBJ(rob); if (IS_RED(ro)) { ro = WRITE_OBJ(rob); SET_COLOUR(ro,BLACK); } }
static void _fix_after_deletion(ptst_t *ptst, stm_tx *tx, stm_blk *sb, stm_blk *xb, node_t *x) { stm_blk *pb, *plb, *sibb, *siblb, *sibrb; node_t *p, *sib, *sibl, *sibr; set_t *s; while (GET_PARENT(x)!=NULL && IS_BLACK(x)) { pb = GET_PARENT(x); p = WRITE_OBJ(pb); plb = GET_LEFT(p); if ( xb == plb ) { sibb = GET_RIGHT(p); sib = WRITE_OBJ(sibb); if (IS_RED(sib)) { SET_COLOUR(sib, BLACK); SET_COLOUR(p, RED); _left_rotate(ptst, tx, sb, pb, p); pb = GET_PARENT(x); p=WRITE_OBJ(pb); sibb = GET_RIGHT(p); sib = WRITE_OBJ(sibb); } siblb = GET_LEFT(sib); sibl = READ_OBJ(siblb); sibrb = GET_RIGHT(sib); sibr = READ_OBJ(sibrb); if (IS_BLACK(sibl) && IS_BLACK(sibr)) { SET_COLOUR(sib, RED); xb = GET_PARENT(x); x = WRITE_OBJ(xb); } else { if (IS_BLACK(sibr)) { sibl = WRITE_OBJ(siblb); SET_COLOUR(sibl, BLACK); SET_COLOUR(sib,RED); _right_rotate(ptst, tx, sb, sibb, sib); pb = GET_PARENT(x); p = WRITE_OBJ(pb); sibb = GET_RIGHT(p); } sib = WRITE_OBJ(sibb); SET_COLOUR(sib, GET_COLOUR(p)); p = WRITE_OBJ(pb); SET_COLOUR(p, BLACK); sibrb = GET_RIGHT(sib); sibr = WRITE_OBJ(sibrb); SET_COLOUR(sibr, BLACK); _left_rotate(ptst, tx, sb, pb, p); s = (set_t*)READ_OBJ(sb); xb = GET_ROOT(s); x = WRITE_OBJ(xb); break; } } else { // inverse sibb = plb; sib = WRITE_OBJ(sibb); if (IS_RED(sib)) { SET_COLOUR(sib, BLACK); SET_COLOUR(p, RED); _right_rotate(ptst, tx, sb, pb, p); pb = GET_PARENT(x); p=WRITE_OBJ(pb); sibb = GET_LEFT(p); sib = WRITE_OBJ(sibb); } siblb = GET_LEFT(sib); sibl = READ_OBJ(siblb); sibrb = GET_RIGHT(sib); sibr = READ_OBJ(sibrb); if (IS_BLACK(sibl) && IS_BLACK(sibr)) { SET_COLOUR(sib, RED); xb = GET_PARENT(x); x = WRITE_OBJ(xb); } else { if (IS_BLACK(sibl)) { sibr = WRITE_OBJ(sibrb); SET_COLOUR(sibr, BLACK); SET_COLOUR(sib, RED); _left_rotate(ptst, tx, sb, sibb, sib); pb = GET_PARENT(x); p = WRITE_OBJ(pb); sibb = GET_LEFT(p); } sib = WRITE_OBJ(sibb); SET_COLOUR(sib, GET_COLOUR(p)); p = WRITE_OBJ(pb); SET_COLOUR(p, BLACK); siblb = GET_LEFT(sib); sibl = WRITE_OBJ(siblb); SET_COLOUR(sibl, BLACK); _right_rotate(ptst, tx, sb, pb, p); s = (set_t*)READ_OBJ(sb); xb = GET_ROOT(s); x = WRITE_OBJ(xb); break; } } } if(IS_RED(x)) { SET_COLOUR(x, BLACK); } }//fix_after_deletion
inline static void insert_node( void *bp ) { RESET_PREALLOC_INFO(GET_NEXT(bp)); //reset the second bit of the HDRPer of the next block if (GET_SIZE(bp) == 8) { PUT_LEFT(bp, list_for_8); list_for_8 = bp; /*used to be wrong with mistaking SET to RESET */ SET_PRE_8_INFO(GET_NEXT(bp)); return; } else if (GET_SIZE(bp) == 16){ if (list_for_16 == NULL_POINTER) { PUT_RIGHT(bp, list_for_16); PUT_LEFT(bp, NULL_POINTER); list_for_16 = bp; return; } PUT_RIGHT(bp, list_for_16); PUT_LEFT(list_for_16, bp); PUT_LEFT(bp, NULL_POINTER); list_for_16 = bp; } else { //use BST when block size > 16 if (root == NULL_POINTER) { PUT_LEFT(bp, NULL_POINTER); PUT_RIGHT(bp, NULL_POINTER); PUT_PARENT(bp, NULL_POINTER); PUT_BROTHER(bp, NULL_POINTER); root = bp; //root is also an address. return; } else { void *parent = root; void *temp = root; int flag = 0; /*flag = 0 : the root itself; flag = 1 : left; flag = 2 : right*/ while (temp != NULL_POINTER) { /*when finding the free block in BST with the same size*/ if (GET_SIZE(temp) == GET_SIZE(bp)) { PUT_LEFT(bp, GET_LEFT(temp)); PUT_RIGHT(bp, GET_RIGHT(temp)); PUT_BROTHER(bp, temp); PUT_PARENT(GET_LEFT(temp), bp); PUT_PARENT(GET_RIGHT(temp), bp); PUT_LEFT(temp, bp); PUT_PARENT(bp, GET_PARENT(temp)); if (flag == 0) { root = bp; } else if (flag == 1) { PUT_LEFT(parent, bp); } else { PUT_RIGHT(parent, bp); } return; /*SEARCH RIGHT CHILD*/ } else if (GET_SIZE(temp) < GET_SIZE(bp)) { parent = temp; temp = (void *)GET_RIGHT(temp); flag = 2; /*SEARCH LEFT CHILD*/ } else { parent = temp; temp = (void *)GET_LEFT(temp); flag = 1; } } /*insert new node*/ if (flag == 1) { PUT_LEFT(parent, bp); } else { PUT_RIGHT(parent, bp); } PUT_LEFT(bp, NULL_POINTER); PUT_RIGHT(bp, NULL_POINTER); PUT_PARENT(bp, parent); PUT_BROTHER(bp, NULL_POINTER); } } //BST_checker(root); }