void test_inserting_and_finding() { struct avl_tree_node* root; int* value; root = avl_tree_create(); root = avl_tree_insert(root, "esa", 3); root = avl_tree_insert(root, "vesa", 4); root = avl_tree_insert(root, "vvv", 5); root = avl_tree_insert(root, "aaa", 7); value = avl_tree_find(root, "vesa"); assertIntEquals(4, *value); value = avl_tree_find(root, "esa"); assertIntEquals(3, *value); value = avl_tree_find(root, "vvv"); assertIntEquals(5, *value); value = avl_tree_find(root, "aaa"); assertIntEquals(7, *value); value = avl_tree_find(root, "bbb"); assertNull(value); avl_tree_destroy(root); }
void test_insertion() { struct avl_tree_node* root; root = avl_tree_create(); root = avl_tree_insert(root, "esa", 0); root = avl_tree_insert(root, "vesa", 1); root = avl_tree_insert(root, "hesa", 2); avl_tree_destroy(root); }
void test_inserting() { struct avl_tree_node* root; root = avl_tree_create(); root = avl_tree_insert(root, "esa", 3); root = avl_tree_insert(root, "vesa", 4); root = avl_tree_insert(root, "vvv", 5); root = avl_tree_insert(root, "aaa", 7); avl_tree_destroy(root); }
void test_for_each() { struct avl_tree_node* root; root = avl_tree_create(); root = avl_tree_insert(root, "aaa", 3); root = avl_tree_insert(root, "vesa", 5); root = avl_tree_insert(root, "esa", 7); TOTAL = 1; avl_tree_for_each(root, test_function); assertIntEquals(3*5*7, TOTAL); avl_tree_destroy(root); }
void avl_tree_find_median ( void ) { AVLTree * t = init_avl_tree(sizeof(IntBucket), &bucket_int_compare); IntBucket * median; IntBucket ib[] = { {30272}, {16274}, {11768}, {10231}, {28474}, { 7272}, {15032}, {13196}, {29825}, { 6840}, {18444}, {18793}, {13786}, {21125}, {25311}, {23414}, {18374}, {24110}, {15465}, {26300}, { 1181}, { 6297}, { 3693}, {20957}, {22585}, { 8915}, {30371}, { 2036}, {18499}, {18391}, {15360}, {32509}, {23336}, {18848}, {25712}, { 6162}, { 1483}, { 4309}, {13482}, {14809}, { 5596}, {22524}, {13958}, {16918}, {25668}, {31621}, {30060}, {24637}, {28116}, {15994}, {30595}, {30642}, {30017}, { 7221}, { 2916}, { 7010}, {29356}, {22282}, {30649}, {17493}, {28780}, { 6725}, {26998}, {28805}, {24689}, {25547}, {17625}, {14250}, {11250}, {16195}, { 9542}, {26029}, { 2734}, {23373}, {21176}, {28102}, { 1894}, { 325}, { 9406}, { 4915}, { 8759}, {32413}, {14144}, { 5394}, { 3495}, {32030}, {23904}, { 4260}, {11579}, {11100}, {27212}, {20562}, {30264}, {30850}, {22393}, {28107}, {21299}, {25306}, { 2668}, { 3894}, }; int i; for ( i = 0; i < 100; i += 1 ) { avl_tree_insert(t, ib+i); } median = (IntBucket*)(avl_tree_get_median(t)->bucket); ASSERT(median->p == 18391, "Wrong median!"); destroy_avl_tree(t); }
void avl_test_find_node ( void ) { AVLTree * t = init_avl_tree(sizeof(IntBucket), &bucket_int_compare); BTNode * found; IntBucket x; IntBucket ib[] = { {30272}, {16274}, {11768}, {10231}, {28474}, { 7272}, {15032}, {13196}, {29825}, { 6840}, {18444}, {18793}, {13786}, {21125}, {25311}, {23414}, {18374}, {24110}, {15465}, {26300}, { 1181}, { 6297}, { 3693}, {20957}, {22585}, { 8915}, {30371}, { 2036}, {18499}, {18391}, {15360}, {32509}, {23336}, {18848}, {25712}, { 6162}, { 1483}, { 4309}, {13482}, {14809}, { 5596}, {22524}, {13958}, {16918}, {25668}, {31621}, {30060}, {24637}, {28116}, {15994}, {30595}, {30642}, {30017}, { 7221}, { 2916}, { 7010}, {29356}, {22282}, {30649}, {17493}, {28780}, { 6725}, {26998}, {28805}, {24689}, {25547}, {17625}, {14250}, {11250}, {16195}, { 9542}, {26029}, { 2734}, {23373}, {21176}, {28102}, { 1894}, { 325}, { 9406}, { 4915}, { 8759}, {32413}, {14144}, { 5394}, { 3495}, {32030}, {23904}, { 4260}, {11579}, {11100}, {27212}, {20562}, {30264}, {30850}, {22393}, {28107}, {21299}, {25306}, { 2668}, { 3894}, }; int i; for ( i = 0; i < 100; i += 1 ) { avl_tree_insert(t, ib+i); } ASSERT(avl_verify_consistency(t, t->root), "Tree starting inconsistent."); x.p = 700; ASSERT(NULL == avl_find_exact ( t, &x ), "Found an element that wasn't there ..."); x.p = 26029; ASSERT( ((IntBucket*)(avl_find_exact(t,&x)->bucket))->p == 26029, "Couldn't find an easy one."); destroy_avl_tree(t); }
void test_avl_tree_to_array(void) { AVLTree *tree; int entries[] = { 89, 23, 42, 4, 16, 15, 8, 99, 50, 30 }; int sorted[] = { 4, 8, 15, 16, 23, 30, 42, 50, 89, 99 }; int num_entries = sizeof(entries) / sizeof(int); int i; int **array; /* Add all entries to the tree */ tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i<num_entries; ++i) { avl_tree_insert(tree, &entries[i], NULL); } assert(avl_tree_num_entries(tree) == num_entries); /* Convert to an array and check the contents */ array = (int **) avl_tree_to_array(tree); for (i=0; i<num_entries; ++i) { assert(*array[i] == sorted[i]); } free(array); }
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; }
/** Create a new semaphore. * @param name Optional name for the semaphore, for debugging purposes. * @param count Initial count of the semaphore. * @param security Security attributes for the ACL. If NULL, default * attributes will be constructed which grant full access * to the semaphore to the calling process' user. * @param rights Access rights for the handle. * @param handlep Where to store handle to the semaphore. * @return Status code describing result of the operation. */ status_t kern_semaphore_create(const char *name, size_t count, const object_security_t *security, object_rights_t rights, handle_t *handlep) { object_security_t ksecurity = { -1, -1, NULL }; user_semaphore_t *sem; status_t ret; if(!handlep) return STATUS_INVALID_ARG; if(security) { ret = object_security_from_user(&ksecurity, security, true); if(ret != STATUS_SUCCESS) return ret; } /* Construct a default ACL if required. */ if(!ksecurity.acl) { ksecurity.acl = kmalloc(sizeof(*ksecurity.acl), MM_WAIT); object_acl_init(ksecurity.acl); object_acl_add_entry(ksecurity.acl, ACL_ENTRY_USER, -1, SEMAPHORE_RIGHT_USAGE); } sem = kmalloc(sizeof(user_semaphore_t), MM_WAIT); sem->id = id_allocator_alloc(&semaphore_id_allocator); if(sem->id < 0) { kfree(sem); object_security_destroy(&ksecurity); return STATUS_NO_SEMAPHORES; } if(name) { ret = strndup_from_user(name, SEMAPHORE_NAME_MAX, &sem->name); if(ret != STATUS_SUCCESS) { id_allocator_free(&semaphore_id_allocator, sem->id); kfree(sem); object_security_destroy(&ksecurity); return ret; } } else { sem->name = NULL; } object_init(&sem->obj, &semaphore_object_type, &ksecurity, NULL); object_security_destroy(&ksecurity); semaphore_init(&sem->sem, (sem->name) ? sem->name : "user_semaphore", count); refcount_set(&sem->count, 1); rwlock_write_lock(&semaphore_tree_lock); avl_tree_insert(&semaphore_tree, &sem->tree_link, sem->id, sem); rwlock_unlock(&semaphore_tree_lock); ret = object_handle_create(&sem->obj, NULL, rights, NULL, 0, NULL, NULL, handlep); if(ret != STATUS_SUCCESS) user_semaphore_release(sem); return ret; }
static VALUE avl_tree_rinsert( VALUE self, VALUE obj ) { avl_tree_r *t; avl_tree_elem elem = (avl_tree_elem *)obj; Data_Get_Struct( self, avl_tree_r, t ); t->root = avl_tree_insert( t->root, elem, cmp ); return obj; }
//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; }
void test_finding() { struct avl_tree_node* root; int* value; root = avl_tree_create(); root = avl_tree_insert(root, "esa", 3); value = avl_tree_find(root, "vesa"); assertNull(value); value = avl_tree_find(root, "esa"); assertIntEquals(3, *value); avl_tree_destroy(root); }
AVLTree *create_tree(void) { AVLTree *tree; int i; /* Create a tree and fill with nodes */ tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i<NUM_TEST_VALUES; ++i) { test_array[i] = i; avl_tree_insert(tree, &test_array[i], &test_array[i]); } return tree; }
void avl_tree_traverse_test ( void ) { AVLTree * t = init_avl_tree(sizeof(IntBucket), &bucket_int_compare); IntBucket bucket; int i; srand(12345678); for ( i = 0; i < 1000; i += 1 ) { bucket.p = rand(); avl_tree_insert(t, &bucket); } avl_tree_traverse(t, doit); destroy_avl_tree(t); }
void avl_tree_insert_random ( void ) { AVLTree * t = init_avl_tree(sizeof(IntBucket), &bucket_int_compare); IntBucket bucket; int i; srand(12345678); for ( i = 0; i < 100000; i += 1 ) { bucket.p = rand(); avl_tree_insert(t, &bucket); ASSERT(t->root->count == i+1, "Wrong count after insert"); } ASSERT(avl_verify_consistency(t, t->root)==true, "Tree inconsistent after insert"); destroy_avl_tree(t); }
void avl_tree_test_delete ( void ) { AVLTree * t = init_avl_tree(sizeof(IntBucket), &bucket_int_compare); BTNode * median_node; IntBucket x; IntBucket ib[] = { {30272}, {16274}, {11768}, {10231}, {28474}, { 7272}, {15032}, {13196}, {29825}, { 6840}, {18444}, {18793}, {13786}, {21125}, {25311}, {23414}, {18374}, {24110}, {15465}, {26300}, { 1181}, { 6297}, { 3693}, {20957}, {22585}, { 8915}, {30371}, { 2036}, {18499}, {18391}, {15360}, {32509}, {23336}, {18848}, {25712}, { 6162}, { 1483}, { 4309}, {13482}, {14809}, { 5596}, {22524}, {13958}, {16918}, {25668}, {31621}, {30060}, {24637}, {28116}, {15994}, {30595}, {30642}, {30017}, { 7221}, { 2916}, { 7010}, {29356}, {22282}, {30649}, {17493}, {28780}, { 6725}, {26998}, {28805}, {24689}, {25547}, {17625}, {14250}, {11250}, {16195}, { 9542}, {26029}, { 2734}, {23373}, {21176}, {28102}, { 1894}, { 325}, { 9406}, { 4915}, { 8759}, {32413}, {14144}, { 5394}, { 3495}, {32030}, {23904}, { 4260}, {11579}, {11100}, {27212}, {20562}, {30264}, {30850}, {22393}, {28107}, {21299}, {25306}, { 2668}, { 3894}, }; int i; for ( i = 0; i < 100; i += 1 ) { avl_tree_insert(t, ib+i); } ASSERT(avl_verify_consistency(t, t->root), "Tree starting inconsistent."); median_node = avl_tree_get_median(t); avl_delete_node(t, median_node); ASSERT(avl_verify_consistency(t, t->root), "Tree inconsistent after delete."); median_node = avl_tree_get_median(t); ASSERT( ((IntBucket*)(median_node->bucket))->p == 18374, "Wrong median after delete." ); while ( t->root->count > 1 ) { avl_delete_node(t, t->root); ASSERT(avl_verify_consistency(t, t->root), "Tree inconsistent after delete."); } avl_delete_node(t, t->root); x.p = 99; avl_tree_insert(t, &x); x.p = 199; avl_tree_insert(t, &x); x.p = 299; avl_tree_insert(t, &x); x.p = 399; avl_tree_insert(t, &x); x.p = 499; avl_tree_insert(t, &x); ASSERT(5 == t->root->count, "Wrong count after 5 inserts."); ASSERT(avl_verify_consistency(t, t->root), "Tree inconsistent after 5 inserts."); avl_delete_node(t, t->root->right); ASSERT(4 == t->root->count, "Wrong count after first delete."); ASSERT(avl_verify_consistency(t, t->root), "Tree inconsistent after first delete."); destroy_avl_tree(t); }
void test_that_keys_are_copied() { struct avl_tree_node* root; int* value; char key[] = "esa"; root = avl_tree_create(); root = avl_tree_insert(root, key, 3); value = avl_tree_find(root, "esa"); assertIntEquals(3, *value); key[0] = 'a'; value = avl_tree_find(root, "esa"); assertIntEquals(3, *value); avl_tree_destroy(root); }
void test_avl_tree_child(void) { AVLTree *tree; AVLTreeNode *root; AVLTreeNode *left; AVLTreeNode *right; int values[] = { 1, 2, 3 }; int *p; int i; /* Create a tree containing some values. Validate the * tree is consistent at all stages. */ tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i<3; ++i) { avl_tree_insert(tree, &values[i], &values[i]); } /* Check the tree */ root = avl_tree_root_node(tree); p = avl_tree_node_value(root); assert(*p == 2); left = avl_tree_node_child(root, AVL_TREE_NODE_LEFT); p = avl_tree_node_value(left); assert(*p == 1); right = avl_tree_node_child(root, AVL_TREE_NODE_RIGHT); p = avl_tree_node_value(right); assert(*p == 3); /* Check invalid values */ assert(avl_tree_node_child(root, -1) == NULL); assert(avl_tree_node_child(root, 10000) == NULL); assert(avl_tree_node_child(root, 2) == NULL); assert(avl_tree_node_child(root, -100000) == NULL); avl_tree_free(tree); }
void test_avl_tree_insert_lookup(void) { AVLTree *tree; AVLTreeNode *node; int i; int *value; /* Create a tree containing some values. Validate the * tree is consistent at all stages. */ tree = avl_tree_new((AVLTreeCompareFunc) int_compare); for (i=0; i<NUM_TEST_VALUES; ++i) { test_array[i] = i; avl_tree_insert(tree, &test_array[i], &test_array[i]); assert(avl_tree_num_entries(tree) == i + 1); validate_tree(tree); } assert(avl_tree_root_node(tree) != NULL); /* Check that all values can be read back again */ for (i=0; i<NUM_TEST_VALUES; ++i) { node = avl_tree_lookup_node(tree, &i); assert(node != NULL); value = avl_tree_node_key(node); assert(*value == i); value = avl_tree_node_value(node); assert(*value == i); } /* Check that invalid nodes are not found */ i = -1; assert(avl_tree_lookup_node(tree, &i) == NULL); i = NUM_TEST_VALUES + 100; assert(avl_tree_lookup_node(tree, &i) == NULL); avl_tree_free(tree); }
int trunk_free_block_insert(FDFSTrunkFullInfo *pTrunkInfo) { int result; FDFSTrunkFileIdentifier target; FDFSTrunksById *pTrunksById; FILL_FILE_IDENTIFIER(target, pTrunkInfo); pTrunksById = (FDFSTrunksById *)avl_tree_find(&tree_info_by_id, &target); if (pTrunksById == NULL) { pTrunksById = (FDFSTrunksById *)malloc(sizeof(FDFSTrunksById)); if (pTrunksById == NULL) { result = errno != 0 ? errno : ENOMEM; logError("file: "__FILE__", line: %d, " \ "malloc %d bytes fail, " \ "errno: %d, error info: %s", \ __LINE__, (int)sizeof(FDFSTrunksById), \ result, STRERROR(result)); return result; } memset(pTrunksById, 0, sizeof(FDFSTrunksById)); memcpy(&(pTrunksById->trunk_file_id), &target, \ sizeof(FDFSTrunkFileIdentifier)); if (avl_tree_insert(&tree_info_by_id, pTrunksById) != 1) { result = errno != 0 ? errno : ENOMEM; logError("file: "__FILE__", line: %d, " \ "avl_tree_insert fail, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } } return trunk_free_block_do_insert(pTrunkInfo, \ &(pTrunksById->block_array)); }
static int storage_trunk_restore(const int64_t restore_offset) { int64_t trunk_binlog_size; int64_t line_count; TrunkBinLogReader reader; TrunkBinLogRecord record; char trunk_mark_filename[MAX_PATH_SIZE]; char buff[256]; int record_length; int result; AVLTreeInfo tree_info_by_offset; struct fast_mblock_node *pMblockNode; FDFSTrunkNode *pTrunkNode; FDFSTrunkNode trunkNode; bool trunk_init_reload_from_binlog; trunk_binlog_size = storage_trunk_get_binlog_size(); if (trunk_binlog_size < 0) { return errno != 0 ? errno : EPERM; } if (restore_offset == trunk_binlog_size) { return 0; } if (restore_offset > trunk_binlog_size) { logWarning("file: "__FILE__", line: %d, " \ "restore_offset: %"PRId64 \ " > trunk_binlog_size: %"PRId64, \ __LINE__, restore_offset, trunk_binlog_size); return storage_trunk_save(); } logDebug("file: "__FILE__", line: %d, " \ "trunk metadata recovering, start offset: " \ "%"PRId64", need recovery binlog bytes: " \ "%"PRId64, __LINE__, \ restore_offset, trunk_binlog_size - restore_offset); trunk_init_reload_from_binlog = (restore_offset == 0); if (trunk_init_reload_from_binlog) { memset(&trunkNode, 0, sizeof(trunkNode)); if ((result=avl_tree_init(&tree_info_by_offset, \ storage_trunk_free_node, \ storage_trunk_node_compare_offset)) != 0) { logError("file: "__FILE__", line: %d, " \ "avl_tree_init fail, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } } memset(&record, 0, sizeof(record)); memset(&reader, 0, sizeof(reader)); reader.binlog_offset = restore_offset; if ((result=trunk_reader_init(NULL, &reader)) != 0) { return result; } line_count = 0; while (1) { record_length = 0; result = trunk_binlog_read(&reader, &record, &record_length); if (result != 0) { if (result == ENOENT) { if (record_length > 0) //skip incorrect record { line_count++; reader.binlog_offset += record_length; continue; } result = (reader.binlog_offset >= \ trunk_binlog_size) ? 0 : EINVAL; if (result != 0) { logError("file: "__FILE__", line: %d, " \ "binlog offset: %"PRId64 \ " < binlog size: %"PRId64 \ ", please check the end of trunk " \ "binlog", __LINE__, \ reader.binlog_offset, trunk_binlog_size); } } break; } line_count++; if (record.op_type == TRUNK_OP_TYPE_ADD_SPACE) { record.trunk.status = FDFS_TRUNK_STATUS_FREE; if (trunk_init_reload_from_binlog) { pMblockNode = fast_mblock_alloc(&free_blocks_man); if (pMblockNode == NULL) { result = errno != 0 ? errno : EIO; logError("file: "__FILE__", line: %d, "\ "malloc %d bytes fail, " \ "errno: %d, error info: %s", \ __LINE__, \ (int)sizeof(FDFSTrunkNode), \ result, STRERROR(result)); return result; } pTrunkNode = (FDFSTrunkNode *)pMblockNode->data; memcpy(&pTrunkNode->trunk, &(record.trunk), \ sizeof(FDFSTrunkFullInfo)); pTrunkNode->pMblockNode = pMblockNode; pTrunkNode->next = NULL; result = avl_tree_insert(&tree_info_by_offset,\ pTrunkNode); if (result < 0) //error { result *= -1; logError("file: "__FILE__", line: %d, "\ "avl_tree_insert fail, " \ "errno: %d, error info: %s", \ __LINE__, result, \ STRERROR(result)); return result; } else if (result == 0) { trunk_info_dump(&(record.trunk), \ buff, sizeof(buff)); logWarning("file: "__FILE__", line: %d"\ ", trunk data line: " \ "%"PRId64", trunk "\ "space already exist, "\ "trunk info: %s", \ __LINE__, line_count, buff); } } else if ((result=trunk_add_space_by_trunk( \ &record.trunk)) != 0) { break; } } else if (record.op_type == TRUNK_OP_TYPE_DEL_SPACE) { record.trunk.status = FDFS_TRUNK_STATUS_FREE; if (trunk_init_reload_from_binlog) { memcpy(&trunkNode.trunk, &record.trunk, \ sizeof(FDFSTrunkFullInfo)); if (avl_tree_delete(&tree_info_by_offset,\ &trunkNode) != 1) { trunk_info_dump(&(record.trunk), \ buff, sizeof(buff)); logWarning("file: "__FILE__", line: %d"\ ", binlog offset: %"PRId64 \ ", trunk data line: %"PRId64 \ " trunk node not exist, " \ "trunk info: %s", __LINE__, \ reader.binlog_offset, \ line_count, buff); } } else if ((result=trunk_delete_space( \ &record.trunk, false)) != 0) { if (result == ENOENT) { logDebug("file: "__FILE__", line: %d, "\ "binlog offset: %"PRId64 \ ", trunk data line: %"PRId64,\ __LINE__, reader.binlog_offset, \ line_count); result = 0; } else { break; } } } reader.binlog_offset += record_length; } trunk_reader_destroy(&reader); trunk_mark_filename_by_reader(&reader, trunk_mark_filename); if (unlink(trunk_mark_filename) != 0) { logError("file: "__FILE__", line: %d, " \ "unlink file %s fail, " \ "errno: %d, error info: %s", __LINE__, \ trunk_mark_filename, errno, STRERROR(errno)); } if (result != 0) { if (trunk_init_reload_from_binlog) { avl_tree_destroy(&tree_info_by_offset); } logError("file: "__FILE__", line: %d, " \ "trunk load fail, errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); return result; } if (trunk_init_reload_from_binlog) { logInfo("file: "__FILE__", line: %d, " \ "free tree node count: %d", \ __LINE__, avl_tree_count(&tree_info_by_offset)); result = avl_tree_walk(&tree_info_by_offset, \ storage_trunk_add_free_blocks_callback, NULL); tree_info_by_offset.free_data_func = NULL; avl_tree_destroy(&tree_info_by_offset); } if (result == 0) { logDebug("file: "__FILE__", line: %d, " \ "trunk metadata recovery done. start offset: " \ "%"PRId64", recovery file size: " \ "%"PRId64, __LINE__, \ restore_offset, trunk_binlog_size - restore_offset); return storage_trunk_save(); } return result; }
static int storage_do_split_trunk_binlog(const int store_path_index, StorageBinLogReader *pReader) { FILE *fp; char *pBasePath; FDFSTrunkFileIdInfo *pFound; char binlogFullFilename[MAX_PATH_SIZE]; char tmpFullFilename[MAX_PATH_SIZE]; FDFSTrunkFullInfo trunk_info; FDFSTrunkFileIdInfo trunkFileId; StorageBinLogRecord record; AVLTreeInfo tree_unique_trunks; int record_length; int result; pBasePath = g_fdfs_store_paths.paths[store_path_index]; recovery_get_full_filename(pBasePath, \ RECOVERY_BINLOG_FILENAME".tmp", tmpFullFilename); fp = fopen(tmpFullFilename, "w"); if (fp == NULL) { result = errno != 0 ? errno : EPERM; logError("file: "__FILE__", line: %d, " \ "open file: %s fail, " \ "errno: %d, error info: %s.", \ __LINE__, tmpFullFilename, result, STRERROR(result)); return result; } if ((result=avl_tree_init(&tree_unique_trunks, free, \ storage_compare_trunk_id_info)) != 0) { logError("file: "__FILE__", line: %d, " \ "avl_tree_init fail, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); fclose(fp); return result; } memset(&trunk_info, 0, sizeof(trunk_info)); memset(&trunkFileId, 0, sizeof(trunkFileId)); result = 0; while (g_continue_flag) { result=storage_binlog_read(pReader, &record, &record_length); if (result != 0) { if (result == ENOENT) { result = 0; } break; } if (fdfs_is_trunk_file(record.filename, record.filename_len)) { if (fdfs_decode_trunk_info(store_path_index, \ record.true_filename, record.true_filename_len,\ &trunk_info) != 0) { continue; } trunkFileId.path = trunk_info.path; trunkFileId.id = trunk_info.file.id; pFound = (FDFSTrunkFileIdInfo *)avl_tree_find( \ &tree_unique_trunks, &trunkFileId); if (pFound != NULL) { continue; } pFound = (FDFSTrunkFileIdInfo *)malloc( \ sizeof(FDFSTrunkFileIdInfo)); if (pFound == NULL) { result = errno != 0 ? errno : ENOMEM; logError("file: "__FILE__", line: %d, " \ "malloc %d bytes fail, " \ "errno: %d, error info: %s", __LINE__,\ (int)sizeof(FDFSTrunkFileIdInfo), \ result, STRERROR(result)); break; } sprintf(trunkFileId.line, "%d %c %s", \ (int)record.timestamp, \ record.op_type, record.filename); memcpy(pFound, &trunkFileId, sizeof(FDFSTrunkFileIdInfo)); if (avl_tree_insert(&tree_unique_trunks, pFound) != 1) { result = errno != 0 ? errno : ENOMEM; logError("file: "__FILE__", line: %d, " \ "avl_tree_insert fail, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); break; } } else { if (record.op_type == STORAGE_OP_TYPE_SOURCE_CREATE_FILE || record.op_type == STORAGE_OP_TYPE_REPLICA_CREATE_FILE) { if (fprintf(fp, "%d %c %s\n", \ (int)record.timestamp, \ record.op_type, record.filename) < 0) { result = errno != 0 ? errno : EIO; logError("file: "__FILE__", line: %d, " \ "write to file: %s fail, " \ "errno: %d, error info: %s.", \ __LINE__, tmpFullFilename, result, STRERROR(result)); break; } } else { if (fprintf(fp, "%d %c %s %s\n", \ (int)record.timestamp, \ record.op_type, record.filename, \ record.src_filename) < 0) { result = errno != 0 ? errno : EIO; logError("file: "__FILE__", line: %d, " \ "write to file: %s fail, " \ "errno: %d, error info: %s.", \ __LINE__, tmpFullFilename, result, STRERROR(result)); break; } } } } if (result == 0) { int tree_node_count; tree_node_count = avl_tree_count(&tree_unique_trunks); if (tree_node_count > 0) { logInfo("file: "__FILE__", line: %d, " \ "recovering trunk file count: %d", __LINE__, \ tree_node_count); result = avl_tree_walk(&tree_unique_trunks, \ tree_write_file_walk_callback, fp); } } avl_tree_destroy(&tree_unique_trunks); fclose(fp); if (!g_continue_flag) { return EINTR; } if (result != 0) { return result; } recovery_get_full_filename(pBasePath, \ RECOVERY_BINLOG_FILENAME, binlogFullFilename); if (rename(tmpFullFilename, binlogFullFilename) != 0) { logError("file: "__FILE__", line: %d, " \ "rename file %s to %s fail, " \ "errno: %d, error info: %s", __LINE__, \ tmpFullFilename, binlogFullFilename, \ errno, STRERROR(errno)); return errno != 0 ? errno : EPERM; } return 0; }
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); }
void avl_tree_insert_elements ( void ) { IntBucket *a,*b,*c,*d,*e,*f,*g; a = malloc(sizeof(IntBucket)); b = malloc(sizeof(IntBucket)); c = malloc(sizeof(IntBucket)); d = malloc(sizeof(IntBucket)); e = malloc(sizeof(IntBucket)); f = malloc(sizeof(IntBucket)); g = malloc(sizeof(IntBucket)); AVLTree * t = init_avl_tree(sizeof(IntBucket), &bucket_int_compare); a->p = 99; b->p = 8; c->p = 7; d->p = 100; e->p = 101; f->p = 75; g->p = 90; avl_tree_insert ( t, a ); ASSERT (t->root->count == 1, "Wrong count of children."); ASSERT (t->root->height == 1, "Root with no children has wrong height."); ASSERT (t->root->balance_factor == 0, "Root with no children has wrong balance factor."); avl_tree_insert ( t, b ); ASSERT (t->root->count == 2, "Wrong count of children in root after inserting one child."); ASSERT (t->root->height == 2, "Wrong height for root with one child."); ASSERT (t->root->balance_factor == 1, "Root with one child has wrong balance factor."); ASSERT (t->root->left->count == 1, "Child has wrong count."); ASSERT (t->root->left->height == 1, "Child has wrong height."); ASSERT (t->root->left->balance_factor == 0, "Node with no children has wrong balance factor."); ASSERT (t->root->left->parent == t->root, "Left child has wrong parent after first insert."); ASSERT ( ((IntBucket*)(t->root->bucket))->p == 99, "Wrong value for root" ); ASSERT ( ((IntBucket*)(t->root->left->bucket))->p == 8, "Wrong value for left child" ); avl_tree_insert(t,c); // ROOT->LEFT->LEFT, should get balance ASSERT ( ((IntBucket*)(t->root->bucket))->p == 8, "Wrong root after insert requiring rotate"); ASSERT ( ((IntBucket*)(t->root->right->bucket))->p == 99, "Wrong root after insert requiring rotate"); ASSERT ( ((IntBucket*)(t->root->left->bucket))->p == 7, "Wrong root after insert requiring rotate"); ASSERT (t->root->left->parent == t->root, "Left has wrong parent after rebalance."); ASSERT (t->root->right->parent == t->root, "Right has wrong parent after rebalance."); ASSERT(t->root->count==3, "Wrong count of children at root after 2nd insert"); ASSERT(t->root->height==2, "Wrong height after 2nd insert"); ASSERT(t->root->balance_factor==0, "Wrong balance factor after 2nd insert"); ASSERT(t->root->left->count==1, "Wrong child count after 2nd insert"); ASSERT(t->root->left->height==1, "Wrong child height after 2nd insert"); ASSERT(t->root->left->balance_factor==0, "Wrong child balance factor after 2nd insert"); avl_tree_insert(t,d); ASSERT(t->root->balance_factor == -1, "Wrong balance"); avl_tree_insert(t,e); ASSERT(t->root->balance_factor == -1, "Wrong balance"); ASSERT(t->root->height == 3, "Wrong height"); avl_tree_insert(t,f); avl_tree_insert(t,g); ASSERT(t->root->count == 7, "wrong count"); destroy_avl_tree(t); free(g); free(f); free(e); free(d); free(c); free(b); free(a); }
void avl_tree_insert_many ( void ) { AVLTree * t = init_avl_tree(sizeof(IntBucket), &bucket_int_compare); int insert_qty = 13; IntBucket ib[] = { {30272}, {16274}, {11768}, {10231}, {28474}, { 7272}, {15032}, {13196}, {29825}, { 6840}, {18444}, {18793}, {13786}, {21125}, {25311}, {23414}, {18374}, {24110}, {15465}, {26300}, { 1181}, { 6297}, { 3693}, {20957}, {22585}, { 8915}, {30371}, { 2036}, {18499}, {18391}, {15360}, {32509}, {23336}, {18848}, {25712}, { 6162}, { 1483}, { 4309}, {13482}, {14809}, { 5596}, {22524}, {13958}, {16918}, {25668}, {31621}, {30060}, {24637}, {28116}, {15994}, {30595}, {30642}, {30017}, { 7221}, { 2916}, { 7010}, {29356}, {22282}, {30649}, {17493}, {28780}, { 6725}, {26998}, {28805}, {24689}, {25547}, {17625}, {14250}, {11250}, {16195}, { 9542}, {26029}, { 2734}, {23373}, {21176}, {28102}, { 1894}, { 325}, { 9406}, { 4915}, { 8759}, {32413}, {14144}, { 5394}, { 3495}, {32030}, {23904}, { 4260}, {11579}, {11100}, {27212}, {20562}, {30264}, {30850}, {22393}, {28107}, {21299}, {25306}, { 2668}, { 3894}, }; int i; /* avl_tree_insert(t, ib+0); ASSERT( ((IntBucket*)t->root->bucket)->p == 30272, "Wrong value in root after first insert"); ASSERT(t->root->count == 1, "Wrong count after first insert"); ASSERT(t->root->height == 1, "Wrong height after first insert"); ASSERT(t->root->balance_factor == 0, "Wrong balance factor after first insert"); ASSERT(t->root->multiplicity == 1, "Wrong multiplicity after first insert"); ASSERT(t->root->left == NULL, "Left not NULL after first insert"); ASSERT(t->root->right == NULL, "Right not NULL after first insert"); ASSERT(t->root->parent == NULL, "Root node parent not NULL"); ASSERT(avl_verify_consistency(t, t->root)==true, "Tree inconsistent after inserting"); avl_tree_insert(t, ib+1); ASSERT( ((IntBucket*)t->root->bucket)->p == 30272, "Wrong value in root after second insert"); ASSERT( ((IntBucket*)t->root->left->bucket)->p == 16274, "Wrong value in root after second insert"); ASSERT(t->root->count == 2, "Wrong count after second insert"); ASSERT(t->root->height == 2, "Wrong height after second insert"); ASSERT(t->root->balance_factor == 1, "Wrong balance factor after second insert"); ASSERT(t->root->left != NULL, "no left child after second insert"); ASSERT(t->root->right == NULL, "right child exists after second insert"); ASSERT(t->root->left->parent == t->root, "Left child has wrong parent after second insert"); ASSERT(avl_verify_consistency(t, t->root)==true, "Tree inconsistent after inserting"); */ for (i = 0; i < insert_qty; i += 1) { avl_tree_insert(t, &(ib[i])); // fprintf(stderr, "%d: %d\n", i, ib[i].p); ASSERT(avl_verify_consistency(t, t->root)==true, "Tree inconsistent after inserting"); } ASSERT(t->root->height == 5, "Wrong height after 13 inserts"); ASSERT(t->root->balance_factor = 1, "Wrong balance factor after 13 inserts"); ASSERT(t->root->count == 13, "Wrong count after 13 inserts"); ASSERT( ((IntBucket*)t->root->left->bucket)->p == 10231, "Wrong"); ASSERT( ((IntBucket*)t->root->left->left->bucket)->p == 7272, "Wrong"); ASSERT( ((IntBucket*)t->root->left->left->left->bucket)->p == 6840, "Wrong"); ASSERT( ((IntBucket*)t->root->left->right->bucket)->p == 13196, "Wrong"); ASSERT( ((IntBucket*)t->root->left->right->left->bucket)->p == 11768, "Wrong"); ASSERT( ((IntBucket*)t->root->left->right->right->bucket)->p == 15032, "Wrong"); ASSERT( ((IntBucket*)t->root->left->right->right->left->bucket)->p == 13786, "Wrong"); ASSERT( ((IntBucket*)t->root->right->bucket)->p == 29825, "Wrong"); ASSERT( ((IntBucket*)t->root->right->left->bucket)->p == 18793, "Wrong"); ASSERT( ((IntBucket*)t->root->right->left->left->bucket)->p == 18444, "Wrong"); ASSERT( ((IntBucket*)t->root->right->left->right->bucket)->p == 28474, "Wrong"); ASSERT( ((IntBucket*)t->root->right->right->bucket)->p == 30272, "Wrong"); avl_tree_insert(t, ib+i); ASSERT( ((IntBucket*)t->root->right->bucket)->p == 28474, "Wrong"); ASSERT( ((IntBucket*)t->root->right->left->bucket)->p == 18793, "Wrong"); ASSERT( ((IntBucket*)t->root->right->left->left->bucket)->p == 18444, "Wrong"); ASSERT( ((IntBucket*)t->root->right->left->right->bucket)->p == 21125, "Wrong"); ASSERT( ((IntBucket*)t->root->right->right->bucket)->p == 29825, "Wrong"); ASSERT( ((IntBucket*)t->root->right->right->right->bucket)->p == 30272, "Wrong"); ASSERT(avl_verify_consistency(t, t->root) == true, "Inconsistent after insert 14"); for (; i < 100; i += 1) { avl_tree_insert(t, &(ib[i])); // fprintf(stderr, "%d: %d\n", i, ib[i].p); ASSERT(avl_verify_consistency(t, t->root)==true, "Tree inconsistent after inserting"); } destroy_avl_tree(t); }
static int trunk_add_free_block(FDFSTrunkNode *pNode, const bool bWriteBinLog) { int result; struct fast_mblock_node *pMblockNode; FDFSTrunkSlot target_slot; FDFSTrunkSlot *chain; pthread_mutex_lock(&trunk_mem_lock); if ((result=trunk_free_block_check_duplicate(&(pNode->trunk))) != 0) { pthread_mutex_unlock(&trunk_mem_lock); return result; } target_slot.size = pNode->trunk.file.size; target_slot.head = NULL; chain = (FDFSTrunkSlot *)avl_tree_find(tree_info_by_sizes + \ pNode->trunk.path.store_path_index, &target_slot); if (chain == NULL) { pMblockNode = fast_mblock_alloc(&tree_nodes_man); if (pMblockNode == NULL) { result = errno != 0 ? errno : EIO; logError("file: "__FILE__", line: %d, " \ "malloc %d bytes fail, " \ "errno: %d, error info: %s", \ __LINE__, (int)sizeof(FDFSTrunkSlot), \ result, STRERROR(result)); pthread_mutex_unlock(&trunk_mem_lock); return result; } chain = (FDFSTrunkSlot *)pMblockNode->data; chain->pMblockNode = pMblockNode; chain->size = pNode->trunk.file.size; pNode->next = NULL; chain->head = pNode; if (avl_tree_insert(tree_info_by_sizes + pNode->trunk. \ path.store_path_index, chain) != 1) { result = errno != 0 ? errno : ENOMEM; logError("file: "__FILE__", line: %d, " \ "avl_tree_insert fail, " \ "errno: %d, error info: %s", \ __LINE__, result, STRERROR(result)); pthread_mutex_unlock(&trunk_mem_lock); return result; } } else { pNode->next = chain->head; chain->head = pNode; } if (bWriteBinLog) { result = trunk_mem_binlog_write(g_current_time, \ TRUNK_OP_TYPE_ADD_SPACE, &(pNode->trunk)); } else { pthread_mutex_lock(&trunk_file_lock); g_trunk_total_free_space += pNode->trunk.file.size; pthread_mutex_unlock(&trunk_file_lock); result = 0; } if (result == 0) { result = trunk_free_block_insert(&(pNode->trunk)); } else { trunk_free_block_insert(&(pNode->trunk)); } pthread_mutex_unlock(&trunk_mem_lock); return result; }