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; }
char *test_copy() { DArray *orig = DArray_create(sizeof(int), 11); DArray *dest = DArray_create(sizeof(int), 11); int i = 0; for(i = 0; i < 10; i++) { int *el_to_add = DArray_new(orig); *el_to_add = i; mu_assert(DArray_push(orig, el_to_add) == 0, "Pushing to DArray failed."); } int rc = DArray_copy(orig, dest); mu_assert(rc == 0, "Copy failed.") mu_assert(orig->max == dest->max, "max did not copy properly."); mu_assert(orig->end == dest->end, "end did not copy properly."); mu_assert(orig->element_size == dest->element_size, "element_size did not copy properly."); mu_assert(orig->expand_rate == dest->expand_rate, "expand_rate did not copy properly."); for(i = 0; i < 10; i++) { int *val = DArray_get(dest, i); mu_assert(val != NULL, "Got NULL from copy."); mu_assert(*val == i, "Failed to copy contents correctly."); } return NULL; }
DArray* _merge_sort(DArray* array, DArray_compare cmp) { DArray_check(array); if(array->end <= 1) return array; DArray* left = DArray_create(array->element_size, array->max); check_mem(left); DArray* right = DArray_create(array->element_size, array->max); check_mem(right); int middle = array->end/2; int i = 0; for(i = 0; i < array->end; i++) { if(i < middle) { DArray_push(left, DArray_get(array, i)); } else { DArray_push(right, DArray_get(array, i)); } } DArray* sort_left = _merge_sort(left, cmp); check(left != NULL, "Error in left merge sort"); DArray* sort_right = _merge_sort(right, cmp); check(right != NULL, "Error in right merge sort"); if(sort_left != left) DArray_destroy(left); if(sort_right != right) DArray_destroy(right); return _merge_array(sort_left, sort_right, cmp); error: return NULL; }
static inline void expose_VM(STATE, VALUE lobby) { VALUE vm = Value_new(state, ObjectType); Value_set(state, lobby, "VM", vm); // VM.primitives map DArray *prims = DArray_create(sizeof(VALUE), 10); VALUE primitives = Map_new(state, prims); Value_set(state, vm, "primitives", primitives); // Object DEFPRIM("to_s", Primitive_to_s); DEFPRIM("prototype", Primitive_prototype); DEFPRIM("or", Primitive_or); DEFPRIM("equals", Primitive_equals); DEFPRIM("is", Primitive_is); DEFPRIM("print", Primitive_print); DEFPRIM("puts", Primitive_puts); DEFPRIM("require", Primitive_require); DEFPRIM("clone", Primitive_clone); // Vector DEFPRIM("vector_[]", Primitive_Vector_at); DEFPRIM("vector_push", Primitive_Vector_push); DEFPRIM("vector_to_map", Primitive_Vector_to_map); DEFPRIM("vector_each", Primitive_Vector_each); DEFPRIM("vector_each_with_index", Primitive_Vector_each_with_index); // Number DEFPRIM("number_+", Primitive_Number_add); DEFPRIM("number_-", Primitive_Number_sub); DEFPRIM("number_*", Primitive_Number_mul); DEFPRIM("number_/", Primitive_Number_div); DEFPRIM("number_<", Primitive_Number_lt); DEFPRIM("number_>", Primitive_Number_gt); // String DEFPRIM("string_+", Primitive_String_concat); // Map DEFPRIM("map_each", Primitive_Map_each); // VM.types map DArray *ts = DArray_create(sizeof(VALUE), 10); VALUE types = Map_new(state, ts); Value_set(state, vm, "types", types); DEFVALUE("object", Object_bp); DEFVALUE("number", Number_bp); DEFVALUE("string", String_bp); DEFVALUE("vector", Vector_bp); DEFVALUE("map", Map_bp); DEFVALUE("closure", Closure_bp); }
static inline DArray* kernel_files(STATE) { DArray *entries = DArray_create(sizeof(bstring), 10); bstring kernel_relative_path = bfromcstr("../kernel"); bstring absolute_path = resolve_path(state, kernel_relative_path); struct dirent **namelist; int n = scandir(bdata(absolute_path), &namelist, 0, alphasort); if (n < 0) { perror("scandir"); } else { for(int i = 0; i < n; i++) { if(strcmp(namelist[i]->d_name, ".") != 0 && strcmp(namelist[i]->d_name, "..") != 0) { DArray_push(entries, bfromcstr(namelist[i]->d_name)); } free(namelist[i]); } free(namelist); } bdestroy(absolute_path); bdestroy(kernel_relative_path); return entries; }
Parallax *Parallax_create() { Parallax *parallax = malloc(sizeof(Parallax)); check(parallax != NULL, "Could not create parallax"); parallax->layers = DArray_create(sizeof(ParallaxLayer), 8); parallax->camera = NULL; GfxSize level = {1, 1}; parallax->level_size = level; parallax->sky_color.rgba.r = 0.5; parallax->sky_color.rgba.g = 0.5; parallax->sky_color.rgba.b = 1.0; parallax->sky_color.rgba.a = 1.0; parallax->sea_color.rgba.r = 0.0; parallax->sea_color.rgba.g = 0.5; parallax->sea_color.rgba.b = 0.0; parallax->sea_color.rgba.a = 1.0; parallax->y_wiggle = 0.0; parallax->sea_level = 1.0; return parallax; error: if (parallax) free(parallax); return NULL; }
static inline TSTree *TSTree_insert_base(TSTree *root, TSTree *node, const char *key, size_t len, void *value) { if(node == NULL) { node = (TSTree *) calloc(1, sizeof(TSTree)); check(node != NULL, "Failed creating node"); node->values = DArray_create(DEFAULT_DARRAY_SIZE, DEFAULT_DARRAY_SIZE); if(root == NULL) root = node; node->splitchar = *key; } if(*key < node->splitchar) { node->low = TSTree_insert_base(root, node->low, key, len, value); } else if(*key == node->splitchar) { if(len > 1) { node->equal = TSTree_insert_base(root, node->equal, key + 1, len - 1, value); } else { DArray_push(node->values, value); return node; // assert(node->value == NULL && "Duplicate insert into tst."); } } else { node->high = TSTree_insert_base(root, node->high, key, len, value); } return node; error: return NULL; }
char *test_iterationBackward_arrayContainingContinousElements() { DArray *array = DArray_create(sizeof(intptr_t), 3); DArray_push(array, (void *) (intptr_t) 60); DArray_push(array, (void *) (intptr_t) 670); DArray_push(array, (void *) (intptr_t) 90); 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 == 1 && "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_distribution() { int i = 0; int stats[3][BUCKETS] = { {0} }; DArray *keys = DArray_create(0, NUM_KEYS); mu_assert(gen_keys(keys, NUM_KEYS) == 0, "Failed to generate random keys."); fill_distribution(stats[ALGO_FNV1A], keys, Hashmap_fnv1a_hash); fill_distribution(stats[ALGO_ADLER32], keys, Hashmap_adler32_hash); fill_distribution(stats[ALGO_DJB], keys, Hashmap_djb_hash); fprintf(stderr, "FNV\tA32\tDJB\n"); for (i = 0; i < BUCKETS; i++) { fprintf(stderr, "%d\t%d\t%d\n", stats[ALGO_FNV1A][i], stats[ALGO_ADLER32][i], stats[ALGO_DJB][i]); } destroy_keys(keys); return NULL; }
DArray * CloseNodes_GetNodes(CloseNodes *close) { assert(close != NULL && "NULL CloseNodes pointer"); DArray *nodes = DArray_create(sizeof(Node *), DArray_max(close->close_nodes)); check(nodes != NULL, "DArray_create failed"); int i = 0; for (i = 0; i < DArray_count(close->close_nodes); i++) { struct CloseNode *close_node = DArray_get(close->close_nodes, i); check(close_node != NULL, "NULL CloseNodes entry"); check(close_node->node != NULL, "NULL Node pointer in CloseNodes entry"); int rc = DArray_push(nodes, close_node->node); check(rc == 0, "DArray_push failed"); } return nodes; error: DArray_destroy(nodes); return NULL; }
char *test_push_pop() { DArray *array = DArray_create(sizeof(intptr_t), 5); DArray_push(array, (void *) (intptr_t) 30); DArray_push(array, (void *) (intptr_t) 20); DArray_push(array, (void *) (intptr_t) 10); intptr_t value = (intptr_t) DArray_pop(array); assert(value == 10 && "pop'ed wrong value from array."); value = (intptr_t) DArray_pop(array); assert(value == 20 && "pop'ed wrong value from array."); value = (intptr_t) DArray_pop(array); assert(value == 30 && "pop'ed wrong value from array."); DArray_push(array, (void *) (intptr_t) 60); value = (intptr_t) DArray_get(array, 0); assert(value == 60 && "Getting value by index after pop'ing all values from array failed."); DArray_destroy(array); return NULL; }
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; }
DArray *TSTree_collect(TSTree *root, const char *prefix, size_t len) { DArray *matches = DArray_create(sizeof(char *), 100); TSTree *node = root; size_t i = 0; while (i < len && node) { if (prefix[i] < node->splitchar) { node = node->low; } else if (prefix[i] > node->splitchar) { node = node->high; } else { assert(prefix[i] == node->splitchar && "Prefix should == splitchar"); i++; if (i < len) { node = node->equal; } } } // node is the node that matches the prefix; all nodes in the tree will match char *partial_match = malloc(sizeof(char) * (len - 1)); memcpy(partial_match, prefix, (len - 1)); _TSTree_collect_sub_nodes(node, matches, partial_match, len); return matches; }
Object* String_to_object(bstring string) { Object *obj = NULL; if (bchar(string, 0) == '"') { int len = blength(string) - 2; obj = Object_create_string(bmidstr(string, 1, len)); } else if (bchar(string, 0) == '[') { int strlen = blength(string) - 2; bstring inner_str = bmidstr(string, 1, strlen); struct bstrList *elements = bsplit(inner_str, ','); int len = elements->qty; int i = 0; DArray *array = DArray_create(sizeof(Object*), len); bstring *ptr = elements->entry; for(i = 0; i < len; i++) { btrimws(*ptr); DArray_push(array, String_to_object(*ptr)); ptr++; } obj = Object_create_array(array); } else { int value = atoi(bdata(string)); if (value != 0) { obj = Object_create_integer(atoi(bdata(string))); } else { return NULL; } } return obj; }
char *test_iterationForward_arrayContainingContinousElements() { DArray *array = DArray_create(sizeof(intptr_t), 3); DArray_push(array, (void *) (intptr_t) 60); DArray_push(array, (void *) (intptr_t) 670); DArray_push(array, (void *) (intptr_t) 90); int index = -1; assert(DArray_iterator_next(array, &index) == 1 && "Expected to continue to next element."); assert(index == 0 && "Expected index was not set by iteration."); assert(DArray_iterator_next(array, &index) == 1 && "Expected to continue to next element."); assert(index == 1 && "Expected index was not set by iteration."); assert(DArray_iterator_next(array, &index) == 1 && "Expected to continue to next element."); assert(index == 2 && "Expected index was not set by iteration."); assert(DArray_iterator_next(array, &index) == 0 && "Expected to end interation."); /* while (DArray_iterator_next(array, &index)) { */ /* intptr_t element = (intptr_t) DArray_get(array, index); */ /* collected_elements[index] = element; */ /* } */ /* assert(collected_elements[0] == 60 && "Expected value at index not found."); */ /* assert(collected_elements[1] == 670 && "Expected value at index not found."); */ /* assert(collected_elements[2] == 90 && "Expected value at index not found."); */ DArray_destroy(array); return NULL; }
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_destroy_emptyArray() { DArray *array = DArray_create(sizeof(intptr_t), 100); DArray_destroy(array); return NULL; }
char *test_create() { array = DArray_create(sizeof(int), 100); mu_assert(array != NULL, "DArray_create failed"); mu_assert(array->contents != NULL, "contents 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"); return NULL; }
char *test_create() { array = DArray_create(sizeof(int), 100); mu_assert(array != NULL, "DArray create failed."); mu_assert(array->contents != NULL, "Contents were not initialized properly."); mu_assert(array->end == 0, "end wasn't created properly."); mu_assert(array->element_size == sizeof(int), "element_size if wrong."); mu_assert(array->max == 100, "Wrong initial max length."); return NULL; }
DArray *create_words() { DArray *result = DArray_create(0, 5); char *words[] = {"asdfasfd", "werwar", "13234", "asdfasfd", "oioj"}; for(int i = 0; i < 5; i++) { DArray_push(result, words[i]); } return result; }
char *test_get_set_undefinedIndex() { DArray *array = DArray_create(sizeof(intptr_t), 100); void *value_at_undefined_index = DArray_get(array, 1); assert(value_at_undefined_index == NULL && "Getting value at undefined index is not NULL."); DArray_destroy(array); return NULL; }
DArray *create_words() { DArray *result = DArray_create(0, 7); char *words[] = { "werwar", "asdasd", "13234", "oioj", "gthht", "lkluil", "xswcde" }; int i = 0; for (i = 0; i < 7; i++) { DArray_push(result, words[i]); } return result; }
Hashmap * Hashmap_create(Hashmap_compare compare, Hashmap_hash hash) { Hashmap *map = calloc(1, sizeof(Hashmap)); map->compare = comare==NULL?default_compare:compare; map->hash = hash==NULL?default_hash:hash; map->buckets = DArray_create(sizeof(DArray *),DEFAULT_NUMBER_OF_BUCKETS); map->buckets->end = map->buckets->max; return map; }
char *test_create() { DArray *array = DArray_create(sizeof(intptr_t), 5); assert(array != NULL && "DArray_create failed."); assert(array->size == 0 && "Logical size does not match."); assert(array->capacity == 5 && "Physical capacity does not match."); assert(array->element_size == sizeof(intptr_t) && "element_size does not match."); assert(array->expand_rate == DARRAY_DEFAULT_EXPAND_RATE && "expand_rate must be set to DARRAY_DEFAULT_EXPAND_RATE."); assert(array->contents != NULL && "contents must not be NULL."); DArray_destroy(array); return NULL; }
CloseNodes * CloseNodes_Create(Hash *id) { CloseNodes *nodes = malloc(sizeof(CloseNodes)); check_mem(nodes); nodes->id = *id; nodes->close_nodes = DArray_create(sizeof(struct CloseNode *), BUCKET_K + 1); check_mem(nodes->close_nodes); return nodes; error: free(nodes); return NULL; }
DArray DArray_find(DArray array, DArray_find_fn *filter_fn, void* args) { if (DArray_is_empty(array)) return NULL; DArray filtered = DArray_create(array->element_size, array->size); for (int i = 0; i < DArray_count(array); i++) { void *item = DArray_get(array, i); if (filter_fn(item, args)) DArray_push(filtered, item); } return filtered; }
void ChipmunkRecorder_clear_frames(Recorder *recorder) { check(recorder != NULL, "No recorder to clear"); // Destroy frames DArray_clear_destroy(recorder->frames); recorder->frames = DArray_create(sizeof(ChipmunkRecorderFrame), 60 * 5); recorder->num_frames = 0; recorder->avg_frame_size = 0; recorder->total_frame_size = 0; return; error: return; }
DArray *darray_init(int *array, size_t count) { DArray *darray = DArray_create(sizeof(int*), count); INV_DARRAY(darray); for (size_t i = 0; i < count; i++) darray->contents[i] = &array[i]; darray->count = count; INV_DARRAY(darray); return darray; error: return NULL; }
Hashmap* Hashmap_create(Hashmap_compare compare, Hashmap_hash hash) { Hashmap* map = calloc(1, sizeof(Hashmap)); check_mem(map); map->compare = compare == NULL ? default_compare : compare; map->hash = hash == NULL ? default_hash : hash; map->buckets = DArray_create(sizeof(DArray*), DEFAULT_NUMBER_OF_BUCKETS); map->buckets->end = map->buckets->max; // fake out expanding it check_mem(map->buckets); return map; error: if(map) Hashmap_destroy(map); return NULL; }
char *test_contains() { DArray *array = DArray_create(sizeof(intptr_t), 3); DArray_push(array, (void *) (intptr_t) 60); DArray_push(array, (void *) (intptr_t) 90); assert(DArray_contains(array, (void *) (intptr_t) 90, _test_predicate) == 1 && "Expected to find value in array."); assert(DArray_contains(array, (void *) (intptr_t) 60, _test_predicate) == 1 && "Expected to find value in array."); assert(DArray_contains(array, (void *) (intptr_t) 100, _test_predicate) == 0 && "Expected to not find value in array."); assert(DArray_contains(array, NULL, _test_predicate) == 0 && "Expected to not find value in array."); DArray_destroy(array); return NULL; }