/* Complexity: O(n log n), worst-case if data is located * at the right-most leaf node on the lowest level of the * tree. */ int heap_remove(Heap *heap, const void *data) { unsigned long i; assert(heap != NULL); if(heap_is_empty(heap)) { return -1; } for(i = 0; i < heap_size(heap); i++) { if(darray_index(heap->h, i) == data) { if(darray_swap(heap->h, i, darray_size(heap->h) - 1) < 0) { return -1; } /* Don't care about the return value */ darray_remove(heap->h, darray_size(heap->h) - 1); heapify_down(heap, i); return 0; } } return -1; }
void *darray_pop(struct darray *da) { if(da->logical_size > 0) { void *elem = darray_remove(da, da->logical_size - 1); da->logical_size--; return elem; } else { return NULL; } }
void *darray_pop(darray_t *array) { check(array->end - 1 > 0, "Attempt to pop from empty array."); void *el = darray_remove(array, array->end - 1); array->end--; if(darray_end(array) > (int)array->expand_rate && darray_end(array) % array->expand_rate) { darray_contract(array); } return el; error: return NULL; }
void hash_remove(struct hash *hash, const char *key, free_func *freer) { unsigned i, h; struct hash_bucket *iter; h = hashstr(key, hash->max_size); for (i = 0; i < hash->buckets[h].length; ++i) { darray_at(&hash->buckets[h], i, (void **)&iter); if (!strcmp(iter->key, key)) { darray_remove(&hash->buckets[h], freer, i); break; } } }
/* Complexity: O(log n) */ void* heap_pop(Heap *heap) { void *ret = NULL; assert(heap != NULL); if(heap_is_empty(heap)) { return NULL; } if(darray_swap(heap->h, 0, darray_size(heap->h) - 1) < 0) { return NULL; } ret = darray_remove(heap->h, darray_size(heap->h) - 1); heapify_down(heap, 0); return ret; }
tns_value_t *default_load_server(const char *uuid) { const char *SERVER_QUERY = "SELECT id, uuid, default_host, bind_addr, port, chroot, access_log, error_log, pid_file, use_ssl FROM server WHERE uuid=%Q"; tns_value_t *ret = DB_exec(SERVER_QUERY, uuid); if(ret == NULL || tns_get_type(ret) != tns_tag_list || ret->value.list->end < 1) return ret; tns_value_t *control_port; tns_value_t *ret2 = DB_exec("SELECT control_port FROM server WHERE uuid=%Q", uuid); if(ret2 != NULL && tns_get_type(ret2) == tns_tag_list && ret2->value.list->end > 0) { tns_value_t *row = (tns_value_t *)darray_first(ret2->value.list); control_port = (tns_value_t *)darray_first(row->value.list); darray_remove(row->value.list, 0); tns_value_destroy(ret2); } else { control_port = tns_parse_string("", 0); } tns_insert_to_list((tns_value_t *)darray_first(ret->value.list), 9, control_port); return ret; }
char *test_darray_operations() { darray_t *array = darray_create(sizeof(int), 100); mu_assert(array != NULL, "darray_create failed."); mu_assert(array->contents != NULL, "contents are wrong in darray"); mu_assert(array->end == 0, "end isn't at the right spot"); mu_assert(array->element_size == sizeof(int), "element size is wrong."); mu_assert(array->max == 100, "wrong max length on initial size"); int *val1 = darray_new(array); mu_assert(val1 != NULL, "failed to make a new element"); int *val2 = darray_new(array); mu_assert(val2 != NULL, "failed to make a new element"); darray_set(array, 0, val1); darray_set(array, 1, val2); mu_assert(darray_get(array, 0) == val1, "Wrong first value."); mu_assert(darray_get(array, 1) == val2, "Wrong second value."); int *val_check = darray_remove(array, 0); mu_assert(val_check != NULL, "Should not get NULL."); mu_assert(*val_check == *val1, "Should get the first value."); mu_assert(darray_get(array, 0) == NULL, "Should be gone."); darray_free(val_check); val_check = darray_remove(array, 1); mu_assert(val_check != NULL, "Should not get NULL."); mu_assert(*val_check == *val2, "Should get the first value."); mu_assert(darray_get(array, 1) == NULL, "Should be gone."); darray_free(val_check); int old_max = array->max; darray_expand(array); mu_assert(array->max == old_max + array->expand_rate, "Wrong size after expand."); darray_contract(array); mu_assert(array->max == array->expand_rate + 1, "Should stay at the expand_rate at least."); darray_contract(array); mu_assert(array->max == array->expand_rate + 1, "Should stay at the expand_rate at least."); int i = 0; for(i = 0; i < 1000; i++) { int *val = darray_new(array); darray_attach(array, val); *val = i * 333; darray_push(array, val); } mu_assert(array->max == 1201, "Wrong max size."); for(i = 999; i > 0; i--) { int *val = darray_pop(array); mu_assert(val != NULL, "Shouldn't get a NULL."); mu_assert(*val == i * 333, "Wrong value."); darray_free(val); } darray_destroy(array); return NULL; }