void run_event(struct os *os, uval event) { struct dlist *curr = dlist_next(&os->po_events.oe_list); lock_acquire(&os->po_events.oe_lock); while (curr != &os->po_events.oe_list) { struct lpar_event *le = PARENT_OBJ(typeof(*le), le_list, curr); dlist_detach(&le->le_list); curr = dlist_next(curr); uval ret = (*le->le_func) (os, le, event); /* * ret == 1 || event==LPAR_DIE --> le is now a bad pointer, * memory may have been freed */ if (ret == 0 && (event != LPAR_DIE)) { dlist_insert(curr, &le->le_list); } } lock_release(&os->po_events.oe_lock); }
int main() { struct DList* list = dlist_create(); dlist_print(list); printf("list length = %d\n", dlist_length(list)); dlist_append(list, 5); printf("list length = %d\n", dlist_length(list)); dlist_append(list, 7); printf("list length = %d\n", dlist_length(list)); dlist_append(list, 8); printf("list length = %d\n", dlist_length(list)); dlist_print(list); dlist_print_reverse(list); dlist_remove(list, 1); printf("list length = %d\n", dlist_length(list)); dlist_print(list); dlist_print_reverse(list); dlist_insert(list, 0, 5); printf("list length = %d\n", dlist_length(list)); dlist_print(list); dlist_print_reverse(list); dlist_delete(list); return 0; }
sval register_event(struct os *os, struct lpar_event *le) { dlist_init(&le->le_list); lock_acquire(&os->po_events.oe_lock); dlist_insert(&os->po_events.oe_list, &le->le_list); lock_release(&os->po_events.oe_lock); return 0; }
/*============================================================================== * - cbi_register() * * - register a cbi into list */ OS_STATUS cbi_register (GUI_CBI *pCBI) { #if 0 dlist_add (&_G_cbi_list, (DL_NODE *)pCBI); /* insert tail */ #else dlist_insert (&_G_cbi_list, NULL, (DL_NODE *)pCBI); /* insert head */ #endif return OS_STATUS_OK; }
void line_list_insert(line_t *line, line_list_t *list) { dlink_t *link; assert(line); assert(list); line_inc_ref(line); link = dlink_new(), link->object = (void *)line; dlist_insert(link, (dlist_t *)list); }
void point_list_insert(point_t *p, point_list_t *list) { dlink_t *link; assert(p); assert(list); point_inc_ref(p); link = dlink_new(); link->object = (void *)p; dlist_insert(link, list); }
bool dlist_insert_ts (DList* list, int32_t index, void* data) { assert(NULL != list); assert(0 <= index); assert(NULL != list->mutex); pthread_mutex_lock(list->mutex); bool ret = dlist_insert(list, index, data); pthread_mutex_unlock(list->mutex); return ret; }
void test_dlist_insert_at_front(void) { unsigned long *val; unsigned long old_size; old_size = dlist_size(test_dlist); val = make_ulong_ptr(8888); assert_true(dlist_insert(test_dlist, 0, val) == 0); /* Verify */ val = NULL; val = dlist_index(test_dlist, 0); assert_ulong_equal(8888, *val); assert_true((old_size + 1) == dlist_size(test_dlist)); }
void test_dlist_insert_in_middle(void) { unsigned long *val; unsigned long old_size; old_size = dlist_size(test_dlist); val = make_ulong_ptr(6666); assert_true(dlist_insert(test_dlist, old_size / 2, val) == 0); /* Verify */ val = NULL; val = dlist_index(test_dlist, old_size / 2); assert_ulong_equal(6666, *val); assert_true((old_size + 1) == dlist_size(test_dlist)); }
void test_dlist_insert_at_back(void) { unsigned long *val; unsigned long old_size; old_size = dlist_size(test_dlist); val = make_ulong_ptr(7777); assert_true(dlist_insert(test_dlist, old_size, val) == 0); /* Verify */ val = NULL; val = dlist_index(test_dlist, old_size); assert_ulong_equal(7777, *val); assert_true((old_size + 1) == dlist_size(test_dlist)); }
static void test_invalid_params(void) { printf("===========Warning is normal begin==============\n"); assert(dlist_length(NULL) == 0); assert(dlist_prepend(NULL, 0) == RET_INVALID_PARAMS); assert(dlist_append(NULL, 0) == RET_INVALID_PARAMS); assert(dlist_delete(NULL, 0) == RET_INVALID_PARAMS); assert(dlist_insert(NULL, 0, 0) == RET_INVALID_PARAMS); assert(dlist_set_by_index(NULL, 0, 0) == RET_INVALID_PARAMS); assert(dlist_get_by_index(NULL, 0, NULL) == RET_INVALID_PARAMS); assert(dlist_find(NULL, NULL, NULL) < 0); assert(dlist_foreach(NULL, NULL, NULL) == RET_INVALID_PARAMS); printf("===========Warning is normal end==============\n"); return; }
int spellcast_htable_insert(sp_hash_table *ht, int key, const void *data) { void *check_data = NULL; int bucket, retval; if (spellcast_htable_lookup(ht, key, &check_data) == 0) { return 1; } bucket = hash_key(ht, key); retval = dlist_insert(&ht->table[bucket], data); if (retval == 0) ht->size++; return retval; }
static void *producer_thread(void *arg) { int i = 0; DList *dlist = (DList *)arg; printf("producer thread executed\n"); printf("append data\n"); for(i = 0; i < 1000; i++) dlist_insert(dlist, 0, (void *)i); sleep(1); printf("prepend data to dlist \n"); for(i = 0; i < 1000; i++) dlist_prepend(dlist, (void *)i); return NULL; }
point_list_t *point_list_new_and_copy(point_list_t *list) { dlink_t *a, *b; point_list_t *ret; point_t *p; assert(list); ret = point_list_new(); for (a = list->tail->next; a != list->head; a = a->next) { p = point_new_and_copy((point_t *)a->object); //point_inc_ref(p); b = dlink_new(); b->object = (void *)p; dlist_insert(b, (dlist_t *)ret); } return ret; }
line_list_t *line_list_new_and_copy(line_list_t *copee) { dlink_t *a, *b; line_list_t *ret; line_t *p; assert(copee); ret = line_list_new(); for (a = copee->tail->next; a != copee->head; a = a->next) { b = dlink_new(); p = line_new_and_copy((line_t *)a->object); //line_inc_ref(p); b->object = (void *)p; dlist_insert(b, (dlist_t *)ret); } return ret; }
static void* producer(void* param) { int i = 0; DList* dlist = (DList*)param; for (i = 0; i < NR; i++) { assert(dlist_append(dlist, (void*)i) == RET_OK); } sleep(1); for (i = 0; i < NR; i++) { assert(dlist_prepend(dlist, (void*)i) == RET_OK); } for (i = 0; i < NR; i++) { assert(dlist_insert(dlist, i, (void*)i) == RET_OK); } return NULL; }
int main(int argc, char* argv[]) { int i = 0; int num = 10; dlist* head = dlist_creat(); #ifdef TEST //#ifdef DLIST_CREAT_ARRAY //dlist_creat_array(); //#endif /*DLIST_CREAT_ARRAY*/ for (i = 0; i < num; i++) { /*dlist_ret ret = dlist_append(head, (void*)i); assert(ret == DLIST_RET_OK);*/ assert(dlist_append(head, (void*)i) == DLIST_RET_OK); /*dlist_append(head, (void*)i);*/ } /*for () { assert(dlist_prepend() == DLIST_RET_OK); } */ //dlist_insert(); // dlist_delete(); dlist_delete(head, 2); dlist_insert(head, 2 ,(void*)11); dlist_print(head, print_int); dlist_destroy(head); #endif /*TEST*/ }
/* Graham's Scan * Given a set of points on the plane, Graham's scan computes their convex hull. * The algorithm works in three phases: * 1. Find an extreme point. * This point will be the pivot, is guaranteed to be on the hull, * and is chosen to be the point with largest y coordinate. * 2. Sort the points in order of increasing angle about the pivot. * We end up with a star-shaped polygon (one in which one special point, * in this case the pivot, can "see" the whole polygon). * 3. Build the hull, by marching around the star-shaped poly, adding edges * when we make a left turn, and back-tracking when we make a right turn. */ static int grahamscan(polygon_t *chull, point_list_t *points) { int i; real_t dx, dy, ymin; real_t *ang; point_t *p, *q; point_t *v1, *v2, *v3; dlink_t *ax, *bx, *cx, *x, *y, *tmp; assert(chull); assert(points); assert(point_list_get_count(points) >= 3); ang = (real_t *)malloc(point_list_get_count(points) * sizeof(real_t)); assert(ang); // Find an extreme point // Preparing the polygon, and // Find the point with minimum value of y-coordinate for (ax = NULL, x = points->tail->next; x != points->head; x = x->next) { p = (point_t *)x->object; y = dlink_new(); point_inc_ref(p); y->object = (void *)p; dlist_insert(y, chull); if (ax == NULL || point_get_y(p) < ymin) { ax = y; ymin = point_get_y(p); } } dlink_cutoff(ax); dlist_dec_count(chull); dlist_push(ax, chull); // Sort the points in order of increasing angle about the pivot. p = (point_t *)ax->object; //point_dump(p); for (i = 0, x = ax->next; x != chull->head; x = x->next) { q = (point_t *)x->object; dx = point_get_x(q) - point_get_x(p); dy = point_get_y(q) - point_get_y(p); ang[i] = arctan2r(dy, dx); x->spare = (void *)&(ang[i]); i++; //point_dump(q); //printf("ang: %lf\n", ang[i-1]); } for (x = ax->next; x->next != chull->head; x = x->next) { for (y = x->next; y != chull->head; y = y->next) { if (*((real_t *)y->spare) < *((real_t *)x->spare)) { dlink_exchange(x, y); tmp = x, x = y, y = tmp; } } } //point_dump((point_t *)c->object); v1 = point_new(); v2 = point_new(); v3 = point_new(); cx = chull->tail->next->next->next; while (cx != chull->head) { bx = cx->prev; ax = bx->prev; point_subtract(v1, (point_t *)ax->object, (point_t *)bx->object); point_subtract(v2, (point_t *)cx->object, (point_t *)bx->object); point_xproduct(v3, v1, v2); // Convex ? if (point_get_z(v3) < 0) { cx = cx->next; } else { dlink_cutoff(bx); dlist_dec_count(chull); point_destroy((point_t *)bx->object); dlink_destroy(bx); } } for (x = chull->tail->next; x != chull->head; x = x->next) x->spare = NULL; point_destroy(v3); point_destroy(v2); point_destroy(v1); free(ang); return dlist_get_count(chull); }
Ret dlist_append(DList* thiz, void* data) { return dlist_insert(thiz, -1, data); }
Ret dlist_prepend(DList* thiz, void* data) { return dlist_insert(thiz, 0, data); }
Dlist_data * dlist_add(Dlist *dl, void *d) { return dlist_insert(dl, __dlist_guard(dl), d); }
/* some problem is occurred due to co-linear pixels, * so it need to be check the maximum distance within same minimum angle * comment : if break statement in the Right chain growth routine is converted * from "if (ycoord[imin] < ycoord[i-1]) break;" * to "if (ycoord[imin] <= ycoord[i-1]) break;" * , then some problem is removed. * However, if an point exits * such that is resemble to "ycoord" of the extreme point * and has the minimum angle * then the convex hull that we want don't be created. */ static int jarvismarch(polygon_t *chull, point_list_t *points) { real_t ang, dist, ymin; real_t amin, dmax, dx, dy; dlink_t *x, *y, *ax, *bx; point_t *p, *q; assert(chull); assert(points); assert(point_list_get_count(points) >= 3); // Preparing the polygon, and // Find the point with minimum value of y-coordinate for (ax = NULL, x = points->tail->next; x != points->head; x = x->next) { p = (point_t *)x->object; y = dlink_new(); point_inc_ref(p); y->object = (void *)p; dlist_insert(y, chull); if (ax == NULL || point_get_y(p) < ymin) { ax = y; ymin = point_get_y(p); } } dlink_cutoff(ax); dlist_dec_count(chull); dlist_push(ax, chull); point_dump((point_t *)ax->object); // Scan right chain for (ax = chull->tail->next; ax->next != chull->head; ax = ax->next) { p = (point_t *)ax->object; for (bx = NULL, x = ax->next; x != chull->head; x = x->next) { q = (point_t *)x->object; dx = point_get_x(q) - point_get_x(p); dy = point_get_y(q) - point_get_y(p); ang = arctan2r(dy, dx); dist = sqrt(sqr(dx) + sqr(dy)); // Find another vertex with min-angle and max-distance if (bx == NULL || ang < amin) { bx = x; amin = ang; dmax = dist; } else if (ang == amin && dist > dmax) { bx = x; dmax = dist; } } q = (point_t *)bx->object; // Right chain complete ? if (point_get_y(q) < point_get_y(p)) break; // Swapping (coordinations and mark) dlink_cutoff(bx); dlink_append(bx, ax); point_dump((point_t *)bx->object); } //printf("n: %d\n", convexhull->count); // Scan left chain for (; ax->next != chull->head; ax = ax->next) { p = (point_t *)ax->object; for (bx = NULL, x = ax->next; x != chull->head; x = x->next) { q = (point_t *)x->object; dx = point_get_x(p) - point_get_x(q); dy = point_get_y(p) - point_get_y(q); ang = arctan2r(dy, dx); dist = sqrt(sqr(dx) + sqr(dy)); if (bx == NULL || ang < amin) { bx = x; amin = ang; dmax = dist; } else if (ang == amin && dist > dmax) { bx = x; dmax = dist; } } y = chull->tail->next; q = (point_t *)y->object; dx = point_get_x(p) - point_get_x(q); dy = point_get_y(p) - point_get_y(q); ang = arctan2r(dy, dx); // Convexhull complete ? if (ang < amin) break; // Swapping dlink_cutoff(bx); dlink_append(bx, ax); point_dump((point_t *)bx->object); } //printf("n: %d\n", convexhull->count); while (ax->next != chull->head) { x = ax->next; dlink_cutoff(x); dlist_dec_count(chull); point_destroy((point_t *)x->object); dlink_destroy(x); } return dlist_get_count(chull); }
static int quickhull(polygon_t *chull, point_list_t *points) { real_t ymin, ymax, yval; point_t *p, *v1, *v2, *v3; dlink_t *ax, *bx, *x, *y, *next; dlist_t *right_group, *left_group; assert(chull); assert(points); // Allocate the structure element of convex hull for (x = points->tail->next; x != points->head; x = x->next) { p = (point_t *)x->object; point_inc_ref(p); y = dlink_new(); y->object = (void *)p; dlist_insert(y, chull); } // find the extreme points along y-axis ax = NULL; bx = NULL; for (x = chull->tail->next; x != chull->head; x = x->next) { yval = point_get_y((point_t *)(x->object)); if (ax == NULL || yval < ymin) { ax = x; ymin = yval; } if (bx == NULL || yval > ymax) { bx = x; ymax = yval; } } dlink_cutoff(ax); dlist_dec_count(chull); dlink_cutoff(bx); dlist_dec_count(chull); //point_dump((point_t *)ax->object); //point_dump((point_t *)bx->object); v1 = point_new(); v2 = point_new(); v3 = point_new(); //printf("for right section\n"); right_group= dlist_new(); dlist_insert(ax, right_group); point_subtract(v2, (point_t *)bx->object, (point_t *)ax->object); for (x = chull->tail->next; x != chull->head;) { //point_dump((point_t *)x->object); point_subtract(v1, (point_t *)x->object, (point_t *)ax->object); point_xproduct(v3, v1, v2); if (point_get_z(v3) > 0) { next = x->next; dlink_cutoff(x); dlist_dec_count(chull); dlist_insert(x, right_group); //printf(" "); //point_dump((point_t *)x->object); x = next; } else x = x->next; } dlist_insert(bx, right_group); quickhull_grouping(right_group); //printf("for left section\n"); ax = dlist_pop(right_group); bx = dlist_extract(right_group); //point_dump((point_t *)ax->object); //point_dump((point_t *)bx->object); left_group = dlist_new(); dlist_insert(bx, left_group); point_subtract(v2, (point_t *)ax->object, (point_t *)bx->object); for (x = chull->tail->next; x != chull->head; ) { point_subtract(v1, (point_t *)x->object, (point_t *)bx->object); point_xproduct(v3, v1, v2); if (point_get_z(v3) > 0) { next = x->next; dlink_cutoff(x); dlist_dec_count(chull); dlist_insert(x, left_group); //point_dump((point_t *)x->object); x = next; } else { next = x->next; dlink_cutoff(x); dlist_dec_count(chull); point_destroy((point_t *)x->object); dlink_destroy(x); x = next; } } dlist_insert(ax, left_group); quickhull_grouping(left_group); ax = dlist_extract(left_group); bx = dlist_pop(left_group); dlist_insert(ax, chull); while (dlist_get_count(right_group) > 0) { x = dlist_pop(right_group); dlist_insert(x, chull); } dlist_insert(bx, chull); while (dlist_get_count(left_group) > 0) { x = dlist_pop(left_group); dlist_insert(x, chull); } dlist_destroy(left_group); dlist_destroy(right_group); point_destroy(v3); point_destroy(v2); point_destroy(v1); return dlist_get_count(chull); }
void test_list() { printf("\ntesting single list\n"); // // single link list // struct snode { struct slist lnk; int i; int j; }; struct slist shead; slist_init(&shead); struct snode* n1 = (struct snode*)malloc(sizeof(struct snode)); n1->i = 1; n1->j = 1; slist_insert(&shead, &n1->lnk); // insert n1 AFTER head struct snode* n2 = (struct snode*)malloc(sizeof(struct snode)); n2->i = 2; n2->j = 2; slist_insert(&n1->lnk, &n2->lnk); // insert n2 after n1 struct snode* n3 = (struct snode*)malloc(sizeof(struct snode)); n3->i = 3; n3->j = 3; slist_insert(&n2->lnk, &n3->lnk); // insert n3 after n2 struct snode* n0 = (struct snode*)malloc(sizeof(struct snode)); n0->i = 0; n0->j = 0; slist_insert(&shead, &n0->lnk); // insert n0 after head struct snode* pos; slist_for_each_entry(pos, struct snode, &shead, lnk) { printf("%d ", pos->i); } slist_remove(&n1->lnk, &n2->lnk); // remove n2 slist_remove(&n1->lnk, &n3->lnk); // remove n3 slist_remove(&shead, &n0->lnk); // remove n0 slist_remove(&shead, &n1->lnk); // remove n1 slist_for_each_entry(pos, struct snode, &shead, lnk) { printf("%d ", pos->i); } printf("\ntesting double link list\n"); // // double link list // struct dnode { struct dlist lnk; int i; int j; }; struct dlist dhead; dlist_init(&dhead); struct dnode* d0 = (struct dnode*)malloc(sizeof(struct dnode)); d0->i = 0; d0->j = 0; dlist_insert(&dhead, &d0->lnk); // insert d0 before head struct dnode* d2 = (struct dnode*)malloc(sizeof(struct dnode)); d2->i = 2; d2->j = 2; dlist_insert(&dhead, &d2->lnk); // insert d2 before head struct dnode* d1 = (struct dnode*)malloc(sizeof(struct dnode)); d1->i = 1; d1->j = 1; dlist_insert(&d2->lnk, &d1->lnk); // insert d2 before d1 struct dnode* p; dlist_for_each_entry(p, struct dnode, &dhead, lnk) { printf("%d ", p->i); } // remove first and last node dlist_remove(&d0->lnk); dlist_remove(&d2->lnk); dlist_for_each_entry(p, struct dnode, &dhead, lnk) { printf("%d ", p->i); } // remove the only left node dlist_remove(&d1->lnk); dlist_for_each_entry(p, struct dnode, &dhead, lnk) { printf("%d ", p->i); } }
/* return 1 for (potential) success, 0 for failure */ int try_server(int index, int conn) { int upfd; int client = conns[conn].client; int n = 0, err; int optval = 1; struct sockaddr_storage *addr = &servers[index].addr; /* The idea is that a client should be able to connect again to the same server even if the server is close to its configured connection limit */ int sticky = ((client != -1) && (index == clients[client].server)); if (index == NO_SERVER) { DEBUG(2, "Won't try to connect to NO_SERVER"); return 0; /* out of bounds */ } DEBUG(2, "Trying server %d for connection %d at time %d", index, conn, now); if (pen_getport(addr) == 0) { DEBUG(1, "No port for you!"); return 0; } if (now-servers[index].status < blacklist_time) { DEBUG(1, "Server %d is blacklisted", index); return 0; } if (servers[index].maxc != 0 && (servers[index].c >= servers[index].maxc) && (sticky == 0 || servers[index].c >= servers[index].hard)) { DEBUG(1, "Server %d is overloaded: sticky=%d, maxc=%d, hard=%d", \ index, sticky, servers[index].maxc, servers[index].hard); return 0; } if ((client != -1) && !match_acl(servers[index].acl, &(clients[client].addr))) { DEBUG(1, "try_server: denied by acl"); return 0; } upfd = socket_nb(addr->ss_family, protoid, 0); if (keepalive) { setsockopt(upfd, SOL_SOCKET, SO_KEEPALIVE, (void *)&optval, sizeof optval); } if (debuglevel > 1) { debug("Connecting to %s", pen_ntoa(addr)); pen_dumpaddr(addr); } conns[conn].t = now; if (transparent) spoof_bind(index, conn, upfd); n = connect(upfd, (struct sockaddr *)addr, pen_ss_size(addr)); err = socket_errno; DEBUG(2, "connect (upfd = %d) returns %d, errno = %d, socket_errno = %d", upfd, n, errno, err); /* A new complication is that we don't know yet if the connect will succeed. */ if (n == 0) { /* connection completed */ conns[conn].state = CS_CONNECTED; if (conns[conn].downfd == -1) { /* idler */ conns[conn].state |= CS_CLOSED_DOWN; } event_add(upfd, EVENT_READ); if (!udp) event_add(conns[conn].downfd, EVENT_READ); servers[index].c++; if (servers[index].status) { servers[index].status = 0; DEBUG(1, "Server %d ok", index); } DEBUG(2, "Successful connect to server %d\n" \ "conns[%d].client = %d\n" \ "conns[%d].server = %d", \ index, conn, conns[conn].client, conn, conns[conn].server); } else if (err == CONNECT_IN_PROGRESS) { /* may potentially succeed */ conns[conn].state = CS_IN_PROGRESS; pending_list = dlist_insert(pending_list, conn); conns[conn].pend = pending_list; pending_queue++; event_add(upfd, EVENT_WRITE); DEBUG(2, "Pending connect to server %d\n" \ "conns[%d].client = %d\n" \ "conns[%d].server = %d", \ index, conn, conns[conn].client, conn, conns[conn].server); } else { /* failed definitely */ if (servers[index].status == 0) { debug("Server %d failed, retry in %d sec: %d", index, blacklist_time, socket_errno); } debug("blacklisting server %d because connect error %d", index, err); blacklist_server(index); close(upfd); return 0; } conns[conn].server = index; DEBUG(2, "Setting server %d for client %d", index, client); clients[client].server = index; current = index; conns[conn].upfd = upfd; fd2conn_set(upfd, conn); return 1; }
int test_dlist() { puts("##########################################"); puts("starting double linked list tests"); puts("##########################################"); int value = 0; struct DList *dlist = dlist_create(); puts("empty double list created"); if (dlist_length(dlist) != 0) { printf("dlist_length of empty list should be zero\n"); return 0; } puts("dlist_length ok"); // Insert value 101 and test functions dlist_insert(dlist, 0, 101); if (dlist_length(dlist) != 1) { printf("dlist_length should be 1\n"); return 0; } if (dlist_get(dlist, 0, &value) == 0) { printf("Error in dlist_get (1)\n"); return 0; } if (value != 101) { printf("dlist_get should return value 101\n"); return 0; } // Insert value 202 and test functions dlist_insert(dlist, 0, 202); if (dlist_length(dlist) != 2) { printf("dlist_length should return 2\n"); return 0; } if (dlist_get(dlist, 0, &value) == 0) { printf("Error in dlist_length (2)\n"); return 0; } if (value != 202) { printf("dlist_get should return 202\n"); return 0; } puts("dlist_get ok"); // Test remove function if (dlist_remove(dlist, 1) == 0) { printf("Error in dlist_remove\n"); return 0; } if (dlist_length(dlist) != 1) { printf("dlist_length should return 1 (after remove)\n"); return 0; } if (dlist_remove(dlist, 1) != 0) { printf("Error in dlist_remove\n"); return 0; } if (dlist_length(dlist) != 1) { printf("dlist_length should return 1 (after remove)\n"); return 0; } if (dlist_remove(dlist, 0) == 0) { printf("Error in dlist_remove\n"); return 0; } if (dlist_length(dlist) != 0) { printf("dlist_length should return 0 (after remove)\n"); return 0; } if (dlist_remove(dlist, 0) != 0) { printf("Error in dlist_remove\n"); return 0; } if (dlist_length(dlist) != 0) { printf("dlist_length should return 0 (after remove)\n"); return 0; } puts("dlist_remove ok"); // test dlist_append() dlist_append(dlist, -5); dlist_append(dlist, 1); dlist_append(dlist, 15); if (dlist_length(dlist) != 3) { printf("dlist_length should return 0\n"); return 0; } if (dlist_get(dlist, 0, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != -5) { printf("dlist_get should return -5\n"); return 0; } if (dlist_get(dlist, 1, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 1) { printf("dlist_get should return 1\n"); return 0; } if (dlist_get(dlist, 2, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 15) { printf("dlist_get should return 15\n"); return 0; } puts("dlist_append ok"); // test dlist insert dlist_insert(dlist, -5, 0); if (dlist_length(dlist) != 4) { printf("dlist_length should return 4\n"); return 0; } if (dlist_get(dlist, 0, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 0) { printf("dlist_get should return 0\n"); return 0; } dlist_insert(dlist, 1, 100); if (dlist_length(dlist) != 5) { printf("dlist_length should return 5\n"); return 0; } if (dlist_get(dlist, 1, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 100) { printf("dlist_get should return 100\n"); return 0; } dlist_insert(dlist, 10, 500); if (dlist_length(dlist) != 6) { printf("dlist_length should return 6\n"); return 0; } if (dlist_get(dlist, 5, &value) != 1) { printf("Error in dlist_append\n"); return 0; } if (value != 500) { printf("dlist_get should return 500\n"); return 0; } puts("dlist_insert ok"); // test print and print reversed puts("print current dlist"); dlist_print(dlist); puts("printing reversed dlist"); dlist_print_reverse(dlist); puts("check print and print_reversed for yourself!"); puts("##########################################"); puts("all tests of double linked lists completed"); puts("##########################################"); puts("------------------------------------------"); dlist_delete(dlist); return 1; }
void test_int_dlist(void) { int s = 0; int i = 0; int n = 100; int data = 0; DList* dlist = dlist_create(NULL, NULL); for (i = 0; i < n; i++) { assert(dlist_append(dlist, (void*)i) == DLIST_RET_OK); assert(dlist_length(dlist) == (i + 1)); assert(dlist_get_by_index(dlist, i, (void**)&data) == DLIST_RET_OK); assert(data == i); assert(dlist_set_by_index(dlist, i, (void*)(2 * i)) == DLIST_RET_OK); assert(dlist_get_by_index(dlist, i, (void**)&data) == DLIST_RET_OK); assert(data == 2 * i); assert(dlist_set_by_index(dlist, i, (void*)i) == DLIST_RET_OK); assert(dlist_find(dlist, cmp_int, (void*)i) == i); } for (i = 0; i < n; i++) { assert(dlist_get_by_index(dlist, 0, (void**)&data) == DLIST_RET_OK); assert(data == (i)); assert(dlist_length(dlist) == (n - i)); assert(dlist_delete(dlist, 0) == DLIST_RET_OK); assert(dlist_length(dlist) == (n - i - 1)); if ((i + 1) < n) { assert(dlist_get_by_index(dlist, 0, (void**)&data) == DLIST_RET_OK); assert((int)data == (i + 1)); } } assert(dlist_length(dlist) == 0); for (i = 0; i < n; i++) { assert(dlist_prepend(dlist, (void*)i) == DLIST_RET_OK); assert(dlist_length(dlist) == (i + 1)); assert(dlist_get_by_index(dlist, 0, (void**)&data) == DLIST_RET_OK); assert(data == i); assert(dlist_set_by_index(dlist, 0, (void*)(2 * i)) == DLIST_RET_OK); assert(dlist_get_by_index(dlist, 0, (void**)&data) == DLIST_RET_OK); assert(data == 2 * i); assert(dlist_set_by_index(dlist, 0, (void*)i) == DLIST_RET_OK); } i = n - 1; assert(dlist_foreach(dlist, check_and_dec_int, &i) == DLIST_RET_OK); s = dlist_length(dlist); for (i = 1; i < n; i++) { assert(dlist_insert(dlist, i, (void*)i) == DLIST_RET_OK); assert(dlist_length(dlist) == (s + i)); assert(dlist_get_by_index(dlist, i, (void**)&data) == DLIST_RET_OK); assert(data == i); assert(dlist_set_by_index(dlist, i, (void*)(2 * i)) == DLIST_RET_OK); assert(dlist_get_by_index(dlist, i, (void**)&data) == DLIST_RET_OK); assert(data == 2 * i); assert(dlist_set_by_index(dlist, i, (void*)i) == DLIST_RET_OK); } dlist_destroy(dlist); return; }
/* * Quick-Hull * Here's an algorithm that deserves its name. * It's a fast way to compute the convex hull of a set of points on the plane. * It shares a few similarities with its namesake, quick-sort: * - it is recursive. * - each recursive step partitions data into several groups. * * The partitioning step does all the work. The basic idea is as follows: * 1. We are given a some points, * and line segment AB which we know is a chord of the convex hull. * 2. Among the given points, find the one which is farthest from AB. * Let's call this point C. * 3. The points inside the triangle ABC cannot be on the hull. * Put them in set s0. * 4. Put the points which lie outside edge AC in set s1, * and points outside edge BC in set s2. * * Once the partitioning is done, we recursively invoke quick-hull on sets s1 and s2. * The algorithm works fast on random sets of points * because step 3 of the partition typically discards a large fraction of the points. */ static int quickhull_grouping(dlist_t *group) { dlink_t *x, *ax, *bx, *cx, *next; dlist_t *s1, *s2; point_t *v1, *v2, *v3; real_t area; assert(group); if (dlist_get_count(group) <= 2) return dlist_get_count(group); v1 = point_new(); v2 = point_new(); v3 = point_new(); // Find the point with maximum parallelogram's area ax = dlist_pop(group); bx = dlist_extract(group); cx = NULL; point_subtract(v2, (point_t *)(bx->object), (point_t *)(ax->object)); for (x = group->tail->next; x != group->head; x = x->next) { point_subtract(v1, (point_t *)(x->object), (point_t *)(ax->object)); point_xproduct(v3, v1, v2); if (cx == NULL || point_get_z(v3) > area) { cx = x; area = point_get_z(v3); } } dlink_cutoff(cx); dlist_dec_count(group); // S1 grouping s1 = dlist_new(); dlist_insert(ax, s1); point_subtract(v2, (point_t *)(cx->object), (point_t *)(ax->object)); for (x = group->tail->next; x != group->head; ) { point_subtract(v1, (point_t *)(x->object), (point_t *)(ax->object)); point_xproduct(v3, v1, v2); if (point_get_z(v3) > 0) { next = x->next; dlink_cutoff(x); dlist_dec_count(group); dlist_insert(x, s1); x = next; } else x = x->next; } dlist_insert(cx, s1); quickhull_grouping(s1); assert(cx == s1->head->prev); // S2 grouping and pop out others cx = dlist_extract(s1); s2 = dlist_new(); dlist_insert(cx, s2); point_subtract(v2, (point_t *)bx->object, (point_t *)cx->object); for (x = group->tail->next; x != group->head;) { point_subtract(v1, (point_t *)x->object, (point_t *)cx->object); point_xproduct(v3, v1, v2); if (point_get_z(v3) > 0) { next = x->next; dlink_cutoff(x); dlist_dec_count(group); dlist_insert(x, s2); x = next; } else { next = x->next; dlink_cutoff(x); dlist_dec_count(group); point_destroy((point_t *)x->object); dlink_destroy(x); x = next; } } dlist_insert(bx, s2); quickhull_grouping(s2); assert(bx == s2->head->prev); assert(dlist_get_count(group) == 0); //assert(group->count == 0); // Merge s1 and s2 into group while (dlist_get_count(s1) > 0) { x = dlist_pop(s1); dlist_insert(x, group); } while (dlist_get_count(s2) > 0) { x = dlist_pop(s2); dlist_insert(x, group); } dlist_destroy(s2); dlist_destroy(s1); point_destroy(v3); point_destroy(v2); point_destroy(v1); return dlist_get_count(group); }
/* * By computing a formula, deriving and finding the minimum, * one can prove that * the minimum rects will always have at least one side that lies on a polygon edge. * In order to find the minimum area or circumference blocking rectangule, * we'll examine a sequence of such rectangles. * The basic idea is to start with a bounding rectangle and to rotate it at each step, * so we'll change only one point from the polygon's points that lie on the rect. * We do that by calculating the angles for each point * between the rect side that lies on it and the next polygon edge (clockwise). * We rotate the rect in the minimal angle we've calculated. * The first rect will lie on the most right, most left, most up and most down points. * For each rect we'll calculate the area and the circumference. This way we can find the minimum. */ static void convexhull_create_circumference_rectangles(dlist_t *circumrects, polygon_t *chull) { int i, irotate; real_t *angle, rectangle[4], delta; real_t rotate, dmin, slope, yslope, ortho, yortho, temp; real_t xmin, xmax, ymin, ymax, area; point_t *p, *q, *r, *s; dlink_t *left, *right, *top, *bottom; dlink_t *cross_vertex[4], *start, *pivot, *pivot_next; dlink_t *ax, *bx; polygon_t *rect; assert(circumrects); assert(chull); assert(polygon_get_count(chull) >= 3); // Finding angle of edge of convexhull angle = (real_t *)malloc(polygon_get_count(chull) * sizeof(real_t)); assert(angle); i = 0; ax = chull->head->prev; bx = chull->tail->next; do { p = (point_t *)ax->object; q = (point_t *)bx->object; angle[i] = arctan2r(point_get_y(q) - point_get_y(p), point_get_x(q) - point_get_x(p)); //angle[i] = angle[i] > M_PI ? angle[i]-M_PI : angle[i]; ax->spare = (void *)&angle[i]; printf("(%lf,%lf)->(%lf,%lf):%lf\n", point_get_x(p), point_get_y(p), point_get_x(q), point_get_y(q), angle[i] * 180 / M_PI); i++; ax = bx; bx = bx->next; } while (bx != chull->head); printf("Initialized the angle between verteces\n"); // Finding four extreme points left = NULL; right = NULL; top = NULL; bottom = NULL; for (ax = chull->tail->next; ax != chull->head; ax = ax->next) { p = (point_t *)ax->object; if (left == NULL || point_get_x(p) < xmin) { left = ax; xmin = point_get_x(p); } if (right == NULL || point_get_x(p) > xmax) { right = ax; xmax = point_get_x(p); } if (bottom == NULL || point_get_y(p) < ymin) { bottom = ax; ymin = point_get_y(p); } if (top == NULL || point_get_y(p) > ymax) { top = ax; ymax = point_get_y(p); } } cross_vertex[0] = bottom; cross_vertex[1] = right; cross_vertex[2] = top; cross_vertex[3] = left; area = (xmax - xmin) * (ymax - ymin); // Forming the starting rectangle from four extreme points rect = polygon_new(); polygon_insert(point_new_and_set(xmin, ymin, 0), rect); polygon_insert(point_new_and_set(xmax, ymin, 0), rect); polygon_insert(point_new_and_set(xmax, ymax, 0), rect); polygon_insert(point_new_and_set(xmin, ymax, 0), rect); // Angle of four edge of the starting rectangle rectangle[0] = 0; rectangle[1] = M_PI_2; rectangle[2] = M_PI; rectangle[3] = M_PI + M_PI_2; for (i = 0, ax = rect->tail->next; ax != rect->head; ax = ax->next) { ax->spare = (void *)&rectangle[i]; i++; } ax = dlink_new(); ax->object = (void *)polygon_new_and_copy(rect); dlist_insert(ax, circumrects); // Difference between angle of edge of rectangle and edge of convexhull start = NULL; for (i = 0, ax = rect->tail->next; ax != rect->head; ax = ax->next) { delta = (*((real_t *)cross_vertex[i]->spare) - *((real_t *)ax->spare) + 2 * M_PI); if (delta >= 2 * M_PI) delta -= 2 * M_PI; if ((start == NULL) || (delta < dmin)) { start = cross_vertex[i]; dmin = delta; irotate = i; } i++; } rotate = 0; pivot = start; do { if (pivot->next == chull->head) pivot_next = chull->tail->next; else pivot_next = pivot->next; p = (point_t *)pivot->object; q = (point_t *)pivot_next->object; if (point_get_x(p) == point_get_x(q) || point_get_y(p) == point_get_y(q)) { // For 0 or 90 or 180 degree // Nothing } else { // For others // Update rectangluar by pivot edge for rotation // Finding parameters of extending line between p and q ///////////////////////////////////////////////////////// slope = (point_get_y(q) - point_get_y(p)) / (point_get_x(q) - point_get_x(p)); yslope = point_get_y(q) - slope * point_get_x(q); r = (point_t *)cross_vertex[(irotate + 1) % 4]->object; ortho = -1 / slope; yortho = point_get_y(r) - ortho * point_get_x(r); s = polygon_glimpse(irotate, rect); point_put_x(-1 * (yslope - yortho) / (slope - ortho), s); point_put_y(slope * point_get_x(s) + yslope, s); ///////////////////////////////////////////////////////// temp = slope; slope = ortho; ortho = temp; yslope = yortho; r = (point_t *)cross_vertex[(irotate + 2) % 4]->object; yortho = point_get_y(r) - ortho * point_get_x(r); s = polygon_glimpse((irotate + 1) % 4, rect); point_put_x(-1 * (yslope - yortho) / (slope - ortho), s); point_put_y(slope * point_get_x(s) + yslope, s); ///////////////////////////////////////////////////////// temp = slope; slope = ortho; ortho = temp; yslope = yortho; r = (point_t *)cross_vertex[(irotate + 3) % 4]->object; yortho = point_get_y(r) - ortho * point_get_x(r); s = polygon_glimpse((irotate + 2) % 4, rect); point_put_x(-1 * (yslope - yortho) / (slope - ortho), s); point_put_y(slope * point_get_x(s) + yslope, s); ///////////////////////////////////////////////////////// temp = slope; slope = ortho; ortho = temp; yslope = yortho; r = (point_t *)cross_vertex[irotate]->object; yortho = point_get_y(r) - ortho * point_get_x(r); s = polygon_glimpse((irotate + 3) % 4, rect); point_put_x(-1 * (yslope - yortho) / (slope - ortho), s); point_put_y(slope * point_get_x(s) + yslope, s); ///////////////////////////////////////////////////////// rotate += dmin; for (ax = rect->tail->next; ax != rect->head; ax = ax->next) { *((real_t *)ax->spare) += dmin; if (*((real_t *)ax->spare) >= 2 * M_PI) *((real_t *)ax->spare) -= 2 * M_PI; } p = polygon_glimpse(0, rect); q = polygon_glimpse(1, rect); r = polygon_glimpse(2, rect); s = polygon_glimpse(3, rect); ax = dlink_new(); ax->object = (void *)polygon_new_and_copy(rect); dlist_insert(ax, circumrects); temp = get_distance_of_p2p(p, q) * get_distance_of_p2p(q, r); if (temp < area) area = temp; } // Update crossing verteces between rectangle and convexhull cross_vertex[irotate] = pivot_next; pivot = NULL; for (i = 0, ax = rect->tail->next; ax != rect->head; ax = ax->next) { delta = (*((real_t *)cross_vertex[i]->spare) - *((real_t *)ax->spare) + 2 * M_PI); if (delta >= 2 * M_PI) delta -= 2 * M_PI; if (pivot == NULL || delta < dmin) { pivot = cross_vertex[i]; dmin = delta; irotate = i; } i++; } p = polygon_glimpse(0, rect); q = polygon_glimpse(1, rect); r = polygon_glimpse(2, rect); s = polygon_glimpse(3, rect); } while (pivot != start); point_destroy(polygon_pop(rect)); point_destroy(polygon_pop(rect)); point_destroy(polygon_pop(rect)); point_destroy(polygon_pop(rect)); polygon_destroy(rect); free(angle); }
static Ret linear_container_dlist_insert(LinearContainer* thiz, size_t index, void* data) { PrivInfo* priv = (PrivInfo*)thiz->priv; return dlist_insert(priv->dlist, index, data); }