bool_t bst_remove(bst_key_t k, node_t* root, int id){ //fprintf(stderr, "bst remove\n"); // node_t* pred; // node_t* curr; node_t* replace = NULL; // operation_t* pred_op; // operation_t* curr_op; operation_t* replace_op = NULL; operation_t* reloc_op = NULL; bst_search_result_t* my_result; while(TRUE) { //root is now a global pointer to a node, not a node my_result = bst_find(k, /*&pred, &pred_op, &curr, &curr_op,*/ root, root, id); if (my_result->result != FOUND) { return FALSE; } if (ISNULL(my_result->curr->right) || ISNULL(my_result->curr->left)) { // node has less than two children if (CAS_PTR(&(my_result->curr->op), my_result->curr_op, FLAG(my_result->curr_op, STATE_OP_MARK)) == my_result->curr_op) { bst_help_marked(my_result->pred, my_result->pred_op, my_result->curr/*, root*/); return TRUE; } } else { // node has two children node_t* curr = my_result->curr; my_search_result[id]->pred = my_result->pred; my_search_result[id]->pred_op = my_result->pred_op; my_search_result[id]->curr = replace; my_search_result[id]->curr_op = replace_op; // my_result = bst_find(k, &pred, &pred_op, &replace, &replace_op, curr, root, id); my_result = bst_find(k, curr, root, id); if ((my_result->result == ABORT) || (my_result->curr->op != my_result->curr_op)) { continue; } //allocate memory //reloc_op = new RelocateOP(curr, curr_op, k, replace->key); reloc_op = (operation_t*) ssalloc_alloc(1, sizeof(operation_t)); reloc_op->relocate_op.state = STATE_OP_ONGOING; reloc_op->relocate_op.dest = my_result->curr; reloc_op->relocate_op.dest_op = my_result->curr_op; reloc_op->relocate_op.remove_key = k; reloc_op->relocate_op.replace_key = replace->key; // fprintf(stderr, "reloc_op address: %p, state address: %p, dest addr: %p, dest_op addr: %p, remove_key addr: %p, replace_key addr: %p \n", (unsigned long)reloc_op, &(reloc_op->relocate_op.state), &(reloc_op->relocate_op.dest), &(reloc_op->relocate_op.dest_op), &(reloc_op->relocate_op.remove_key), &(reloc_op->relocate_op.replace_key) // ); if (CAS_PTR(&(replace->op), replace_op, FLAG(reloc_op, STATE_OP_RELOCATE)) == replace_op) { if (bst_help_relocate(reloc_op, my_result->pred, my_result->pred_op, replace/*, root*/)) { return TRUE; } } } } }
node_ptr bst_find(bstree bst, element_type e) { if (bst == NULL) return NULL; else if (bst->data < e) { return bst_find(bst->right, e); } else if (bst->data > e) { return bst_find(bst->left, e); } return bst; }
bst_tree_t *bst_find(bst_elem_t value, bst_tree_t *tree) { if (tree == NULL) { return NULL; } if (value < tree->elem) { tree = bst_find(value, tree->left); } else if (value > tree->elem) { tree = bst_find(value, tree->right); } return tree; }
int bst_test() { bst bst; int iRet=1; int i=0; int arry_init[]={5,10,5,20,17,12,19,2}; LOGD("[F:%s, L:%d]\n", __FUNCTION__, __LINE__); //1. construct binary sort tree memset(&bst, 0, sizeof(bst)); bst_insert(&bst, arry_init, sizeof(arry_init)/sizeof(int)); LOGD("[F:%s, L:%d], bst size=%d\n", __FUNCTION__, __LINE__, bst.nBstSize); //2. search item iRet = bst_find(&bst, 17); //3. inorder traverse, print bst_inorderTraverse(&bst); //4. destruct binary sort tree bst_destruct(&bst); return iRet; }
// // Look for key in BST subtree rooted at ptr // Return pointer to found node. // If not found, return NULL. // tnode *bst_find(tnode *ptr, int key) { if (ptr == NULL) return NULL ; if ( ptr->data == key ) { // found? return ptr ; } else if ( ptr->data > key ) { // look in left subtree return bst_find(ptr->left, key) ; } else { // look in right subtree return bst_find(ptr->right, key) ; } }
bool_t bst_remove(bst_key_t k, node_t* root){ node_t* pred; node_t* curr; node_t* replace; operation_t* pred_op; operation_t* curr_op; operation_t* replace_op; operation_t* reloc_op; while(TRUE) { if (bst_find(k, &pred, &pred_op, &curr, &curr_op, root, root) != FOUND) { return FALSE; } if (ISNULL(curr->right) || ISNULL(curr->left)) { // node has less than two children if (CAS_PTR(&(curr->op), curr_op, FLAG(curr_op, STATE_OP_MARK)) == curr_op) { bst_help_marked(pred, pred_op, curr, root); return TRUE; } } else { // node has two children if ((bst_find(k, &pred, &pred_op, &replace, &replace_op, curr, root) == ABORT) || (curr->op != curr_op)) { continue; } reloc_op = (operation_t*) ssalloc_alloc(1, sizeof(operation_t)); reloc_op->relocate_op.state = STATE_OP_ONGOING; reloc_op->relocate_op.dest = curr; reloc_op->relocate_op.dest_op = curr_op; reloc_op->relocate_op.remove_key = k; reloc_op->relocate_op.replace_key = replace->key; #if defined(__tile__) MEM_BARRIER; #endif if (CAS_PTR(&(replace->op), replace_op, FLAG(reloc_op, STATE_OP_RELOCATE)) == replace_op) { if (bst_help_relocate(reloc_op, pred, pred_op, replace, root)) { return TRUE; } } } } }
SplayNode<T>* SplayTree<T>::find(T &val) { SplayNode<T> * find_node = bst_find(root, val); if (find_node != NULL) { splay(find_node, NULL); } return find_node; }
bool_t bst_add(skey_t k,sval_t v, node_t* root){ node_t* pred; node_t* curr; node_t* new_node = NULL; operation_t* pred_op; operation_t* curr_op; operation_t* cas_op; sval_t result; while(TRUE) { UPDATE_TRY(); result = bst_find(k, &pred, &pred_op, &curr, &curr_op, root, root); if (result & val_mask) { #if GC == 1 if (new_node!=NULL) { ssmem_free(alloc,new_node); } #endif return FALSE; } if (new_node == NULL) { new_node = create_node(k,v,0); } bool_t is_left = (result == NOT_FOUND_L); node_t* old; if (is_left) { old = (node_t*) curr->left; } else { old = (node_t*) curr->right; } cas_op = alloc_op(); cas_op->child_cas_op.is_left = is_left; cas_op->child_cas_op.expected = old; cas_op->child_cas_op.update = new_node; #if defined(__tile__) MEM_BARRIER; #endif if (CAS_PTR(&curr->op, curr_op, FLAG(cas_op, STATE_OP_CHILDCAS)) == curr_op) { bst_help_child_cas(cas_op, curr, root); #if GC == 1 //if (UNFLAG(curr_op)!=0) ssmem_free(alloc,(void*)UNFLAG(curr_op)); #endif return TRUE; } else { #if GC == 1 ssmem_free(alloc,cas_op); #endif } } }
void *test(void *data) { fprintf(stderr, "Starting test\n"); //get the per-thread data thread_data_t *d = (thread_data_t *)data; //place the thread on the apropriate cpu set_cpu(the_cores[d->id]); int op_count = 10000; ssalloc_init(); bst_init_local(d->id); /* Wait on barrier */ barrier_cross(d->barrier); int i; bool_t added; for ( i = 1; i <= op_count; i++){ added = bst_insert(i, root, d->id); // fprintf(stderr, "[%d] Added %d? %d\n", d->id, i, added==TRUE); if (added == TRUE) { d->num_insert++; } } // printf("Root right node: %d", root->right->key); for ( i = 1; i <= op_count; i++){ node_t* found = bst_find(i, root, d->id); // printf("Contains %d? %d\n", i, found==FOUND); if (found != NULL) { d->num_search ++; } } for ( i = 1; i <= op_count; i++){ bool_t removed = bst_delete(i, root, d->id); // printf("Removed %d? %d\n", i, removed==TRUE); if (removed == TRUE) { d->num_remove ++; } } // for ( i = 1; i < 10; i++){ // bool_t found = bst_contains(i); // printf("Contains %d? %d\n", i, found==FOUND); // } return NULL; }
SplayNode<T> * SplayTree<T>::bst_find(SplayNode<T> *node, T &key) { if (node == NULL) { return NULL; } if (node->val == key) { return node; } if (node -> val < key) { return bst_find(node->left, key); } else { return bst_find(node->right, key); } }
sval_t bst_contains(skey_t k, node_t* root){ node_t* pred; node_t* curr; operation_t* pred_op; operation_t* curr_op; sval_t res = bst_find(k, &pred, &pred_op, &curr, &curr_op, root, root); if (res & val_mask) return res; return 0; }
bool_t bst_add(bst_key_t k, node_t* root, int id){ //fprintf(stderr, "bst add\n"); // node_t* pred; // node_t* curr; node_t* new_node; // operation_t* pred_op; // operation_t* curr_op; operation_t* cas_op; // search_res_t result; bst_search_result_t* my_result; while(TRUE) { //root is now a global pointer to a node, not a node my_result = bst_find(k, /*&pred, &pred_op, &curr, &curr_op, */root, root, id); if (my_result->result == FOUND) { return FALSE; } // allocate memory // new_node = new Node(k); new_node = (node_t*) ssalloc(sizeof(node_t)); new_node->key = k; new_node->op = NULL; new_node->left = NULL; new_node->right = NULL; // fprintf(stderr, "new_node address: %p, 64bit aligned: %d key address %p, left node addr: %p, right node addr: %p, op addr: %p\n", new_node, ((unsigned long)new_node & 7) == 0,&(new_node->key), &(new_node->left), &(new_node->right), &(new_node->op) // ); bool_t is_left = (my_result->result == NOT_FOUND_L); node_t* old; if (is_left) { old = my_result->curr->left; } else { old = my_result->curr->right; } // allocate memory //cas_op = new child_cas_op_t(is_left, old, new_node) cas_op = (operation_t*) ssalloc_alloc(1, sizeof(operation_t)); cas_op->child_cas_op.is_left = is_left; cas_op->child_cas_op.expected = old; cas_op->child_cas_op.update = new_node; // fprintf(stderr, "cas_op address: %p, is_left address: %p, expected addr: %p, update addr: %p\n", (unsigned long)cas_op, &(cas_op->child_cas_op.is_left), &(cas_op->child_cas_op.expected), &(cas_op->child_cas_op.update) // ); if (CAS_PTR(&(my_result->curr->op), my_result->curr_op, FLAG(cas_op, STATE_OP_CHILDCAS)) == my_result->curr_op) { // legit cast? YES!! verif bst_help_child_cas(cas_op, my_result->curr/*, root*/); return TRUE; } } }
bool_t bst_contains(bst_key_t k, node_t* root, int id){ //fprintf(stderr, "bst contains\n"); // node_t* pred; // node_t* curr; // operation_t* pred_op; // operation_t* curr_op; // root is now a global pointer to a node, not a node return bst_find(k, /*&pred, &pred_op, &curr, &curr_op,*/ root, root, id)->result == FOUND; // return TRUE; }
struct server_child* get_child (int ourid) { ASSERT (ourid > 0); struct server_child temp; temp.ourid = ourid; pthread_mutex_lock (&index.lock); struct server_child* result = (struct server_child*) bst_find (&index.tree, &temp); pthread_mutex_unlock (&index.lock); return result; };
const char* ccl_get(const struct ccl_t *data, const char *key) { const struct ccl_pair_t *pair; struct ccl_pair_t temp; if(data == 0 || key == 0) return 0; temp.key = (char*) key; temp.value = 0; pair = (const struct ccl_pair_t*) bst_find(data->table, &temp); return pair == 0 ? 0 : pair->value; }
/* retrieve a value from a table */ void *ht_get(hashtbl_t * tbl, char *key) { unsigned long h; bstree_t *tree; bst_node_t *treenode; ht_elem_t key_elem; h = tbl->hash((unsigned char *) key) % tbl->arrsz; tree = tbl->arr[h]; if (! tree) /* invalid key - nothing in this slot yet */ return NULL; key_elem.key = key; treenode = bst_find(tree, &key_elem); if (! treenode) return NULL; return ((ht_elem_t *) treenode->data)->data; }
bool_t bst_add(bst_key_t k, node_t* root){ node_t* pred; node_t* curr; node_t* new_node; operation_t* pred_op; operation_t* curr_op; operation_t* cas_op; search_res_t result; while(TRUE) { result = bst_find(k, &pred, &pred_op, &curr, &curr_op, root, root); if (result == FOUND) { return FALSE; } new_node = (node_t*) ssalloc(sizeof(node_t)); new_node->key = k; new_node->op = NULL; new_node->left = NULL; new_node->right = NULL; bool_t is_left = (result == NOT_FOUND_L); node_t* old; if (is_left) { old = curr->left; } else { old = curr->right; } cas_op = (operation_t*) ssalloc_alloc(1, sizeof(operation_t)); cas_op->child_cas_op.is_left = is_left; cas_op->child_cas_op.expected = old; cas_op->child_cas_op.update = new_node; #if defined(__tile__) MEM_BARRIER; #endif if (CAS_PTR(&curr->op, curr_op, FLAG(cas_op, STATE_OP_CHILDCAS)) == curr_op) { bst_help_child_cas(cas_op, curr, root); return TRUE; } } }
void test_bst(test_balanced_t kind) { bstree_t *tree; bst_node_t *node; if (kind == BALANCED) fprintf(stderr, "Testing balanced tree\n"); else if (kind == LEFT_HEAVY) fprintf(stderr, "Testing left-heavy tree\n"); else if (kind == RIGHT_HEAVY) fprintf(stderr, "Testing right-heavy tree\n"); tree = make_tree(kind, 0); ASSERT_TRUE(bst_find(tree, "AAA") != NULL, "bst_find: look up existing value (0)"); ASSERT_TRUE(bst_find(tree, "BBB") != NULL, "bst_find: look up existing value (1)"); ASSERT_TRUE(bst_find(tree, "CCC") != NULL, "bst_find: look up existing value (2)"); ASSERT_TRUE(bst_find(tree, "DDD") == NULL, "bst_find: look up non-existing value"); node = bst_insert(tree, strdup("DDD")); ASSERT_TRUE(bst_find(tree, "DDD") != NULL, "bst_insert: insert an element."); /* This should exercise each path when run for all of the balance kinds. */ bst_delete(tree, "AAA"); ASSERT_TRUE(bst_find(tree, "AAA") == NULL, "bst_delete: remove element A"); bst_delete(tree, "BBB"); ASSERT_TRUE(bst_find(tree, "BBB") == NULL, "bst_delete: remove element B"); bst_delete(tree, "CCC"); ASSERT_TRUE(bst_find(tree, "CCC") == NULL, "bst_delete: remove element C"); bst_delete(tree, "DDD"); ASSERT_TRUE(bst_find(tree, "DDD") == NULL, "bst_delete: remove element D"); bst_destroy(tree); ASSERT_TRUE(tree->root == NULL, "bst_destroy: null out structure."); free(tree); }
/* Put a new key/value pair into a table. */ int ht_put(hashtbl_t * tbl, char *key, void *data) { unsigned long h; bst_node_t *treenode; ht_elem_t *elem, key_elem; key_elem.key = key; elem = mempool_alloc(tbl->ht_elem_pool, sizeof(ht_elem_t)); if (! elem) return -1; elem->key = mempool_alloc(tbl->key_pool, sizeof(char) * strlen(key) + 1); if (! elem->key) { /* elem leaks here, but we cannot free it from the mempool. */ return -1; } strcpy(elem->key, key); elem->data = data; h = tbl->hash((unsigned char *) elem->key) % tbl->arrsz; if (!tbl->arr[h]) { tbl->arr[h] = xmalloc(sizeof(bstree_t)); /* No free() fn for the bst, since its elements are in a mempool. */ bst_init(tbl->arr[h], ht_key_cmp, NULL); bst_insert(tbl->arr[h], elem); tbl->nelems++; return 0; } treenode = bst_find(tbl->arr[h], &key_elem); /* If no match is found, insert the new element and increase the counter. * Otherwise, replace the old data with the new. */ if (!treenode) { bst_insert(tbl->arr[h], elem); tbl->nelems++; } else { if (tbl->free) tbl->free(((ht_elem_t *) treenode->data)->data); treenode->data = elem; } return 0; }
/* remove a key/value pair from a table */ void ht_delete(hashtbl_t * tbl, char *key) { unsigned long h; bstree_t *tree; bst_node_t *treenode; ht_elem_t key_elem; h = tbl->hash((unsigned char *) key) % tbl->arrsz; tree = tbl->arr[h]; if (! tree) /* A NULL slot means the key is unknown. */ return; key_elem.key = key; treenode = bst_find(tree, &key_elem); if (treenode) { if (tbl->free) tbl->free(((ht_elem_t *) treenode->data)->data); bst_delete(tree, &key_elem); tbl->nelems--; } }
void * bstree_get (bstree_table_t *tbl, void *key, int keylen) { bst_entry_t *entry = NULL; bst_entry_t searchentry = {0, }; if ((!tbl) || (!key)) return NULL; searchentry.key = key; searchentry.keylen = keylen; LOCK (&tbl->tablelock); entry = bst_find (tbl->table, &searchentry); UNLOCK (&tbl->tablelock); if (!entry) return NULL; return entry->data; }
int main() { bst_t *tree = (bst_t *) malloc(sizeof(bst_t)); int *found = (int *) malloc(sizeof(int)); printf("Test null tree find\n"); printf("expected value\n"); printf("found: 0, value: -1\n"); printf("actual value\n"); printf("found: %d, value: %d\n\n", *found, bst_find(NULL, 0, found)); printf("Test only head find & insert\n"); printf("expected value\n"); printf("found: 1, value: 10\n"); printf("actual value\n"); bst_insert(tree, 10); printf("found: %d, value: %d\n\n", *found, bst_find(tree, 10, found)); printf("Test level 1 node find & insert\n"); printf("expected value\n"); printf("found: 1, value: 15\n"); printf("actual value\n"); bst_insert(tree, 15); printf("found: %d, value: %d\n\n", *found, bst_find(tree, 15, found)); printf("Test delete\n"); printf("Current Tree\n"); print_tree(tree); printf("Delete 10 Tree\n"); bst_delete(tree, 10); print_tree(tree); printf("Delete 15 Tree\n"); bst_delete(tree, 15); print_tree(tree); printf("Delete value nonexistent Tree\n"); bst_delete(tree, -1); print_tree(tree); printf("\nLarge insert set\n"); bst_insert(tree, 30); bst_insert(tree, 15); bst_insert(tree, 45); bst_insert(tree, 35); bst_insert(tree, 10); bst_insert(tree, 26); bst_insert(tree, 28); bst_insert(tree, 23); bst_insert(tree, 20); bst_insert(tree, 24); bst_insert(tree, 22); bst_insert(tree, 29); printf("Current Tree\n"); print_tree(tree); printf("\nTest two child delete\n"); printf("Delete 15 Tree\n"); bst_delete(tree, 15); print_tree(tree); printf("\nTest one child delete\n"); printf("Delete 28 Tree\n"); bst_delete(tree, 28); print_tree(tree); printf("\nTest no child delete\n"); printf("Delete 29 Tree\n"); bst_delete(tree, 29); print_tree(tree); printf("\nTest delete root from large tree\n"); printf("Delete 30 Tree\n"); bst_delete(tree, 30); print_tree(tree); //gotta stay squeaky clean delete_tree(tree); free(found); }
sval_t bst_remove(skey_t k, node_t* root){ node_t* pred; node_t* curr; node_t* replace; sval_t val; operation_t* pred_op; operation_t* curr_op; operation_t* replace_op; operation_t* reloc_op=NULL; while(TRUE) { UPDATE_TRY(); sval_t res = bst_find(k, &pred, &pred_op, &curr, &curr_op, root, root); if (!(res & val_mask)) { #if GC == 1 //if (reloc_op!=NULL) ssmem_free(alloc,reloc_op); #endif return 0; } if (ISNULL((node_t*) curr->right) || ISNULL((node_t*) curr->left)) { // node has less than two children if (CAS_PTR(&(curr->op), curr_op, FLAG(curr_op, STATE_OP_MARK)) == curr_op) { bst_help_marked(pred, pred_op, curr, root); #if GC == 1 //if (reloc_op!=NULL) ssmem_free(alloc,reloc_op); if (UNFLAG(curr->op)!=0) ssmem_free(alloc,(void*)UNFLAG(curr->op)); ssmem_free(alloc,curr); #endif return res; } } else { // node has two children val = bst_find(k, &pred, &pred_op, &replace, &replace_op, curr, root); if ((val == ABORT) || (curr->op != curr_op)) { continue; } //if (reloc_op==NULL) { reloc_op = alloc_op(); //} reloc_op->relocate_op.state = STATE_OP_ONGOING; reloc_op->relocate_op.dest = curr; reloc_op->relocate_op.dest_op = curr_op; reloc_op->relocate_op.remove_key = k; reloc_op->relocate_op.remove_value = res; reloc_op->relocate_op.replace_key = replace->key; reloc_op->relocate_op.replace_value = replace->value; #if defined(__tile__) MEM_BARRIER; #endif if (CAS_PTR(&(replace->op), replace_op, FLAG(reloc_op, STATE_OP_RELOCATE)) == replace_op) { #if GC == 1 if (UNFLAG(replace_op)!=0) ssmem_free(alloc,(void*)UNFLAG(replace_op)); #endif if (bst_help_relocate(reloc_op, pred, pred_op, replace, root)) { //if (UNFLAG(replace->op)!=0) ssmem_free(alloc,(void*)UNFLAG(replace->op)); #if GC == 1 //ssmem_free(alloc,replace); #endif return res; } } else { #if GC == 1 ssmem_free(alloc,reloc_op); // reloc_op=NULL; #endif } } } }