/* 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 graph_free_all(Graph *g, FreeFn vertex_data_freefn) { unsigned long index; Vertex *v; assert(g != NULL); if(NULL == vertex_data_freefn) { /* Default to stdlib free */ vertex_data_freefn = free; } /* Free edge lists and vertex data */ for(index = 0; index < darray_size(g->vertices); index++) { v = (Vertex *)darray_index(g->vertices, index); vertex_data_freefn(v->data); darray_free_all(v->edges, NULL); } /* Free vertex list */ darray_free_all(g->vertices, NULL); /* Free graph container */ free(g); }
DArray* graph_get_edges(const Graph *g) { unsigned long index; DArray *edges; Vertex *v; assert(g != NULL); edges = darray_create(); if(NULL == edges) { fprintf(stderr, "Cannot create edge list (%s:%d)\n", __FUNCTION__, __LINE__); return NULL; } for(index = 0; index < darray_size(g->vertices); index++) { v = (Vertex *)darray_index(g->vertices, index); if(darray_concat(edges, v->edges) < 0) { fprintf(stderr, "Cannot construct edge list (%s:%d)\n", __FUNCTION__, __LINE__); darray_free(edges); return NULL; } } return edges; }
DArray* graph_vertex_get_out_edges(const Graph *g, const Vertex *v) { unsigned long index; DArray *out_edges; Edge *e; assert(g != NULL); assert(v != NULL); out_edges = darray_create(); if(NULL == out_edges) { fprintf(stderr, "Cannot create out-edge list (%s:%d)\n", __FUNCTION__, __LINE__); return NULL; } for(index = 0; index < darray_size(v->edges); index++) { e = (Edge *)darray_index(v->edges, index); if(v == e->source) { if(darray_append(out_edges, e) < 0) { fprintf(stderr, "Cannot construct out-edge list (%s:%d)\n", __FUNCTION__, __LINE__); darray_free(out_edges); return NULL; } } } return out_edges; }
/* Complexity: O(log n), worst-case */ int heap_push(Heap *heap, void *data) { assert(heap != NULL); darray_append(heap->h, data); heapify_up(heap, darray_size(heap->h) - 1); return 0; }
int graph_vertex_add(Graph *g, Vertex *v) { assert(g != NULL); assert(v != NULL); v->idx = darray_size(g->vertices); return darray_append(g->vertices, v); }
/* 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; }
int main(int argc, char *argv[]) { dyn_array_t arr = darray_make(4); // Store 1,2,3,4 in array for (int i = 0; i < darray_size(arr); ++i) darray_set(arr, i, i); // Print arr[i] = i for i=[1,4] for (int i = 0; i < darray_size(arr); ++i) printf("arr[%d] = %d\n", i, *darray_get(arr, i)); darray_append(&arr, 5); darray_append(&arr, 6); darray_prepend(&arr, 7); darray_prepend(&arr, 8); // Print arr[i] = j for i=[1,8] for (int i = 0; i < darray_size(arr); ++i) printf("arr[%d] = %d\n", i, *darray_get(arr, i)); darray_free(&arr); arr = NULL; return 0; }
Vertex* graph_vertex_find(const Graph *g, const void *data) { unsigned long index; Vertex *v; assert(g != NULL); assert(data != NULL); for(index = 0; index < darray_size(g->vertices); index++) { v = (Vertex *)darray_index(g->vertices, index); if(v->data == data) { return v; } } return NULL; }
int graph_edge_add(Graph *g, Edge *e) { unsigned long index; Vertex *v; assert(g != NULL); assert(e != NULL); for(index = 0; index < darray_size(g->vertices); index++) { v = (Vertex *)darray_index(g->vertices, index); if(v == e->source) { v->out_degree++; darray_append(v->edges, e); g->edge_count++; } if((v == e->target)) { /* For undirected graphs, insert an extra edge to allow * traversal from the target vertex back to the source * vertex, except in the case where an edge is a loop. */ if(graph_is_undirected(g)) { v->out_degree++; if(e->target != e->source) { darray_append(v->edges, edge_create(e->target, e->source, e->weight)); } else { /* Loops are counted twice */ v->out_degree++; } } else { /* Keep track of the number of edges directed * toward this vertex, but not which edges * * TODO Keep a separate in-edge list for each * node? */ v->in_degree++; } } } return 0; }
/* Complexity: O(size(heap1) + 2 * size(heap2)) => O(n) */ int heap_merge(Heap *heap1, Heap* heap2) { unsigned long i; assert(heap1 != NULL); assert(heap2 != NULL); if(heap_is_empty(heap1) && heap_is_empty(heap2)) { return -1; } /* O(size(heap2)) */ if(darray_concat(heap1->h, heap2->h) < 0) { return -1; } /* O(size(heap1) + size(heap2)) */ for(i = (darray_size(heap1->h) - 1) / 2; i > 0; i--) { heapify_down(heap1, i); } heapify_down(heap1, 0); /* Edge-case for loop 0 index */ return 0; }
/** * Returns the number of entries in the context's include path. */ XKB_EXPORT unsigned int xkb_context_num_include_paths(struct xkb_context *ctx) { return darray_size(ctx->includes); }
unsigned long graph_vertex_count(const Graph *g) { assert(g != NULL); return darray_size(g->vertices); }
/* Complexity: O(1) */ unsigned long heap_size(Heap *heap) { assert(heap != NULL); return darray_size(heap->h); }
/* * Bucket sort algorithm. */ void integer_sort(int *array, int n) { int max, _max; /* Max number in array. */ int range; /* Bucket range. */ int i, j, k; /* Loop indexes. */ int *indexes; /* Index for buckets. */ struct darray **buckets; /* Buckets. */ indexes = smalloc(NUM_BUCKETS*sizeof(int)); /* Create buckets. */ buckets = smalloc(NUM_BUCKETS*sizeof(struct darray *)); for (i = 0; i < NUM_BUCKETS; i++) buckets[i] = darray_create(n/NUM_BUCKETS); max = INT_MIN; #pragma omp parallel private(i, j, k, _max) { _max = INT_MIN; /* Find max number in the array. */ #pragma omp for schedule(static) for (i = 0; i < n; i++) { /* Found. */ if (array[i] > _max) _max = array[i]; } #pragma omp critical { if (_max > max) { max = _max; } } #pragma omp master range = max/NUM_BUCKETS; #pragma omp barrier /* Distribute numbers into buckets. */ #pragma omp master for (i = 0; i < n; i++) { j = array[i]/range; if (j >= NUM_BUCKETS) j = NUM_BUCKETS - 1; darray_append(buckets[j], array[i]); } /* Sort Each bucket. */ #pragma omp for schedule(dynamic) for (i = 0; i < NUM_BUCKETS; i++) { if (darray_size(buckets[i]) > 0) sort(buckets[i]); } #pragma omp master { /* Build indexes. */ indexes[0] = 0; for (i = 1; i < NUM_BUCKETS; i++) indexes[i] = indexes[i - 1] + darray_size(buckets[i]); /* Rebuild array. */ for (i = 0; i < NUM_BUCKETS; i++) { k = indexes[i]; for (j = 0; j < darray_size(buckets[i]); j++) array[k + j] = darray_get(buckets[i], j); } } } /* House keeping. */ for (i = 0; i < NUM_BUCKETS; i++) darray_destroy(buckets[i]); free(buckets); free(indexes); }
unsigned long vertex_edge_count(const Vertex *v) { assert(v != NULL); return darray_size(v->edges); }
int main(void) { darray(long) arr = darray_new(); darray_char str = darray_new(); darray(long*) arrp = darray_new(); arrp.onFree = _arr_free_handler; #define reset(arr) do {darray_free(arr); darray_init(arr);} while(0) size_t i; trace("Generating amalgams (internal)"); generateAmalgams(); plan_tests(54); testLits(); testing(darray_pushptr); { int vMaxCount = 10;//ARRAY_SIZE(lotsOfNumbers); for (int k=0; k < vMaxCount; k++) { long* p = malloc(sizeof(long)); *p = lotsOfNumbers[k]; darray_push(arrp, p); } ok1(darray_size(arrp) == vMaxCount); ok1(darray_alloc(arrp) >= darray_size(arrp)); long **i; size_t j = 0; darray_foreach(i, arrp) { if (i - arrp.item != j) break; if (**i != (long)lotsOfNumbers[j]) break; j++; }; ok1(j == vMaxCount); darray_free_all(arrp); ok1(_free_count == vMaxCount); } testing(darray_push); { for (i=0; i < ARRAY_SIZE(lotsOfNumbers); i++) darray_push(arr, lotsOfNumbers[i]); ok1(darray_size(arr) == ARRAY_SIZE(lotsOfNumbers)); ok1(darray_alloc(arr) >= darray_size(arr)); ok1(!memcmp(arr.item, lotsOfNumbers, sizeof(lotsOfNumbers))); } testing(darray_insert); { darray_insert(arr, 0, 123456); ok1(darray_size(arr) == ARRAY_SIZE(lotsOfNumbers)+1); ok1(!memcmp(arr.item+1, lotsOfNumbers, sizeof(lotsOfNumbers))); ok1(darray_item(arr, 0) == 123456); darray_insert(arr, 15, 0x112233); ok1(darray_size(arr) == ARRAY_SIZE(lotsOfNumbers)+2); ok1(darray_item(arr, 15) == 0x112233); ok1(!memcmp(arr.item+1, lotsOfNumbers, 14*sizeof(long))); ok1(!memcmp(arr.item+16, &lotsOfNumbers[14], ARRAY_SIZE(lotsOfNumbers)-(15*sizeof(long)))); } testing(darray_del); { darray_del(arr, 15); darray_del(arr, 0); ok1(darray_size(arr) == ARRAY_SIZE(lotsOfNumbers)); ok1(!memcmp(arr.item, lotsOfNumbers, sizeof(lotsOfNumbers))); } reset(arr); testing(darray_prepend, darray_pop); { for (i = ARRAY_SIZE(lotsOfNumbers); i;) darray_prepend(arr, lotsOfNumbers[--i]); ok1(darray_size(arr) == ARRAY_SIZE(lotsOfNumbers)); ok1(darray_alloc(arr) >= darray_size(arr)); ok1(!memcmp(arr.item, lotsOfNumbers, sizeof(lotsOfNumbers))); for (i = ARRAY_SIZE(lotsOfNumbers); i;) { if (darray_pop(arr) != (long)lotsOfNumbers[--i]) { i++; break; } } ok1(i==0); ok1(darray_size(arr) == 0); } reset(arr); testing(darray_from_c, darray_foreach, darray_foreach_reverse); { long *i; size_t j; darray_from_c(arr, lotsOfNumbers); ok1(darray_size(arr) == ARRAY_SIZE(lotsOfNumbers)); ok1(darray_alloc(arr) >= darray_size(arr)); ok1(memcmp(arr.item, lotsOfNumbers, sizeof(lotsOfNumbers)) == 0); j = 0; darray_foreach(i, arr) { if (i - arr.item != j) break; if (*i != (long)lotsOfNumbers[j]) break; j++; }; ok1(j == ARRAY_SIZE(lotsOfNumbers)); j = 0; darray_foreach_reverse(i, arr) { if (i - arr.item != darray_size(arr)-j-1) break; if (*i != (long)lotsOfNumbers[darray_size(arr)-j-1]) break; j++; }; ok1(j == ARRAY_SIZE(lotsOfNumbers)); } reset(arr); testing(darray_append_string); { for (i=0; i < ARRAY_SIZE(lotsOfStrings); i++) darray_append_string(str, lotsOfStrings[i]); ok1(str.size == amalgams.stringsSize); ok1(str.alloc > str.size); ok1(str.item[str.size] == 0); ok1(!strcmp(str.item, amalgams.stringsF)); } reset(str); testing(darray_prepend_string); { for (i=0; i < ARRAY_SIZE(lotsOfStrings); i++) darray_prepend_string(str, lotsOfStrings[i]); ok1(str.size == amalgams.stringsSize); ok1(str.alloc > str.size); ok1(str.item[str.size] == 0); ok1(!strcmp(str.item, amalgams.stringsB)); } reset(str); testing(darray_from_string); { for (i=0; i < ARRAY_SIZE(lotsOfStrings); i++) { darray_from_string(str, lotsOfStrings[i]); if (str.size != strlen(lotsOfStrings[i])) break; if (str.alloc < strlen(lotsOfStrings[i])+1) break; if (strcmp(str.item, lotsOfStrings[i])) break; } ok1(i == ARRAY_SIZE(lotsOfStrings)); } reset(str); testing(darray_resize0); { size_t prevSize=0, size; for (i=0; i < ARRAY_SIZE(lotsOfNumbers); i++, prevSize=size) { size = lotsOfNumbers[i] & 0xFFFF; darray_resize0(arr, size); if (darray_size(arr) != size) break; if (darray_alloc(arr) < size) break; if (size>prevSize) { if (!isZeros(arr.item+prevSize, (size-prevSize)*sizeof(*arr.item))) break; } //fill the darray with lotsOfNumbers garbage memtile(arr.item, darray_size(arr)*sizeof(*arr.item), lotsOfNumbers, sizeof(lotsOfNumbers)); } ok1(i == ARRAY_SIZE(lotsOfNumbers)); } reset(arr); testing(darray_realloc); { size_t s,a; for (i=0; i < ARRAY_SIZE(lotsOfNumbers); i++) { arr.size = (s = lotsOfNumbers[i] >> 16); //give size a nonsense value to make sure darray_realloc doesn't care about it a = amalgams.stringsSize/sizeof(*arr.item)+2; darray_realloc(arr, a = lotsOfNumbers[i] % ((amalgams.stringsSize/sizeof(*arr.item))+1)); if (a*sizeof(*arr.item) > amalgams.stringsSize) break; if (darray_alloc(arr) != a) break; if (darray_size(arr) != s) break; memtile(arr.item, a*sizeof(*arr.item), amalgams.stringsF, a*sizeof(*arr.item)); if (memcmp(arr.item, amalgams.stringsF, a*sizeof(*arr.item))) break; } ok1(i == ARRAY_SIZE(lotsOfNumbers)); } reset(arr); testing(darray_growalloc); { size_t prevA, s, a; for (i=0; i < ARRAY_SIZE(lotsOfNumbers); i++) { arr.size = (s = lotsOfNumbers[i] >> 16); //give size a nonsense value to make sure darray_growalloc doesn't care about it a = amalgams.stringsSize/sizeof(*arr.item)+2; prevA = darray_alloc(arr); darray_growalloc(arr, a = lotsOfNumbers[i] % ((amalgams.stringsSize/sizeof(*arr.item))+1)); if (a*sizeof(*arr.item) > amalgams.stringsSize) break; if (darray_alloc(arr) < a) break; if (darray_alloc(arr) < prevA) break; if (darray_size(arr) != s) break; memtile(arr.item, a*sizeof(*arr.item), amalgams.stringsF, a*sizeof(*arr.item)); if (memcmp(arr.item, amalgams.stringsF, a*sizeof(*arr.item))) break; //clear the darray every now and then if (!(lotsOfNumbers[i] & 15)) { reset(arr); } } ok1(i == ARRAY_SIZE(lotsOfNumbers)); } reset(arr); testing(darray_make_room); { for (i=0; i < ARRAY_SIZE(lotsOfStrings); i++) { char *dest = darray_make_room(str, strlen(lotsOfStrings[i])); if (str.alloc < str.size+strlen(lotsOfStrings[i])) break; if (dest != str.item+str.size) break; memcpy(dest, lotsOfStrings[i], strlen(lotsOfStrings[i])); str.size += strlen(lotsOfStrings[i]); } ok1(i == ARRAY_SIZE(lotsOfStrings)); ok1(str.size == amalgams.stringsSize); darray_append(str, 0); ok1(!strcmp(str.item, amalgams.stringsF)); } reset(str); testing(darray_appends, darray_prepends, darray_pop_check); { darray(const char*) arr = darray_new(); const char *n[9] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight"}; #if HAVE_TYPEOF darray_appends(arr, n[5], n[6], n[7], n[8]); #else darray_appends_t(arr, const char *, n[5], n[6], n[7], n[8]); #endif ok1(darray_size(arr)==4 && darray_alloc(arr)>=4); #if HAVE_TYPEOF darray_prepends(arr, n[0], n[1], n[2], n[3], n[4]); #else darray_prepends_t(arr, const char *, n[0], n[1], n[2], n[3], n[4]); #endif ok1(darray_size(arr)==9 && darray_alloc(arr)>=9); ok1(arr.item[0]==n[0] && arr.item[1]==n[1] && arr.item[2]==n[2] && arr.item[3]==n[3] && arr.item[4]==n[4] && arr.item[5]==n[5] && arr.item[6]==n[6] && arr.item[7]==n[7] && arr.item[8]==n[8]); ok1(darray_pop_check(arr)==n[8] && darray_pop_check(arr)==n[7] && darray_pop_check(arr)==n[6] && darray_pop_check(arr)==n[5] && darray_pop_check(arr)==n[4] && darray_pop_check(arr)==n[3] && darray_pop_check(arr)==n[2] && darray_pop_check(arr)==n[1] && darray_pop_check(arr)==n[0]); ok1(darray_size(arr)==0); ok1(darray_pop_check(arr)==NULL && darray_pop_check(arr)==NULL && darray_pop_check(arr)==NULL); darray_free(arr); } trace("Freeing amalgams (internal)"); freeAmalgams(); return exit_status(); }
struct type *type_function_get_rettype(const struct type *t) { RF_ASSERT(type_is_function(t) && darray_size(t->operator.operands) == 2, "Non function type detected"); return darray_item(t->operator.operands, 1); }
unsigned int xkb_context_num_failed_include_paths(struct xkb_context *ctx) { return darray_size(ctx->failed_includes); }
static inline void analyzer_traversal_ctx_prev_parent(struct analyzer_traversal_ctx *ctx) { RF_ASSERT(darray_size(ctx->parent_nodes) != 0, "Tried to go beyond the root"); (void)darray_pop(ctx->parent_nodes); }