list_t *list_dup(list_t *orig) { list_iter *iter = list_get_iterator(orig, LIST_START_HEAD); if (iter == NULL) { return NULL; } list_t *copy = list_create(&orig->type); if (copy == NULL) { list_release_iterator(iter); return NULL; } list_node *node; while ((node = list_next(iter)) != NULL) { void *value = node->value; if (copy->type.dup) { value = copy->type.dup(value); if (value == NULL) { list_release_iterator(iter); list_release(copy); return NULL; } } if (list_add_node_tail(copy, value) == NULL) { list_release_iterator(iter); list_release(copy); return NULL; } } list_release_iterator(iter); return copy; }
int main(int argc, char *argv[]) { list_type type; type.dup = node_dup; type.free = node_free; type.compare = node_compare; list_t *list = list_create(&type); for (int i = 0; i < 10; ++i) { sds value = sdsempty(); value = sdscatprintf(value, "%d", i); list_add_node_tail(list, value); printf("add %s\n", value); sdsfree(value); } for (int i = 0; i < 10; ++i) { sds value = sdsempty(); value = sdscatprintf(value, "%d", 10 + i); list_add_node_head(list, value); printf("add %s\n", value); sdsfree(value); } list_node *node = list_index(list, 10); sds value = sdsempty(); value = sdscatprintf(value, "%d", 100); list_insert_node(list, node, value, 1); printf("insert %s\n", value); node = list_find(list, value); printf("search: %s\n", (char *)node->value); sdsfree(value); for (int i = -10; i < 10; ++i) { node = list_index(list, i); if (node) { printf("%d: %s\n", i, (char *)node->value); } } list_t *copy = list_dup(list); list_release(list); printf("len: %ld\n", list_len(copy)); list_rotate(copy); list_rotate(copy); list_rotate(copy); list_iter *iter = list_get_iterator(copy, LIST_START_HEAD); while ((node = list_next(iter)) != NULL) { printf("%s\n", (char *)node->value); list_del(copy, node); } list_release_iterator(iter); list_release(copy); printf("len: %ld\n", list_len(copy)); printf("head: %p, tail: %p\n", copy->head, copy->tail); return 0; }
list_node *list_find(list_t *list, void *value) { if (list->type.compare == NULL) return NULL; list_iter *iter = list_get_iterator(list, LIST_START_HEAD); if (iter == NULL) { return NULL; } list_node *node; while ((node = list_next(iter)) != NULL) { if (list->type.compare(node->value, value) == 0) { list_release_iterator(iter); return node; } } list_release_iterator(iter); return NULL; }
int http_response_write(array_queue *equeue, int err, void *arg, call *next) { http_response *res = (http_response*)arg; next->arg = res; if (res->output_buffer_written == 0) { sprintf(res->output_buffer, "%s %d Raccoon\r\n", res->http_version_str, res->status_code); list_iterator *it = list_get_iterator(&res->headers); http_header *header; while ((header = list_iterate(it)) != NULL) { strcat(res->output_buffer, header->name); strcat(res->output_buffer, ":"); strcat(res->output_buffer, header->value); strcat(res->output_buffer, "\r\n"); } strcat(res->output_buffer, "\r\n"); } int output_buffer_len = strlen(res->output_buffer); int witten = write(res->client_sockfd, res->output_buffer, output_buffer_len); if (witten > 0) res->output_buffer_written += witten; if ((witten == -1 && errno == EAGAIN) || (witten > 0 && res->output_buffer_written < output_buffer_len)) { array_queue_push(equeue, call_new(&http_response_write, res, next)); return 1; } else if (witten == -1) { return -2; } if (res->body_data != NULL && &res->response_body_writer != NULL) res->response_body_writer(res->client_sockfd, res->body_data); return 0; }
/* Search the list for a node matching a given key. * The match is performed using the 'match' method * set with listSetMatchMethod(). If no 'match' method * is set, the 'value' pointer of every node is directly * compared with the 'key' pointer. * * On success the first matching node pointer is returned * (search starts from head). If no matching node exists * NULL is returned. */ list_node *list_search_key(list *list, void *key, int len) { list_iter *iter; list_node *node; iter = list_get_iterator(list, AL_START_HEAD); while((node = list_next(iter)) != NULL) { if (len > 0) { if (memcmp(node->value, key, len) == 0) { list_release_iterator(iter); return node; } } else { if (key == node->value) { list_release_iterator(iter); return node; } } } list_release_iterator(iter); return NULL; }
static inline void aggregate_seed(int agg_type, void *acc, void *start, int count, size_t size) { switch(agg_type) { case AGG_FIRST: memcpy(acc, start, size); return; case AGG_MIN_INT: case AGG_MAX_INT: MELD_INT(acc) = MELD_INT(start); return; case AGG_SUM_INT: MELD_INT(acc) = MELD_INT(start) * count; return; case AGG_MIN_FLOAT: case AGG_MAX_FLOAT: MELD_FLOAT(acc) = MELD_FLOAT(start); return; case AGG_SUM_FLOAT: MELD_FLOAT(acc) = MELD_FLOAT(start) * count; return; case AGG_SET_UNION_INT: { Set *set = set_int_create(); set_int_insert(set, MELD_INT(start)); set_print(set); MELD_SET(acc) = set; return; } case AGG_SET_UNION_FLOAT: { Set *set = set_float_create(); set_float_insert(set, MELD_FLOAT(start)); set_print(set); MELD_SET(acc) = set; return; } case AGG_SUM_LIST_INT: { List *result_list = list_int_create(); List *start_list = MELD_LIST(start); /* add values to result_list */ list_iterator it; for(it = list_get_iterator(start_list); list_iterator_has_next(it); it = list_iterator_next(it)) { meld_int total = list_iterator_int(it) * (meld_int)count; list_int_push_tail(result_list, total); } MELD_LIST(acc) = result_list; return; } case AGG_SUM_LIST_FLOAT: { List *result_list = list_float_create(); List *start_list = MELD_LIST(start); /* add values to result_list */ list_iterator it; for(it = list_get_iterator(start_list); list_iterator_has_next(it); it = list_iterator_next(it)) { meld_float total = list_iterator_float(it) * (meld_float)count; list_float_push_tail(result_list, total); } MELD_LIST(acc) = result_list; return; } } assert(0); while(1); }
static inline bool aggregate_accumulate(int agg_type, void *acc, void *obj, int count) { switch (agg_type) { case AGG_SET_UNION_INT: { Set *set = MELD_SET(acc); set_int_insert(set, MELD_INT(obj)); set_print(set); return false; } case AGG_SET_UNION_FLOAT: { Set *set = MELD_SET(acc); set_float_insert(set, MELD_FLOAT(obj)); set_print(set); return false; } case AGG_FIRST: return false; case AGG_MAX_INT: if (MELD_INT(obj) > MELD_INT(acc)) { MELD_INT(acc) = MELD_INT(obj); return true; } else return false; case AGG_MIN_INT: if (MELD_INT(obj) < MELD_INT(acc)) { MELD_INT(acc) = MELD_INT(obj); return true; } else return false; case AGG_SUM_INT: MELD_INT(acc) += MELD_INT(obj) * count; return false; case AGG_MAX_FLOAT: if(MELD_FLOAT(obj) > MELD_FLOAT(acc)) { MELD_FLOAT(acc) = MELD_FLOAT(obj); return true; } else return false; case AGG_MIN_FLOAT: if(MELD_FLOAT(obj) < MELD_FLOAT(acc)) { MELD_FLOAT(acc) = MELD_FLOAT(obj); return true; } else return false; case AGG_SUM_FLOAT: MELD_FLOAT(acc) += MELD_FLOAT(obj) * (meld_float)count; return false; case AGG_SUM_LIST_INT: { List *result_list = MELD_LIST(acc); List *other_list = MELD_LIST(obj); if(list_total(result_list) != list_total(other_list)) { fprintf(stderr, "lists differ in size for accumulator AGG_SUM_LIST_INT:" " %d vs %d\n", list_total(result_list), list_total(other_list)); exit(1); } list_iterator it_result = list_get_iterator(result_list); list_iterator it_other = list_get_iterator(other_list); while(list_iterator_has_next(it_result)) { list_iterator_int(it_result) += list_iterator_int(it_other) * (meld_int)count; it_other = list_iterator_next(it_other); it_result = list_iterator_next(it_result); } return false; } case AGG_SUM_LIST_FLOAT: { List *result_list = MELD_LIST(acc); List *other_list = MELD_LIST(obj); if(list_total(result_list) != list_total(other_list)) { fprintf(stderr, "lists differ in size for accumulator AGG_SUM_LIST_FLOAT: " "%d vs %d\n", list_total(result_list), list_total(other_list)); exit(1); } list_iterator it_result = list_get_iterator(result_list); list_iterator it_other = list_get_iterator(other_list); while(list_iterator_has_next(it_result)) { list_iterator_float(it_result) += list_iterator_float(it_other) * (meld_float)count; it_result = list_iterator_next(it_result); it_other = list_iterator_next(it_other); } return false; } } assert(0); while(1); }