char *test_set() { DArray_set(array, 0, val1); DArray_set(array, 1, val2); return NULL; }
DArray DArray_group_by(DArray array, DArray_group_by_fn *group_by_fn) { if (DArray_is_empty(array) || !group_by_fn) return NULL; DArray groups = DArray_create(sizeof(DArray), 10); DArray group; int idx; void *el; size_t count = (size_t) DArray_count(array); for (size_t i = 0; i < count; i++) { el = DArray_remove(array, i); if (!el) continue; idx = group_by_fn(el); if (idx == -1) continue; group = DArray_get(groups, idx); if (!group) { group = DArray_create(array->element_size, DArray_count(array) + 1); DArray_ensure_capacity(groups, idx + 1); DArray_set(groups, idx, group); } DArray_push(group, el); } return groups; }
void *Hashmap_delete(Hashmap *map, void *key) { uint32_t hash = 0; DArray *bucket = Hashmap_find_bucket(map, key, 0, &hash); if(!bucket) { return NULL; } int i = Hashmap_get_node(map, hash, bucket, key); if(i == -1) { return NULL; } HashmapNode *node = DArray_get(bucket, i); void *data = node->data; free(node); HashmapNode *ending = DArray_pop(bucket); if(ending != node) { // alright looks like it's not the last one, swap it. DArray_set(bucket, i, ending); } return data; }
static inline DArray *Hashmap_find_bucket(Hashmap * map, void *key, int create, uint32_t * hash_out) { uint32_t hash = map->hash(key); int bucket_n = hash % DEFAULT_NUMBER_OF_BUCKETS; check(bucket_n >= 0, "Invalid bucket found: %d", bucket_n); // store it for the return so the caller can use it *hash_out = hash; DArray *bucket = DArray_get(map->buckets, bucket_n); if (!bucket && create) { // new bucket, set it up bucket = DArray_create( sizeof(void *), DEFAULT_NUMBER_OF_BUCKETS); check_mem(bucket); DArray_set(map->buckets, bucket_n, bucket); } return bucket; error: return NULL; }
int CloseNodes_Add(CloseNodes *close, Node *node) { assert(close != NULL && "NULL CloseNodes pointer"); assert(node != NULL && "NULL Node pointer"); Distance distance = Hash_Distance(&close->id, &node->id); int i = FindIndex(close->close_nodes, &distance); if (i < 0) return 0; struct CloseNode *close_node = malloc(sizeof(struct CloseNode)); check_mem(close_node); close_node->node = node; close_node->distance = distance; if (DArray_count(close->close_nodes) < BUCKET_K) DArray_push(close->close_nodes, NULL); ShiftFrom(close->close_nodes, i); DArray_set(close->close_nodes, i, close_node); return 0; error: return -1; }
int DArray_mergesort(DArray *array, DArray_compare cmp) { int count = array->end; if (count > 1) { int pivot = count / 2; int after_pivot = count - pivot; DArray *left = DArray_create(array->element_size, pivot); DArray *right = DArray_create(array->element_size, after_pivot); for (int i = 0; i < pivot; i++) { DArray_push(left, DArray_get(array, i)); } for (int i = pivot; i < count; i++) { DArray_push(right, DArray_get(array, i)); } DArray_mergesort(left, cmp); DArray_mergesort(left, cmp); int i = 0; int l_ptr = 0; int r_ptr = 0; for (i = 0; i < count; i++) { if (l_ptr >= pivot) { DArray_set(array, i, DArray_get(right, r_ptr)); r_ptr++; } else if (r_ptr >= after_pivot) { DArray_set(array, i, DArray_get(left, l_ptr)); l_ptr++; } else if (cmp(DArray_get(left, l_ptr), DArray_get(right, r_ptr)) < 0) { DArray_set(array, i, DArray_get(left, l_ptr)); l_ptr++; } else { DArray_set(array, i, DArray_get(right, r_ptr)); r_ptr++; } } DArray_destroy(left); DArray_destroy(right); } return 0; }
char *test_get_set() { DArray *array = DArray_create(sizeof(intptr_t), 5); intptr_t value; DArray_set(array, 1, (void *) (intptr_t) 15); value = (intptr_t) DArray_get(array, 1); assert(value == 15 && "Did not get expected value at index 1."); assert(array->size == 1 && "Unexpected array size after adding one element at index 1."); DArray_set(array, 4, (void *) (intptr_t) 9789); value = (intptr_t) DArray_get(array, 4); assert(value == 9789 && "Did not get expected value at index 4."); assert(array->size == 2 && "Unexpected array size after adding one element at index 4."); DArray_destroy(array); return NULL; }
int DArray_push(DArray *array, void *el) { check(array, "received darray null pointer"); assert(array->count <= array->max && "inconsistent darray capacity"); if (array->count == array->max) check(!DArray_expand(&array), "expand of darray failed"); return DArray_set(array, array->count, el); error: return 1; }
char *test_iterationBackward_arrayContainingHoles_1() { DArray *array = DArray_create(sizeof(intptr_t), 3); DArray_set(array, 0, (void *) (intptr_t) 10); DArray_set(array, 2, (void *) (intptr_t) 30); int index = -1; assert(DArray_iterator_prev(array, &index) == 1 && "Expected to continue to prev element."); assert(index == 2 && "Expected index was not set by iteration."); assert(DArray_iterator_prev(array, &index) == 1 && "Expected to continue to prev element."); assert(index == 0 && "Expected index was not set by iteration."); assert(DArray_iterator_prev(array, &index) == 0 && "Expected to end interation."); DArray_destroy(array); return NULL; }
char *test_expand_setUndefinedIndexExpandsArray() { int initial_capacity = 2; DArray *array = DArray_create(sizeof(intptr_t), initial_capacity); DArray_set(array, 0, (void *) (intptr_t) 9789); DArray_set(array, 1, (void *) (intptr_t) 747); assert(array->size == 2 && "Unexpected array size after adding 2 elements"); assert(array->capacity == initial_capacity && "Unexpected array capacity - should match initial capacity."); DArray_set(array, 2, (void *) (intptr_t) 8776); assert(array->size == 3 && "Unexpected array size - after adding one more element."); assert(array->capacity == (initial_capacity + DARRAY_DEFAULT_EXPAND_RATE) && "Unexpected array capacity after expanding."); intptr_t value = (intptr_t) DArray_get(array, 0); assert(value == 9789 && "Did not get expected value at index 0."); value = (intptr_t) DArray_get(array, 1); assert(value == 747 && "Did not get expected value at index 1."); value = (intptr_t) DArray_get(array, 2); assert(value == 8776 && "Did not get expected value at index 2."); // index 0 1 2 are set, all others should be NULL for (int i = initial_capacity + 1; i < initial_capacity + DARRAY_DEFAULT_EXPAND_RATE; i++) { void *null_value = DArray_get(array, i); assert(null_value == NULL && "Expected remaining indexes to be NULL"); } DArray_destroy(array); return NULL; }
char *test_remove() { DArray *array = DArray_create(sizeof(intptr_t), 100); DArray_remove(array, 66); assert(array->size == 0 && "Unexpected array size - must be 0 as no elements were added."); DArray_set(array, 20, (void *) (intptr_t) 9789); DArray_remove(array, 20); assert(array->size == 0 && "Unexpected array size - must be 0 again after removing element."); void *value = DArray_get(array, 20); assert(value == NULL && "Value at index 20 was not removed."); DArray_destroy(array); return NULL; }
void ShiftFrom(DArray *close, int from) { assert(close != NULL && "NULL DArray pointer"); assert(BUCKET_K - 1 < DArray_max(close) && "Too small DArray"); assert(0 <= from && from <= DArray_end(close) && "Bad shift index"); if (DArray_end(close) == BUCKET_K) free(DArray_last(close)); int i; for (i = DArray_end(close) - 1; i > from; i--) { struct CloseNode *tmp = DArray_get(close, i - 1); DArray_set(close, i, tmp); } }
static inline DArray *Hashmap_find_bucket(Hashmap *map, void *key, int create, uint32_t *hash_out) { uint32_t hash = map->hash(key); int bucket_n = hash % DEFAULT_NUMBER_OF_BUCKETS; check(bucket_n >= 0, "Invalid bucket number found %d", bucket_n); *hash_out = hash; DArray *bucket = DArray_get(map->buckets, bucket_n); if(!bucket && create) { bucket = DArray_create(sizeof(void *), DEFAULT_NUMBER_OF_BUCKETS); check_mem(bucket); DArray_set(map->buckets, bucket_n, bucket); } return bucket; error: return NULL; }
void* Hashmap_delete(Hashmap* map, void* key) { uint32_t hash = 9; DArray* bucket = Hashmap_find_bucket(map, key, 0, &hash); if(!bucket) return NULL; int i = Hashmap_get_node(map, hash, bucket, key); if(i == -1) return NULL; HashmapNode* node = DArray_get(bucket, i); void* data = node->data; free(node); HashmapNode* ending = DArray_pop(bucket); if(ending != node) { DArray_set(bucket, i, ending); } return data; }
static inline DArray *Hashmap_find_bucket(Hashmap *map, void *key, int create, uint32_t *hash_out) {//caller fn will include 1 or 0 for int create true or false uint32_t hash = map->hash(key); int bucket_n = hash % DEFAULT_NUMBER_OF_BUCKETS;//finds bucket, will always find a bucket no matter how big check(bucket_n >= 0, "Invalid bucket found: %d", bucket_n); *hash_out = hash; //store it for the return so caller can use it. I forget how caller is supposed to use this DArray *bucket = DArray_get(map->buckets, bucket_n); if(!bucket && create) {//creates bucket if none found //new bucket, set it up bucket = DArray_create(sizeof(void *), DEFAULT_NUMBER_OF_BUCKETS); check_mem(bucket); DArray_set(map->buckets, bucket_n, bucket); } return bucket; error: return NULL; }
char *test_contract() { int initial_size = 2; DArray *array = DArray_create(sizeof(intptr_t), initial_size); DArray_set(array, 0, (void *) (intptr_t) 1); DArray_set(array, 1, (void *) (intptr_t) 2); // start expanding, first time DArray_set(array, 2, (void *) (intptr_t) 3); DArray_set(array, 3, (void *) (intptr_t) 4); DArray_set(array, 4, (void *) (intptr_t) 5); DArray_set(array, 5, (void *) (intptr_t) 6); DArray_set(array, 6, (void *) (intptr_t) 7); DArray_set(array, 7, (void *) (intptr_t) 8); DArray_set(array, 8, (void *) (intptr_t) 9); DArray_set(array, 9, (void *) (intptr_t) 10); DArray_set(array, 10, (void *) (intptr_t) 11); DArray_set(array, 11, (void *) (intptr_t) 12); assert(array->size == 12 && "Unexpected array size - expected initial size + one time expansion."); // start expanding, second time DArray_set(array, 12, (void *) (intptr_t) 13); DArray_set(array, 13, (void *) (intptr_t) 14); DArray_set(array, 14, (void *) (intptr_t) 15); DArray_set(array, 15, (void *) (intptr_t) 16); DArray_set(array, 16, (void *) (intptr_t) 17); DArray_set(array, 17, (void *) (intptr_t) 18); DArray_set(array, 18, (void *) (intptr_t) 19); DArray_set(array, 19, (void *) (intptr_t) 20); DArray_set(array, 20, (void *) (intptr_t) 21); DArray_set(array, 21, (void *) (intptr_t) 22); assert(array->size == 22 && "Unexpected array size - expected initial size + one time expansion."); DArray_destroy(array); return NULL; }
void swap(DArray *array, int i, int j) { void *tmp = DArray_get(array, i); DArray_set(array, i, DArray_get(array, j)); DArray_set(array, j, tmp); }