LElement * list_flat(LElement * list) { LElement * next_element; LElement * new_list; new_list = list_init(); next_element = list; // printf("Plaszcze:\n"); // status(list); // getchar(); do { next_element = next_element->pointer; if (next_element->czy_lista) { // printf("To lista, rekursja!\n"); new_list = list_merge(new_list, list_flat(next_element->sublist)); } else { // printf("To wartosc!\n"); new_list = list_push_value(new_list, next_element->value); } } while(next_element != list); // printf("...splaszczylem.\n"); return new_list; }
static linked_list_t * shc_split_buckets(shardcache_client_t *c, shc_multi_item_t **items, int *num_items) { linked_list_t *pools = list_create(); int i; for(i = 0; items[i]; i++) { shc_multi_item_t *item = items[i]; item->idx = i; char *addr = select_node(c, item->key, item->klen, NULL); tagged_value_t *tval = list_get_tagged_value(pools, addr); if (!tval || list_count((linked_list_t *)tval->value) > c->pipeline_max) { linked_list_t *sublist = list_create(); tval = list_create_tagged_sublist(addr, sublist); // put the new sublist at the beggining of the main tagged list // so that in case of multiple lists for the same node this will // be the one returned by list_get_tagged_value() list_unshift_tagged_value(pools, tval); } list_push_value((linked_list_t *)tval->value, item); } if (num_items) *num_items = i; return pools; }
/* * ... without removing it from the list * USER MUST NOT FREE MEMORY FOR RETURNED VALUES * User MUST create a new list, pass it as 'values' * and destroy it when no more needed .... entries * returned inside the 'values' list MUST not be freed, * because they reference directly the real entries inside 'list'. */ size_t list_get_tagged_values(linked_list_t *list, char *tag, linked_list_t *values) { int i; int ret; tagged_value_t *tval; ret = 0; for(i = 0;i < (int)list_count(list); i++) { tval = list_pick_tagged_value(list, i); if (!tval) { continue; } if(strcmp(tval->tag, tag) == 0) { list_push_value(values, tval->value); ret++; } } return ret; }
// merge two heaps in a single iteration binheap_t *binheap_merge(binheap_t *bh1, binheap_t *bh2) { if (bh1->mode != bh2->mode) { // refuse to merge binomial heaps initialized with different operational modes // TODO - error message return NULL; } linked_list_t *new_list = list_create(); binomial_tree_node_t *node1 = list_shift_value(bh1->trees); binomial_tree_node_t *node2 = list_shift_value(bh2->trees); binomial_tree_node_t *carry = NULL; while (node1 || node2 || carry) { if (carry) { // if we have a carry (merged tree from previous iteration) // lets check if either node1 or node2 is of the same order and // in case let's merge it before comparing node1 with node2 so // we get rid of the carry as soon as possible binomial_tree_node_t *node = NULL; if (node1 && node1->num_children == carry->num_children) { node = node1; } else if (node2 && node2->num_children == carry->num_children) { node = node2; } else { if (!node1 && !node2) { // if we have the carry but there is neither node1 nor node2 // we can just add the carry to the list and forget about it list_push_value(new_list, carry); carry = NULL; continue; } // if either node1 or node2 is of an higher order than the carry, // let's swap it so that we will always compare the lower order trees // among the three (node1, node2 and carry) if (node1 && node1->num_children > carry->num_children) { binomial_tree_node_t *tmp = node1; node1 = carry; carry = tmp; } else if (node2 && node2->num_children > carry->num_children) { binomial_tree_node_t *tmp = node2; node2 = carry; carry = tmp; } } if (node) { if (HAS_PRECEDENCE(bh1, node->key, node->klen, carry->key, carry->klen)) { binomial_tree_merge(node, carry); } else { binomial_tree_merge(carry, node); if (node == node1) node1 = carry; else node2 = carry; } carry = NULL; } } // we have already taken care of the carry here // so now if either node1 or node2 is missing // we can just add the other to the list and go ahead if (node1 && !node2) { list_push_value(new_list, node1); node1 = list_shift_value(bh1->trees); continue; } else if (node2 && !node1) { list_push_value(new_list, node2); node2 = list_shift_value(bh2->trees); continue; } else if (carry && !node1 && !node2) { // XXX - this case should have already been handled earlier // (we have a carry but neither node1 nor node2) list_push_value(new_list, carry); carry = NULL; continue; } int order1 = node1->num_children; int order2 = node2->num_children; // compare node1 and node2 and if they are of different orders // let's add the lower one to the list and go ahead if (order1 < order2) { list_push_value(new_list, node1); node1 = list_shift_value(bh1->trees); continue; } else if (order1 > order2) { list_push_value(new_list, node2); node2 = list_shift_value(bh2->trees); continue; } // if we are here node1 and node2 have the same order so they // need to be merged if (HAS_PRECEDENCE(bh1, node1->key, node1->klen, node2->key, node2->klen)) { binomial_tree_merge(node1, node2); if (carry) { if (bh1->cbs->cmp(node1->key, node1->klen, carry->key, carry->klen) >= 0) { binomial_tree_merge(node1, carry); carry = node1; } else { binomial_tree_merge(carry, node1); } } else { carry = node1; } } else { binomial_tree_merge(node2, node1); if (carry) { if (HAS_PRECEDENCE(bh1, node2->key, node2->klen, carry->key, carry->klen)) { binomial_tree_merge(node2, carry); carry = node2; } else { binomial_tree_merge(carry, node2); } } else { carry = node2; } } // the two trees (node1 and node2) have been merged and put into carry, // so let's get the next two nodes (if any) and go ahead node1 = list_shift_value(bh1->trees); node2 = list_shift_value(bh2->trees); } binheap_t *merged_heap = calloc(1, sizeof(binheap_t)); merged_heap->mode = bh1->mode; merged_heap->trees = new_list; merged_heap->count = bh1->count + bh2->count; merged_heap->cbs = bh1->cbs; return merged_heap; }
int main() { LElement * list1; LElement * list2; LElement * list3; LElement * list4; // Lista 1 list1 = list_init(); list1 = list_push_value(list1, 3); list1 = list_push_value(list1, 1); list1 = list_push_value(list1, 5); // Lista 2 list2 = list_init(); list2 = list_push_value(list2, 2); list2 = list_push_list(list2); list2->sublist = list_push_value(list2->sublist, 4); list2->sublist = list_push_value(list2->sublist, 7); list2 = list_push_list(list2); // Lista 3 list3 = list_init(); list3 = list_push_list(list3); list3->sublist = list_push_list(list3->sublist); list3->sublist->sublist = list_push_value(list3->sublist->sublist, 3); list3->sublist = list_push_list(list3->sublist); list3->sublist->sublist = list_push_value(list3->sublist->sublist, 5); list3->sublist->sublist = list_push_value(list3->sublist->sublist, 8); list3->sublist = list_push_value(list3->sublist, 2); list3 = list_push_list(list3); list3->sublist = list_push_value(list3->sublist, 1); list3->sublist = list_push_value(list3->sublist, 5); list1 = list_merge(list2, list1); list4 = list_flat(list3); printf("PO POLACZENIU:\n"); status(list1); printf("LISTA 4 - JEDNOPOZIOMOWA:\n"); status(list4); printf("LISTA 3 - WIELOPOZIOMOWA, ZRODLO LISTA 4, NIEZMIENIONE:\n"); status(list3); return 0; }