static void reheap (c_heap_t *h, size_t root, enum reheap_direction dir) { size_t left; size_t right; size_t min; int status; /* Calculate the positions of the children */ left = (2 * root) + 1; if (left >= h->list_len) left = 0; right = (2 * root) + 2; if (right >= h->list_len) right = 0; /* Check which one of the children is smaller. */ if ((left == 0) && (right == 0)) return; else if (left == 0) min = right; else if (right == 0) min = left; else { status = h->compare (h->list[left], h->list[right]); if (status > 0) min = right; else min = left; } status = h->compare (h->list[root], h->list[min]); if (status <= 0) { /* We didn't need to change anything, so the rest of the tree should be * okay now. */ return; } else /* if (status > 0) */ { void *tmp; tmp = h->list[root]; h->list[root] = h->list[min]; h->list[min] = tmp; } if ((dir == DIR_UP) && (root == 0)) return; if (dir == DIR_UP) reheap (h, (root - 1) / 2, dir); else if (dir == DIR_DOWN) reheap (h, min, dir); } /* void reheap */
byte * MultipleIndexIterator::getNextListCompressed(int *length, int *size, byte *buffer) { #if SUPPORT_APPEND_TAIT *length = currentChunkLength; *size = currentChunkSize; byte *result; if (buffer == NULL) buffer = currentChunkCompressed; else { memcpy(buffer, currentChunkCompressed, currentChunkSize); free(currentChunkCompressed); } currentChunkCompressed = NULL; prepareNextChunk(); return buffer; #else int top = iteratorHeap[0]; if (!iterators[top].hasMoreData) { *length = 0; *size = 0; return NULL; } buffer = iterators[top].iterator->getNextListCompressed(length, size, buffer); listPos++; reheap(); return buffer; #endif } // end of getNextListCompressed(int*, int*, byte*)
int c_heap_insert(c_heap_t *h, void *ptr) { size_t index; if ((h == NULL) || (ptr == NULL)) return (-EINVAL); pthread_mutex_lock(&h->lock); assert(h->list_len <= h->list_size); if (h->list_len == h->list_size) { void **tmp; tmp = realloc(h->list, (h->list_size + 16) * sizeof(*h->list)); if (tmp == NULL) { pthread_mutex_unlock(&h->lock); return (-ENOMEM); } h->list = tmp; h->list_size += 16; } /* Insert the new node as a leaf. */ index = h->list_len; h->list[index] = ptr; h->list_len++; /* Reorganize the heap from bottom up. */ reheap(h, /* parent of this node = */ (index - 1) / 2, DIR_UP); pthread_mutex_unlock(&h->lock); return (0); } /* int c_heap_insert */
void heap<T>::modified(T data, bool (*eqCb)(const T&, const T&)) { signed i = treeArr.indexOf(data, eqCb); if (i > 0) // assert that i < currSize { reheap(i); } }
void deheap (void const * heap [], size_t size, int comp (void const *, void const *), void swap (void const *[], size_t, size_t)) { while (size > 1) { swap (heap, 0, --size); reheap (heap, size, comp, swap); } return; }
size_t saveheap (char * heap [], size_t heapsize, FILE * ofp) { while ((heapsize > 0) && (fputs (heap [0], ofp) != EOF)) { swap ((void *) (heap), 0, -- heapsize); reheap ((void *) (heap), heapsize, (int (*)(void const *, void const *)) (comp), swap); free (heap [heapsize]); } return (heapsize); }
T heap<T>::extract() { if (0 == currSize) { throw std::runtime_error("removing from empty heap"); } T data = treeArr[0]; swap(treeArr, 0, currSize-1); g_delete(treeArr[--currSize]); reheap(0); return data; }
bool heap<T>::remove(T data, bool (*eqCb)(const T&, const T&)) { bool dataRemoved = false; signed i = treeArr.indexOf(data, eqCb); if (i > 0) // assert that i < currSize { dataRemoved = true; swap(treeArr, i, currSize); g_delete(treeArr[--currSize]); reheap(i); } return dataRemoved; }
void *c_heap_get_root (c_heap_t *h) { void *ret = NULL; if (h == NULL) return (NULL); pthread_mutex_lock (&h->lock); if (h->list_len == 0) { pthread_mutex_unlock (&h->lock); return (NULL); } else if (h->list_len == 1) { ret = h->list[0]; h->list[0] = NULL; h->list_len = 0; } else /* if (h->list_len > 1) */ { ret = h->list[0]; h->list[0] = h->list[h->list_len - 1]; h->list[h->list_len - 1] = NULL; h->list_len--; reheap (h, /* root = */ 0, DIR_DOWN); } /* free some memory */ if ((h->list_len + 32) < h->list_size) { void **tmp; tmp = realloc (h->list, (h->list_len + 16) * sizeof (*h->list)); if (tmp != NULL) { h->list = tmp; h->list_size = h->list_len + 16; } } pthread_mutex_unlock (&h->lock); return (ret); } /* void *c_heap_get_root */
offset * MultipleIndexIterator::getNextListUncompressed(int *length, offset *buffer) { #if SUPPORT_APPEND_TAIT *length = currentChunkLength; if (buffer == NULL) buffer = typed_malloc(offset, currentChunkLength); memcpy(buffer, currentChunk, currentChunkLength * sizeof(offset)); free(currentChunkCompressed); currentChunkCompressed = NULL; prepareNextChunk(); return buffer; #else int top = iteratorHeap[0]; if (!iterators[top].hasMoreData) { *length = 0; return NULL; } offset *result = iterators[top].iterator->getNextListUncompressed(length, buffer); listPos++; reheap(); return result; #endif } // end of getNextListUncompressed(int*, offset*)
/* * merge -- * Merge sort a group of files to 'outfile'. */ void merge(FILE *infile[], int nfiles, FILE *outfile) { char *lineptr[MERGEORDER]; char linebuf[MERGETEXT]; int lbp = 0, nf = 0; int i, inf; for (i = 0; i < nfiles; i++) { if (fgets(&linebuf[lbp], MAXLINE, infile[i]) != NULL) { lineptr[nf++] = &linebuf[lbp]; lbp += MAXLINE; } } qsort(lineptr, nf, sizeof(lineptr[0]), qcmpstr); while (nf > 0) { fputs(lineptr[0], outfile); inf = (lineptr[0] - linebuf) / MAXLINE; if (fgets(lineptr[0], MAXLINE, infile[inf]) == NULL) { lineptr[0] = lineptr[nf-1]; nf--; } reheap(lineptr, nf, linebuf); } }
static DAZZ_TRACK *merge_tracks(DAZZ_DB *block, int mtop, int64 nsize) { DAZZ_TRACK *ntrack; Event ev[mtop+1]; Event *heap[mtop+2]; int r, mhalf; int64 *anno; int *data; ntrack = (DAZZ_TRACK *) Malloc(sizeof(DAZZ_TRACK),"Allocating merged track"); if (ntrack == NULL) Clean_Exit(1); ntrack->name = Strdup("merge","Allocating merged track"); ntrack->anno = anno = (int64 *) Malloc(sizeof(int64)*(block->nreads+1),"Allocating merged track"); ntrack->data = data = (int *) Malloc(sizeof(int)*nsize,"Allocating merged track"); ntrack->size = sizeof(int); ntrack->next = NULL; if (anno == NULL || data == NULL || ntrack->name == NULL) Clean_Exit(1); { DAZZ_TRACK *track; int i; track = block->tracks; for (i = 0; i < mtop; i++) { ev[i].ano = ((int *) (track->data)) + ((int64 *) (track->anno))[0]; ev[i].out = 1; heap[i+1] = ev+i; track = track->next; } ev[mtop].idx = INT32_MAX; heap[mtop+1] = ev+mtop; } mhalf = mtop/2; nsize = 0; for (r = 0; r < block->nreads; r++) { int i, level, hsize; DAZZ_TRACK *track; anno[r] = nsize; track = block->tracks; for (i = 0; i < mtop; i++) { ev[i].end = ((int *) (track->data)) + ((int64 *) (track->anno))[r+1]; if (ev[i].ano < ev[i].end) ev[i].idx = *(ev[i].ano); else ev[i].idx = INT32_MAX; track = track->next; } hsize = mtop; for (i = mhalf; i > 1; i--) reheap(i,heap,hsize); level = 0; while (1) { Event *p; reheap(1,heap,hsize); p = heap[1]; if (p->idx == INT32_MAX) break; p->out = 1-p->out; if (p->out) { level -= 1; if (level == 0) data[nsize++] = p->idx; } else { if (level == 0) data[nsize++] = p->idx; level += 1; } p->ano += 1; if (p->ano >= p->end) p->idx = INT32_MAX; else p->idx = *(p->ano); } } anno[r] = nsize; return (ntrack); }
static int64 merge_size(DAZZ_DB *block, int mtop) { Event ev[mtop+1]; Event *heap[mtop+2]; int r, mhalf; int64 nsize; { DAZZ_TRACK *track; int i; track = block->tracks; for (i = 0; i < mtop; i++) { ev[i].ano = ((int *) (track->data)) + ((int64 *) (track->anno))[0]; ev[i].out = 1; heap[i+1] = ev+i; track = track->next; } ev[mtop].idx = INT32_MAX; heap[mtop+1] = ev+mtop; } mhalf = mtop/2; nsize = 0; for (r = 0; r < block->nreads; r++) { int i, level, hsize; DAZZ_TRACK *track; track = block->tracks; for (i = 0; i < mtop; i++) { ev[i].end = ((int *) (track->data)) + ((int64 *) (track->anno))[r+1]; if (ev[i].ano < ev[i].end) ev[i].idx = *(ev[i].ano); else ev[i].idx = INT32_MAX; track = track->next; } hsize = mtop; for (i = mhalf; i > 1; i--) reheap(i,heap,hsize); level = 0; while (1) { Event *p; reheap(1,heap,hsize); p = heap[1]; if (p->idx == INT32_MAX) break; p->out = 1-p->out; if (p->out) { level -= 1; if (level == 0) nsize += 1; } else { if (level == 0) nsize += 1; level += 1; } p->ano += 1; if (p->ano >= p->end) p->idx = INT32_MAX; else p->idx = *(p->ano); } } return (nsize); }
void heap<T>::insert(T data) { T buffer; treeArr[currSize++] = data; reheap(currSize-1); }