int main(int argc, char **argv) { Heap heap; void *data; int intval[30], i; /***************************************************************************** * * * Initialize the heap. * * * *****************************************************************************/ heap_init(&heap, compare_int, NULL); /***************************************************************************** * * * Perform some heap operations. * * * *****************************************************************************/ i = 0; intval[i] = 5; fprintf(stdout, "Inserting %03d\n", intval[i]); if (heap_insert(&heap, &intval[i]) != 0) return 1; print_heap(&heap); i++; intval[i] = 10; fprintf(stdout, "Inserting %03d\n", intval[i]); if (heap_insert(&heap, &intval[i]) != 0) return 1; print_heap(&heap); i++; intval[i] = 20; fprintf(stdout, "Inserting %03d\n", intval[i]); if (heap_insert(&heap, &intval[i]) != 0) return 1; print_heap(&heap); i++; intval[i] = 1; fprintf(stdout, "Inserting %03d\n", intval[i]); if (heap_insert(&heap, &intval[i]) != 0) return 1; print_heap(&heap); i++; intval[i] = 25; fprintf(stdout, "Inserting %03d\n", intval[i]); if (heap_insert(&heap, &intval[i]) != 0) return 1; print_heap(&heap); i++; intval[i] = 22; fprintf(stdout, "Inserting %03d\n", intval[i]); if (heap_insert(&heap, &intval[i]) != 0) return 1; print_heap(&heap); i++; intval[i] = 9; fprintf(stdout, "Inserting %03d\n", intval[i]); if (heap_insert(&heap, &intval[i]) != 0) return 1; print_heap(&heap); i++; while (heap_size(&heap) > 0) { if (heap_extract(&heap, (void **) &data) != 0) return 1; fprintf(stdout, "Extracting %03d\n", *(int *) data); print_heap(&heap); } /***************************************************************************** * * * Destroy the heap. * * * *****************************************************************************/ fprintf(stdout, "Destroying the heap\n"); heap_destroy(&heap); return 0; }
int main(void) { uint32_t cnt, i, data[] = {14, 2, 22, 13, 23, 10, 90, 36, 108, 12, 9, 91, 1, 51, 11, 3, 15, 80, 3, 78, 53, 5, 12, 21, 65, 70, 4}; const uint32_t data_len = sizeof(data)/sizeof(uint32_t); struct heap heap = heap_create(data_len + 5); printf(COL_BEG "push data...\n" COL_END); for (i = 0; i < data_len; i++) if (!heap_full(&heap)) heap_push(&heap, &data[i]); printf("data len = %u, heap size = %u.\n", data_len, heap_size(&heap)); printf(COL_BEG "heap tree:\n" COL_END); heap_print_tr(&heap, &test_print); printf(COL_BEG "heap array:\n" COL_END); heap_print_arr(&heap, &test_print); heap_set_callbk(&heap, &test_less_than); printf(COL_BEG "after heapify:\n" COL_END); minheap_heapify(&heap); heap_print_tr(&heap, &test_print); cnt = 0; printf(COL_BEG "ranking emulation...:\n" COL_END); while (cnt < 100) { i = (i + 1) % data_len; if (!heap_full(&heap)) { printf("insert %d\n", data[i]); minheap_insert(&heap, &data[i]); } else { void *top = heap_top(&heap); if (test_less_than(top, &data[i])) { printf("replace with %d\n", data[i]); minheap_delete(&heap, 0); minheap_insert(&heap, &data[i]); } } cnt ++; } printf(COL_BEG "a heavy heap tree now:\n" COL_END); heap_print_tr(&heap, &test_print); minheap_sort(&heap); printf(COL_BEG "heap array after min-heap sort:\n" COL_END); heap_print_arr(&heap, &test_print); heap_destory(&heap); printf(COL_BEG "a new heap...\n" COL_END); heap = heap_create(data_len + 5); heap_set_callbk(&heap, &test_less_than); for (i = 0; i < data_len; i++) if (!heap_full(&heap)) heap_push(&heap, &data[i]); printf(COL_BEG "heap array:\n" COL_END); heap_print_arr(&heap, &test_print); heap_sort_desc(&heap); printf(COL_BEG "heap array after heap sort:\n" COL_END); heap_print_arr(&heap, &test_print); heap_print_tr(&heap, &test_print); heap_destory(&heap); printf(COL_BEG "sort a heap with one element...\n" COL_END); heap = heap_create(data_len + 5); heap_set_callbk(&heap, &test_less_than); heap_push(&heap, &data[0]); heap_print_tr(&heap, &test_print); heap_sort_desc(&heap); heap_destory(&heap); return 0; }
int heap_extract(Heap *heap, void **data) { void *save, *temp; int ipos, lpos, rpos, mpos; /***************************************************************************** * * * Do not allow extraction from an empty heap. * * * *****************************************************************************/ if (heap_size(heap) == 0) return -1; /***************************************************************************** * * * Extract the node at the top of the heap. * * * *****************************************************************************/ *data = heap->tree[0]; /***************************************************************************** * * * Adjust the storage used by the heap. * * * *****************************************************************************/ save = heap->tree[heap_size(heap) - 1]; if (heap_size(heap) - 1 > 0) { if ((temp = (void **)realloc(heap->tree, (heap_size(heap) - 1) * sizeof (void *))) == NULL) { return -1; } else { heap->tree = temp; } /************************************************************************** * * * Adjust the size of the heap to account for the extracted node. * * * **************************************************************************/ heap->size--; } else { /************************************************************************** * * * Manage the heap when extracting the last node. * * * **************************************************************************/ free(heap->tree); heap->tree = NULL; heap->size = 0; return 0; } /***************************************************************************** * * * Copy the last node to the top. * * * *****************************************************************************/ heap->tree[0] = save; /***************************************************************************** * * * Heapify the tree by pushing the contents of the new top downward. * * * *****************************************************************************/ ipos = 0; lpos = heap_left(ipos); rpos = heap_right(ipos); while (1) { /************************************************************************** * * * Select the child to swap with the current node. * * * **************************************************************************/ lpos = heap_left(ipos); rpos = heap_right(ipos); if (lpos < heap_size(heap) && heap->compare(heap->tree[lpos], heap-> tree[ipos]) > 0) { mpos = lpos; } else { mpos = ipos; } if (rpos < heap_size(heap) && heap->compare(heap->tree[rpos], heap-> tree[mpos]) > 0) { mpos = rpos; } /************************************************************************** * * * When mpos is ipos, the heap property has been restored. * * * **************************************************************************/ if (mpos == ipos) { break; } else { /*********************************************************************** * * * Swap the contents of the current node and the selected child. * * * ***********************************************************************/ temp = heap->tree[mpos]; heap->tree[mpos] = heap->tree[ipos]; heap->tree[ipos] = temp; /*********************************************************************** * * * Move down one level in the tree to continue heapifying. * * * ***********************************************************************/ ipos = mpos; } } return 0; }
int heap_insert(Heap *heap, const void *data) { void *temp; int ipos, ppos; /***************************************************************************** * * * Allocate storage for the node. * * * *****************************************************************************/ if ((temp = (void **)realloc(heap->tree, (heap_size(heap) + 1) * sizeof (void *))) == NULL) { return -1; } else { heap->tree = temp; } /***************************************************************************** * * * Insert the node after the last node. * * * *****************************************************************************/ heap->tree[heap_size(heap)] = (void *)data; /***************************************************************************** * * * Heapify the tree by pushing the contents of the new node upward. * * * *****************************************************************************/ ipos = heap_size(heap); ppos = heap_parent(ipos); while (ipos > 0 && heap->compare(heap->tree[ppos], heap->tree[ipos]) < 0) { /************************************************************************** * * * Swap the contents of the current node and its parent. * * * **************************************************************************/ temp = heap->tree[ppos]; heap->tree[ppos] = heap->tree[ipos]; heap->tree[ipos] = temp; /************************************************************************** * * * Move up one level in the tree to continue heapifying. * * * **************************************************************************/ ipos = ppos; ppos = heap_parent(ipos); } /***************************************************************************** * * * Adjust the size of the heap to account for the inserted node. * * * *****************************************************************************/ heap->size++; return 0; }
void max_heap_insert(Heap h, Hnode value){ h[0].val += 1; h[heap_size(h)].val = INT_MIN; heap_increase_key(h, heap_size(h), value); }
void heap_print(Heap h){ for(int i = 1 ; i <= heap_size(h); i++){ printf("%d %g ",h[i].id, h[i].val); } printf("\n"); }
// Implementation from: // https://en.wikipedia.org/wiki/A*_search_algorithm#Pseudocode int a_star(list_t graph, int width, int height, point_t* start, point_t* goal) { list_t closed; list_create(&closed, width * height); start->dist = 0; f_score[start->x][start->y] = start->dist + heuristic_cost_estimate(start, goal); heap_t open; heap_create(&open, width * height); heap_insert(open, 0, start); while (heap_size(open) > 0) { // find node with minimal f_score value point_t* current; heap_remove(open, ¤t); if (current == goal) { list_free(closed, NULL, NULL); heap_free(open, NULL, NULL); return EXIT_SUCCESS; } // remove from open list and insert into closed list list_insert(closed, current->id, current); // for neighbours of current for (int i = MAX(current->x - 1, 0); i <= MIN(current->x + 1, width - 1); ++i) { for (int j = MAX(current->y - 1, 0); j <= MIN(current->y + 1, height - 1); ++j) { if (i != current->x || j!= current->y) // skip self { point_t* neighbour = graph_find(graph, width, height, i, j); if (list_search(closed, neighbour->id, NULL)) { continue; // ignore neighbour which is already evaluated } int tentative_g_score = current->dist + neighbour->cost; if (tentative_g_score < neighbour->dist) { neighbour->prev = current; neighbour->dist = tentative_g_score; f_score[i][j] = neighbour->dist + heuristic_cost_estimate(neighbour, goal); heap_insert(open, neighbour->dist, neighbour); } } } } } list_free(closed, NULL, NULL); heap_free(open, NULL, NULL); return EXIT_FAILURE; }
int heap_extract(Heap *heap, void **data) { void *save, *temp; int ipos, lpos, rpos, mpos; if (heap_size(heap) == 0) return -1; *data = heap->tree[0]; save = heap->tree[heap_size(heap) - 1]; /* * Adjust heap storage. There are two cases: * * 1. Only one node left * 2. More than one node left */ /* Case 1: Only one left */ if (heap_size(heap) - 1 == 0) { free(heap->tree); heap->tree = NULL; heap->size = 0; return 0; } /* Case 2: More than 1 left */ if ((temp = (void **)realloc(heap->tree,(heap_size(heap) - 1) * sizeof(void *))) == NULL) return -1; heap->tree = temp; heap->size--; /* * Copy last node to top and then heapify */ heap->tree[0] = save; ipos = 0; while (1) { lpos = heap_left(ipos); rpos = heap_right(ipos); /* * Find position with max value. First check left child... */ if (lpos < heap_size(heap) && heap->compare(heap->tree[lpos], heap->tree[ipos]) > 0) mpos = lpos; else mpos = ipos; /* ...then check right child */ if (rpos < heap_size(heap) && heap->compare(heap->tree[rpos], heap->tree[mpos]) > 0) mpos = rpos; /* If the max position is the insert position, we're done. */ if (mpos == ipos) break; /* otherwise, keep going */ temp = heap->tree[mpos]; heap->tree[mpos] = heap->tree[ipos]; heap->tree[ipos] = temp; ipos = mpos; } return 0; }
bool serialize(const int devfd, struct bitcoin_storage *const st, bool serial_pad) { static struct encoder_state s; static bool first_run = true; static int buf_left = 0; // Bytes left to send static int buf_i = 0; // Bytes position of next unsent byte if (first_run) { encoder_state_init(&s); first_run = false; } gint queued = heap_size(&st->send_queue); if (!buf_left && queued) { // Try to fill send buffer struct msg *m = bitcoin_dequeue(st); // Should not happen if (m == NULL) errx(6,"Send queue handling error"); // Do not retransmit if it is already sent. if (m->sent) { printf("Already sent %s %s, skipping\n", bitcoin_type_str(m), hex256(bitcoin_inv_hash(m))); return true; } // Mark message as sent m->sent = true; // Calculate signature. FIXME: Include type in calculation! // Bitcoin message header in unidirectional // transfer. The signature is used to verify the // transmitter. Transactions have their own signature // inside message body, too. unsigned char sig[72]; int siglen; secp256k1_ecdsa_sign(m->payload,m->length,sig,&siglen,NULL,NULL); encode_start(&s); encode(&s,&siglen,1); // FIXME doesn't work on big endian archs encode(&s,&sig,siglen); encode(&s,&m->type,1); // FIXME doesn't work on big endian archs encode(&s,m->payload,m->length); // Finishing encoding and updating send buffer buf_left = encode_end(&s); buf_i = 0; // Debugging char height_buf[20] = ""; if (m->height != UNCONFIRMED) { snprintf(height_buf,sizeof(height_buf), " @ %d",m->height); } printf("Sending %s %s%s, %d bytes, %d items left\n", bitcoin_type_str(m), hex256(bitcoin_inv_hash(m)), height_buf, m->length, queued); } if (buf_left) { // Consume buffer as much as possible const int wrote = write(devfd, s.buf+buf_i, buf_left); if (wrote == 0) { errx(3,"Weird behaviour on serial port"); } else if (wrote == -1) { err(4,"Unable to write to serial port"); } buf_i += wrote; buf_left -= wrote; } else { if (!serial_pad) { // All is sent, do not come back until there // is more data availableq printf("Serial device idle\n"); return false; } // Send padding and go back to waiting loop. guint8 buf[PAD_COUNT*5]; int i = 0; while (i < sizeof(buf)) { // Z_SYNC_FLUSH is 5 bytes long: buf[i++] = 0x00; buf[i++] = 0x00; buf[i++] = 0x00; buf[i++] = 0xFF; buf[i++] = 0xFF; } const int ret = write(devfd,buf,sizeof(buf)); if (ret < 1) err(4,"Unable to write to serial port"); if (ret != sizeof(buf)) err(10,"Too large padding buffer or non-linuxy system"); printf("Sending %d bytes of padding\n",ret); } return true; }
int main(int argc, char** argv) { pre=sbrk(0); bottom=malloc(256)-sizeof(size_t); // don't free this one - that keeps it an innocuous stub (a root with no graph attached) init_gc(); timediff(); printf("Checking global root set handling an general GC functionality\n"); /* the most basic allocation and clearing pointer exercise. This only checks for following the root set pointers one level. */ void *pre = sbrk(0); for(int i=0;i<MAX_ALLOCATIONS;i++) allocs[i]=malloc(i*2+128); printf("Heap after first round of allocations: %zu, free %d, inuse %d\n",heap_size(),free_chunks(),inuse_chunks()); for(int i=0;i<MAX_ALLOCATIONS;i++) allocs[i]=0; gc(); printf("Heap after first gc(): %zu, free %d, inuse %d\n",heap_size(),free_chunks(),inuse_chunks()); /* allocations which all point to each other. this checks for proper traversal of the chunk graph. */ for(int i=0;i<MAX_ALLOCATIONS;i++) { allocs[i]=malloc(i*2+128); if(i>0) *(void**)(allocs[i])=allocs[i-1]; } printf("Heap after second round of allocations: %zu, free %d, inuse %d\n",heap_size(),free_chunks(),inuse_chunks()); for(int i=0;i<MAX_ALLOCATIONS-1;i++) allocs[i]=0; gc(); // here, since we keep the last entry, which points to the next-to-last and so on, everything should still be around printf("Heap after clearing all but one, and gc(): %zu, free %d, inuse %d\n",heap_size(),free_chunks(),inuse_chunks()); allocs[MAX_ALLOCATIONS-1]=0; gc(); printf("Heap after clearing last one, and gc(): %zu, free %d, inuse %d\n",heap_size(),free_chunks(),inuse_chunks()); /* allocations which all point to each other. this checks for proper traversal of the chunk graph. */ for(int i=0;i<MAX_ALLOCATIONS;i++) { allocs[i]=malloc(i*2+128); if(i>0) { void *start_of_new_alloc = allocs[i]; void *start_of_prev_alloc = allocs[i-1]; int offset_into_new_alloc = 8*random_up_to((i*2+120)/8); int offset_into_old_alloc = 8*random_up_to(((i-1)*2+120)/8); void **location_of_pointer = (void**)(start_of_new_alloc + offset_into_new_alloc); *location_of_pointer = start_of_prev_alloc + offset_into_old_alloc; } } printf("Heap after third round of allocations: %zu, free %d, inuse %d\n",heap_size(),free_chunks(),inuse_chunks()); for(int i=0;i<MAX_ALLOCATIONS-1;i++) allocs[i]=0; gc(); // here, since we keep the last entry, which points to the next-to-last and so on, everything should still be around printf("Heap after clearing all but one, and gc(): %zu, free %d, inuse %d\n",heap_size(),free_chunks(),inuse_chunks()); allocs[MAX_ALLOCATIONS-1]=0; gc(); printf("Heap after clearing last one, and gc(): %zu, free %d, inuse %d\n",heap_size(),free_chunks(),inuse_chunks()); printf("Now checking stack root set handling.\n"); recursive_allocations(100); gc(); printf("After Recursive1 %zu, free %d, inuse %d\n",heap_size(),free_chunks(),inuse_chunks()); recursive_allocations2(100); gc(); printf("After Recursive2 %zu, free %d, inuse %d\n",heap_size(),free_chunks(),inuse_chunks()); }
int router_nearest(struct router_t* router, const uint8_t id[N_NODEID], struct node_t* nodes[], size_t count) { int i, min, diff; uint8_t xor[N_NODEID]; heap_t* heap; struct rbitem_t* item; struct rbtree_node_t* node; const struct rbtree_node_t* prev; const struct rbtree_node_t* next; heap = heap_create(node_compare_less, (void*)id); heap_reserve(heap, count + 1); min = N_BITS; locker_lock(&router->locker); rbtree_find(&router->rbtree, id, &node); if (NULL == node) { locker_unlock(&router->locker); return 0; } item = rbtree_entry(node, struct rbitem_t, link); bitmap_xor(xor, id, item->node->id, N_BITS); diff = bitmap_count_leading_zero(xor, N_BITS); min = min < diff ? min : diff; heap_push(heap, item->node); prev = rbtree_prev(node); next = rbtree_next(node); do { while (prev) { item = rbtree_entry(prev, struct rbitem_t, link); bitmap_xor(xor, id, item->node->id, N_BITS); diff = bitmap_count_leading_zero(xor, N_BITS); heap_push(heap, item->node); if (heap_size(heap) > (int)count) heap_pop(heap); prev = rbtree_prev(prev); if (diff < min) { min = diff; break; // try right } } while (next) { item = rbtree_entry(next, struct rbitem_t, link); bitmap_xor(xor, id, item->node->id, N_BITS); diff = bitmap_count_leading_zero(xor, N_BITS); heap_push(heap, item->node); if (heap_size(heap) > (int)count) heap_pop(heap); next = rbtree_next(next); if (diff < min) { min = diff; break; // try left } } } while (heap_size(heap) < (int)count && (prev || next)); for (i = 0; i < (int)count && !heap_empty(heap); i++) { nodes[i] = heap_top(heap); node_addref(nodes[i]); heap_pop(heap); } locker_unlock(&router->locker); heap_destroy(heap); return i; }
QueryResult *Query_Execute(Query *query) { //__queryStage_Print(query->root, 0); QueryResult *res = malloc(sizeof(QueryResult)); res->error = 0; res->errorString = NULL; res->totalResults = 0; res->ids = NULL; res->numIds = 0; int num = query->offset + query->limit; heap_t *pq = malloc(heap_sizeof(num)); heap_init(pq, cmpHits, NULL, num); // start lazy evaluation of all query steps IndexIterator *it = NULL; if (query->root != NULL) { it = Query_EvalStage(query, query->root); } // no query evaluation plan? if (query->root == NULL || it == NULL) { res->error = QUERY_ERROR_INTERNAL; res->errorString = QUERY_ERROR_INTERNAL_STR; return res; } IndexHit *pooledHit = NULL; // iterate the root iterator and push everything to the PQ while (1) { // TODO - Use static allocation if (pooledHit == NULL) { pooledHit = malloc(sizeof(IndexHit)); } IndexHit *h = pooledHit; IndexHit_Init(h); int rc = it->Read(it->ctx, h); if (rc == INDEXREAD_EOF) { break; } else if (rc == INDEXREAD_NOTFOUND) { continue; } h->totalFreq = processHitScore(h, query->docTable); ++res->totalResults; if (heap_count(pq) < heap_size(pq)) { heap_offerx(pq, h); pooledHit = NULL; } else { IndexHit *qh = heap_peek(pq); if (qh->totalFreq < h->totalFreq) { pooledHit = heap_poll(pq); heap_offerx(pq, h); // IndexHit_Terminate(pooledHit); } else { pooledHit = h; // IndexHit_Terminate(pooledHit); } } } if (pooledHit) { free(pooledHit); } it->Free(it); // Reverse the results into the final result size_t n = MIN(heap_count(pq), query->limit); res->numIds = n; res->ids = calloc(n, sizeof(RedisModuleString *)); for (int i = 0; i < n; ++i) { IndexHit *h = heap_poll(pq); LG_DEBUG("Popping %d freq %f", h->docId, h->totalFreq); res->ids[n - i - 1] = Redis_GetDocKey(query->ctx, h->docId); free(h); } // if we still have something in the heap (meaning offset > 0), we need to // poll... while (heap_count(pq) > 0) { IndexHit *h = heap_poll(pq); free(h); } heap_free(pq); return res; }
/**************************************************************************************** * Function name - tq_size * * Description - Returns current size of timer-queue * * Input - *tq - pointer to an initialized timer queue, e.g. heap * Return Code/Output - On Success - zero or positive number, on error - (-1) ****************************************************************************************/ int tq_size (timer_queue*const tq) { return heap_size ((heap *const) tq); }
__inline int pqueue_size(const PQueue queue) { return heap_size(queue); }
int main(int argc, char** argv) { // Create the heap heap h; heap_create(&h, 0, NULL); // Maximum int count = 10000000; // 10M if (argc > 1) count = atoi(argv[1]); // Get the count as an argument printf("Sorting array of %d random entries.\n", count); // Allocate a key and value int* key = (int*)malloc(count*sizeof(int)); char* value = "The meaning of life."; // Initialize the first key unsigned int val = 42; srand(val); printf("Seed %d\n", val); // Store that as the minimum int min = INT_MAX; // Use a pseudo-random generator for the other keys for (int i=0; i<count; i++) { *(key+i) = rand(); // Check for a new min if (*(key+i) < min) min = *(key+i); // Insert into the heap heap_insert(&h, key+i, value); } // Get the minimum int* min_key; char* min_val; int *prev_key = &min; // Show the real minimum printf("Real min: %d\n", min); // Try to get the minimum while (heap_delmin(&h, (void**)&min_key, (void**)&min_val)) { // Verify that the values are getting larger if (*prev_key > *min_key) { printf("Previous key is greater than current key!\n"); break; } prev_key = min_key; } if (heap_size(&h) == 0) printf("Verify success!\n"); // Clean up the heap heap_destroy(&h); }