void test_avl_tree_remove(void) { AVLTree *tree; int i; int x, y, z; int value; int expected_entries; tree = create_tree(); /* Try removing invalid entries */ i = NUM_TEST_VALUES + 100; assert(avl_tree_remove(tree, &i) == 0); i = -1; assert(avl_tree_remove(tree, &i) == 0); /* Delete the nodes from the tree */ expected_entries = NUM_TEST_VALUES; /* This looping arrangement causes nodes to be removed in a * randomish fashion from all over the tree. */ for (x=0; x<4; ++x) { for (y=0; y<4; ++y) { for (z=0; z<8; ++z) { value = z * 16 + (3 - y) * 4 + x; assert(avl_tree_remove(tree, &value) != 0); validate_tree(tree); expected_entries -= 1; assert(avl_tree_num_entries(tree) == expected_entries); } } } /* All entries removed, should be empty now */ assert(avl_tree_root_node(tree) == NULL); avl_tree_free(tree); }
static VALUE avl_tree_rremove( 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_remove( t->root, elem, cmp ); return obj; }
/** Release a user semaphore. * @param sem Semaphore to release. */ static void user_semaphore_release(user_semaphore_t *sem) { if(refcount_dec(&sem->count) == 0) { rwlock_write_lock(&semaphore_tree_lock); avl_tree_remove(&semaphore_tree, &sem->tree_link); rwlock_unlock(&semaphore_tree_lock); object_destroy(&sem->obj); id_allocator_free(&semaphore_id_allocator, sem->id); kfree(sem); } }
/* remove process from list */ static void remove_process_from_list(process_t *process) { unsigned long irqs_state; /* acquire lock before access */ irqs_state = spin_lock_irqsave(&processes_lock); /* remove process */ xlist_remove_unsafe(&processes_list, &process->procs_list_node); /* remove process from tree */ if(!avl_tree_remove(&processes_tree, process)) panic("remove_process_from_list(): failed to remove process from tree!\n"); /* release lock */ spin_unlock_irqrstor(&processes_lock, irqs_state); }
void writer(uss_t *srv, uss_connection_t *conn, int error, driver_core_t *core) { driver_core_connection_state_t *s = conn->priv; if (error) { LOG(LOG_LEVEL_WARN, "Couldn't send buffer to client: %s\n", strerror(errno)); avl_tree_remove(&core->connection_state, conn->fd); unix_socket_server_close_connection(srv, conn); return; } s->argc = s->args_received = 0; s->last_argument_offset = 0; buffer_realloc(&conn->read_task.b, 0); unix_socket_server_recv(srv, conn, sizeof(pr_signature_t), (uss_reader_t)reader, core); }
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); }
/************ definitions ************/ void reader(uss_t *srv, uss_connection_t *conn, int error, driver_core_t *core) { const pr_signature_t *s; pr_driver_response_t *response_header; const pr_driver_command_t *dc; const pr_driver_command_argument_t *dca; const uint8_t *dca_value; uint8_t argc, arg_idx; uint8_t cmd_idx; size_t required_length; driver_command_t *comm; buffer_t response; driver_core_connection_state_t *state; if (error) { LOG(LOG_LEVEL_WARN, "Couldn't recv from client: %s\n", strerror(errno)); avl_tree_remove(&core->connection_state, conn->fd); unix_socket_server_close_connection(srv, conn); return; } if (conn->eof) { LOG_MSG(LOG_LEVEL_DEBUG, "Another one EOF\n"); avl_tree_remove(&core->connection_state, conn->fd); unix_socket_server_close_connection(srv, conn); return; } s = (const pr_signature_t *)(conn->read_task.b.data); if (PR_DRV_COMMAND != s->s) { LOG(LOG_LEVEL_WARN, "Invalid signature received: %#02x\n", s->s); avl_tree_remove(&core->connection_state, conn->fd); unix_socket_server_close_connection(srv, conn); return; } if (conn->read_task.b.user_size < sizeof(pr_driver_command_t)) { conn->read_task.b.offset = conn->read_task.b.user_size; unix_socket_server_recv( srv, conn, sizeof(pr_driver_command_t) - conn->read_task.b.user_size, (uss_reader_t)reader, core); return; } state = (driver_core_connection_state_t *)conn->priv; dc = (const pr_driver_command_t *)s; argc = dc->argc; cmd_idx = dc->cmd_idx; dca = (const pr_driver_command_argument_t *)(dc + 1); state->argc = argc; comm = (driver_command_t *)vector_get(&core->payload->commands, cmd_idx); if (argc > comm->max_arity) { LOG(LOG_LEVEL_WARN, "Maximum command arity exceeded: %#02x vs %#02x\n", (unsigned int)argc, (unsigned int)comm->max_arity); avl_tree_remove(&core->connection_state, conn->fd); unix_socket_server_close_connection(srv, conn); return; } if (!argc) { LOG(LOG_LEVEL_DEBUG, "Calling %*s with no arguments\n", comm->name_len, comm->name); buffer_init(&response, sizeof(*response_header), bp_non_shrinkable); comm->handler(cmd_idx, comm->name, comm->name_len, argc, NULL, &response); if (response.user_size < sizeof(*response_header)) { LOG_MSG(LOG_LEVEL_FATAL, "Comand handler malforms response buffer\n"); abort(); } response_header = (pr_driver_response_t *)response.data; response_header->s.s = PR_DRV_RESPONSE; response_header->len = response.user_size - sizeof(*response_header); unix_socket_server_send(srv, conn, response.data, response.user_size, (uss_writer_t)writer, core); buffer_deinit(&response); return; } /* if (!argc) */ if (state->argc == state->args_received) { LOG(LOG_LEVEL_DEBUG, "Calling %*s with %d arguments\n", comm->name_len, comm->name, state->argc); driver_command_argument_t argv[state->argc]; for (arg_idx = 0; arg_idx < state->argc; ++arg_idx) { argv[arg_idx].arg = (const char *)(dca + 1); argv[arg_idx].arg_len = dca->len; dca = (const pr_driver_command_argument_t *)( (const uint8_t *)(dca + 1) + dca->len); } buffer_init(&response, 0, bp_non_shrinkable); comm->handler(cmd_idx, comm->name, comm->name_len, state->argc, argv, &response); unix_socket_server_send(srv, conn, response.data, response.user_size, (uss_writer_t)writer, core); buffer_deinit(&response); return; } /* if (state->argc == state->args_received) */ /* TODO receive full arguments vector */ if (0 == state->last_argument_offset) state->last_argument_offset = sizeof(*dc); dca = (const pr_driver_command_argument_t *)( (const uint8_t *)s + state->last_argument_offset ); if (conn->read_task.b.user_size < state->last_argument_offset + sizeof(*dca)) { required_length = state->last_argument_offset + sizeof(*dca); conn->read_task.b.offset = conn->read_task.b.user_size; unix_socket_server_recv( srv, conn, required_length - conn->read_task.b.user_size, (uss_reader_t)reader, core); return; } if (conn->read_task.b.user_size < state->last_argument_offset + sizeof(*dca) + dca->len) { required_length = state->last_argument_offset + sizeof(*dca) + dca->len; conn->read_task.b.offset = conn->read_task.b.user_size; unix_socket_server_recv( srv, conn, required_length - conn->read_task.b.user_size, (uss_reader_t)reader, core); return; } ++state->args_received; state->last_argument_offset += sizeof(*dca) + dca->len; required_length = state->last_argument_offset + sizeof(*dca); if (state->args_received < state->argc) { conn->read_task.b.offset = conn->read_task.b.user_size; unix_socket_server_recv( srv, conn, required_length - conn->read_task.b.user_size, (uss_reader_t)reader, core); return; } LOG(LOG_LEVEL_DEBUG, "Calling %*s with %d arguments\n", comm->name_len, comm->name, state->argc); driver_command_argument_t argv[state->argc]; for (arg_idx = 0; arg_idx < state->argc; ++arg_idx) { argv[arg_idx].arg = (const char *)(dca + 1); argv[arg_idx].arg_len = dca->len; dca = (const pr_driver_command_argument_t *)( (const uint8_t *)(dca + 1) + dca->len); } buffer_init(&response, sizeof(*response_header), bp_non_shrinkable); comm->handler(cmd_idx, comm->name, comm->name_len, state->argc, argv, &response); if (response.user_size < sizeof(*response_header)) { LOG_MSG(LOG_LEVEL_FATAL, "Comand handler malforms response buffer\n"); abort(); } response_header = (pr_driver_response_t *)response.data; response_header->s.s = PR_DRV_RESPONSE; response_header->len = response.user_size - sizeof(*response_header); unix_socket_server_send(srv, conn, response.data, response.user_size, (uss_writer_t)writer, core); buffer_deinit(&response); }