atn* avl_tree_search(atn* node,avl_search_input_type data){ int i; if(node){ i=avl_search_compare(node->data,data); if(i==0) return node; if(i<0) return avl_tree_search(node->left,data); return avl_tree_search(node->right,data); } return 0; }
int main(int argc, char *argv[]) { int idx; avl_tree_t *tree; if (!(tree = avl_tree_init((cmp_t *)cmp))) { fprintf(stderr, "error on avl_tree_init\n"); return -1; } for (idx = 0; idx < sizeof(test_ints)/sizeof(test_ints[0]); idx++) { #if RAND_TEST test_ints[idx] = rand(); if (test_ints[idx] == 0) { test_ints[idx]++; } #endif if (avl_tree_insert(tree, &test_ints[idx]) < 0) { fprintf(stderr, "error on avl_tree_insert\n"); return -1; } } /* printf("%s", avl_tree_str(tree, node2s)); */ if (iter_list(tree, !RAND_TEST)) { return -1; } /* printf("\n"); */ for (idx = 0; idx < 20; idx++) { if (*(int *)avl_tree_search(tree, &test_ints[idx]) != test_ints[idx]) { fprintf(stderr, "error on avl_tree_search\n"); return -1; } } #if RAND_TEST for (idx = 0; idx < sizeof(test_ints)/sizeof(test_ints[0])/2; idx++) { avl_tree_delete(tree, &test_ints[idx]); } #else avl_tree_delete(tree, &test_ints[6]); avl_tree_delete(tree, &test_ints[2]); avl_tree_delete(tree, &test_ints[1]); avl_tree_delete(tree, &test_ints[9]); avl_tree_delete(tree, &test_ints[11]); avl_tree_delete(tree, &test_ints[4]); #endif /* printf("%s", avl_tree_str(tree, node2s)); */ if (iter_list(tree, !RAND_TEST)) { return -1; } printf("Test successful!\n"); return 0; }
//you should get down_write for inode_inf before running this function int add_event_to_inode( struct inode* inode, unsigned short child_index, unsigned char type, void* data, unsigned int datalen, unsigned char flags){ struct avl_tree_node* atn; struct GSFS_inode* inode_info=(struct GSFS_inode*)inode->i_private; struct child* child; int ret; if(unlikely(type>=Events_Num)) return -1; ret=0; atn=avl_tree_search( inode_info->children, child_index); if(atn){ child=atn->data; //printk("<0>" "add event to inode: pino:%lu index:%d type%d len:%d\n",inode->i_ino, child_index, type,datalen); } else{ //be care full that it is possible to go here for example //for traverse all gdirents for a has_sec_child dir //therefore we should make this part active to add child gt(printk("<0>" "add event to inode with no child_index: pino:%lu index:%d type:%d len:%d\n",inode->i_ino, child_index, type,datalen)); child=kzalloc(sizeof(struct child),GFP_KERNEL); child->index=child_index; inode_info->children=avl_tree_insert(inode_info->children, child); if(!inode_info->children){ printk("<1>" "Some errors in inserting new child_events.\n"); ret=-1; } if(ret==-1) goto back; } if(child->events[type].flags & event_flag_is_present) if(child->events[type].data) if(child->events[type].data != data) free_one_present_event(&child->events[type],type); child->events[type].data=data; child->events[type].datalen=datalen; child->events[type].flags=flags|event_flag_is_present; back: //print_all_events(child); return ret; }
//you should get down_read for inf->inode_rwsem before running this function int get_event(struct GSFS_inode* inf, unsigned short child_index,unsigned char type, void* data, unsigned int* len){ atn* res; struct child* child; int ret=-1; //printk("<0>" "get_event for inode:%u child_index:%d type:%d\n",inf->disk_info.ino, child_index, type); res=avl_tree_search(inf->children, child_index); if(res){ child=res->data; if(child->events[type].flags & event_flag_is_present){ ret=0; memcpy(data, child->events[type].data, EventsLen[type]); *len=child->events[type].datalen; //printk("<0>" "get_event: len:%d, data:\n",*len); //printkey(data); } //print_all_events(res->data); } return ret; }
void perform_avl_tree_test (avl_tree_t *avlt, int use_odd_numbers) { int i, lo, hi, d, fail_search; int rv; int fine, not_fine; char *oddness = use_odd_numbers ? "odd" : "even"; char *reverse = use_odd_numbers ? "even" : "odd"; unsigned long long int bytes_used; double megabytes_used; void *fwdata, *searched, *found, *removed; chunk_manager_parameters_t chparams; printf("size of ONE avl node is: %lu bytes\n", sizeof(avl_node_t)); /* ** Fill opposing ends of array, converge in middle. ** This gives some sort of randomness to data. */ printf("filling array of size %d with %s number data\n", MAX_SZ, oddness); d = use_odd_numbers ? 1 : 0; lo = 0; hi = MAX_SZ - 1; while (1) { data[lo++] = d; d += 2; data[hi--] = d; d += 2; if (lo > hi) break; } if (max_value_reached < d) { max_value_reached = d + 10; printf("max value recorded so far is %d\n", max_value_reached); } chparams.initial_number_of_chunks = max_value_reached + 10; chparams.grow_size = 1024; avl_tree_init(avlt, 1, int_compare, NULL, &chparams); /* enter all array data into avl tree */ printf("now entering all %s number data into the avl tree\n", oddness); timer_start(&timr); for (i = 0; i < MAX_SZ; i++) { fwdata = &data[i]; rv = avl_tree_insert(avlt, fwdata, &found); if (rv != 0) { printf("populate_data: avl_tree_insert error: %d failed\n", i); } } timer_end(&timr); timer_report(&timr, MAX_SZ, NULL); OBJECT_MEMORY_USAGE(avlt, bytes_used, megabytes_used); printf("total memory used by the avl tree of %d nodes: %llu bytes (%lf Mbytes)\n", avlt->n, bytes_used, megabytes_used); printf("searching for non existant data\n"); fine = not_fine = 0; timer_start(&timr); for (i = max_value_reached; i < (max_value_reached + EXTRA); i++) { searched = &i; rv = avl_tree_search(avlt, searched, &found); if ((rv == 0) || found) { not_fine++; } else { fine++; } } timer_end(&timr); timer_report(&timr, EXTRA, NULL); printf("expected %d, NOT expected %d\n", fine, not_fine); /* now search all data that should be found (all of them) */ printf("now searching all %s numbers in the avl tree\n", oddness); fine = not_fine = 0; timer_start(&timr); for (i = 0; i < MAX_SZ; i++) { searched = &data[i]; rv = avl_tree_search(avlt, searched, &found); if ((rv != 0) || (data[i] != *((int*) found))) { not_fine++; } else { fine++; } } timer_end(&timr); timer_report(&timr, MAX_SZ, NULL); printf("found %d as expected and %d as NOT expected\n", fine, not_fine); /* now search for all entries that should NOT be in the tree */ printf("now searching for all %s numbers in the avl tree\n", reverse); fine = not_fine = 0; d = use_odd_numbers ? 0 : 1; timer_start(&timr); for (i = 0; i < MAX_SZ; i++) { searched = &d; rv = avl_tree_search(avlt, searched, &found); if ((rv == 0) || found) { not_fine++; } else { fine++; } d += 2; } timer_end(&timr); timer_report(&timr, MAX_SZ, NULL); printf("%d as expected and %d as NOT expected\n", fine, not_fine); #if 0 int tree_nodes = avlt->n; printf("now deleting the whole tree (%d nodes)\n", tree_nodes); timer_start(&timr); avl_tree_destroy(avlt); timer_end(&timr); timer_report(&timr, tree_nodes, NULL); return; #endif // 0 /* now delete one entry at a time and search it (should not be there) */ printf("now deleting and searching\n"); fine = not_fine = fail_search = 0; timer_start(&timr); for (i = 0; i < MAX_SZ; i++) { searched = &data[i]; rv = avl_tree_remove(avlt, searched, &removed); if ((rv != 0) || (data[i] != *((int*) removed))) { not_fine++; } else { fine++; } rv = avl_tree_search(avlt, searched, &found); if ((rv == 0) || found) { fail_search++; } } timer_end(&timr); timer_report(&timr, MAX_SZ*2, NULL); printf("deleted %d, could NOT delete %d, erroneous search %d\n", fine, not_fine, fail_search); OBJECT_MEMORY_USAGE(avlt, bytes_used, megabytes_used); printf("total memory used by the avl tree (%d nodes) after deletes: " "%llu bytes (%f Mbytes)\n", avlt->n, bytes_used, megabytes_used); avl_tree_destroy(avlt); }