Beispiel #1
0
void
heap_heapify(heap_t* h, int i)
{
    int l, r;
    int largest;
    double tmp;
    double* tmp_data; // FIXME: void*

    if (i < h->len/2) {
        l = HEAP_LEFT(i);
        r = HEAP_RIGHT(i);

        if((l < h->len) && (h->A[l] > h->A[i]))
            largest = l;
        else
            largest = i;

        if((r < h->len) && (h->A[r] > h->A[largest]))
            largest = r;

        if(largest != i)
        {
            tmp = h->A[i];
            tmp_data = h->data[i];
            h->A[i] = h->A[largest];
            h->data[i] = h->data[largest];
            h->A[largest] = tmp;
            h->data[largest] = tmp_data;
            heap_heapify(h,largest);
        }
    }
}
Beispiel #2
0
void 
heap_deletehead (void *heap, int size, int *num, heap_comp hc)
{
  (*num)--;
  SWAP (size, heap, (char *) heap + *num * size);
  heap_heapify (heap, size, *num, 1, hc);
}
Beispiel #3
0
/************************************************************************
 *
 * NOTE: If you choose to change the comparison function the first thing 
 *       you do after changing the function is call heap_build.
 *
 */
void 
heap_build (void *heap, int size, int num, heap_comp hc)
{
  register int i;
  for (i = num / 2; i > 0; i--)
    heap_heapify (heap, size, num, i, hc);
}
Beispiel #4
0
static int
heap_heapify(Heap *h,int idx)
{
    int 		l,r,largest;
    HeapInternCmp 	cmp_func;
    DBG(debug("heap_heapify(h=%p,idx=%d)\n",h,idx));

    l = HLEFT(idx);
    r = HRIGHT(idx);

    LLOG(l); LLOG(r);

    if (h->hpMode == HEAP_MAXIMIZE)
	cmp_func = heap_larger;
    else 
    	cmp_func = heap_smaller;

    if (l <= HSIZE(h) && cmp_func(h,HARRAY(h,l),HARRAY(h,idx)))
	largest = l; 
    else 
	largest = idx;

    if (r <= HSIZE(h) && cmp_func(h,HARRAY(h,r),HARRAY(h,largest)))
	largest = r;

    if (largest != idx)
    {
	heap_swap(h,idx,largest);
	return heap_heapify(h,largest);
    }

    return 0;
}
Beispiel #5
0
void test_heapify(void) {
  size_t i;
  /* initialize data */
  int *array = zmalloc(sizeof(int) * LOTS_OF_INTS);
  int sum = 0;
  for (i = 0; i < LOTS_OF_INTS; i++) {
    array[i] = random() % 123456789;
    sum += array[i];
  }

  /* construct a heap from our random array */
  heap_t *h = heap_heapify(array, LOTS_OF_INTS, sizeof(int),
                           NULL, (cmp_func_t)intcmp);

  assert(heap_size(h) == LOTS_OF_INTS);
  int ctrlsum = 0, maxctrl, *e;
  /* peek head */
  if (heap_size(h)) maxctrl = *(int*)heap_get(h, 0);
  while (heap_size(h)) {
    e = heap_pop(h); ctrlsum += *e;
    /* check that elements are in heap order */
    assert(*e <= maxctrl); maxctrl = *e;
  }
  assert(ctrlsum == sum);
  heap_destroy(h);
  free(array);
}
Beispiel #6
0
static void heap_heapify(struct heap *h, unsigned int i)
{
	unsigned int l, r, smallest;
	struct heapitem *tmp;

	l = (2 * i) + 1;	/* left child */
	r = l + 1;		/* right child */
    
	if ((l < h->size) && h->cmp(h->map[l], h->map[i]))
		smallest = l;
	else
		smallest = i;

	if ((r < h->size) && h->cmp(h->map[r], h->map[smallest]))
		smallest = r;

	if (smallest == i)
		return;

	/* exchange to maintain heap property */
	tmp = h->map[smallest];
	h->map[smallest] = h->map[i];
	h->map[smallest]->index = smallest;
	h->map[i] = tmp;
	h->map[i]->index = i;
	heap_heapify(h, smallest);
}
Beispiel #7
0
int heap_build( heap_t *heap_in )
{
	long j = ( heap_in->size >> 1 ); /* divide by 2... kind of */
	while( j >= 0 )
	{
		heap_heapify( heap_in, j );
		--j;
	}
	return 0;
}
Beispiel #8
0
/****************************************************
 *
 * NOTE : The heap must be built before heap_sort is called. 
 *        This has the effect of reversing the order of the array.
 *		e.g. if your comparison function is designed to pull the
 *                   biggest thing off the heap first then the result of
 *		     sorting with this function will be to put the bigest
 *                   thing at the end of the array.
 *
 */
void 
heap_sort (void *heap, int size, int num, heap_comp hc)
{
  register int i;
  for (i = num; i > 1; i--)
    {
      SWAP (size, heap, (char *) heap + (i - 1) * size);
      heap_heapify (heap, size, i - 1, 1, hc);
    }
}
Beispiel #9
0
void*
heap_extract_max(heap_t* h)
{
    void* max;

    assert(h->len > 0);

    max = h->data[0];
    h->A[0] = h->A[h->len - 1];
    h->data[0] = h->data[h->len - 1];
    h->len--;
    heap_heapify(h,0);
    return(max);
}
Beispiel #10
0
heapItem heap_delete(heap *h, int i)
{
  heapItem hi;
  assert(h);
  assert(h->size>i);
  // get item
  hi = h->items[i];
  // fill in the gap
  h->size--;
  h->items[i] = h->items[h->size];
  // reorder heap array
  heap_heapify(h, i);
  return hi;
}
Beispiel #11
0
int
heap_pop(struct heap_list *h, TYPE **data)
{
	if (h == NULL || h->heap_keys == 0) {
		errno = ENOENT;
		return -1;
	}
	if (data != NULL)
		*data = h->heap_data[0];
	if (h->heap_keys < (h->heap_size / 2))
		heap_decr(h); 
	h->heap_data[0] = h->heap_data[--h->heap_keys];
	heap_heapify(h, 0);
	return 0;
}
Beispiel #12
0
struct heapitem *heap_remove(struct heap *h, unsigned int index)
{
    struct heapitem *item;

    if (index >= h->size)
		return NULL;

    item = h->map[index];
    h->size--;
	h->map[index] = h->map[h->size];
	heap_heapify(h, index);
    item->index = 0;
    item->active = 0;

    return item;
}
Beispiel #13
0
struct heapnode heap_extract_min(struct heap *h)
{
    if (h->nnodes == 0)
	return (struct heapnode){0, NULL};
    struct heapnode minnode = h->nodes[1];
    h->nodes[1] = h->nodes[h->nnodes];
    h->Vtoidx[h->nodes[1].value] = 1;
    h->nnodes--;
    heap_heapify(h, 1);
    return minnode;
}

void heap_heapify(struct heap *h, int index)
{
    for (;;) {
	int left = 2 * index;
	int right = 2 * index + 1;
	// Find largest key: A[index], A[left] and A[right]
	int largest = index;
	if (left <= h->nnodes && h->nodes[largest].key > h->nodes[left].key) {
	    largest = left;
	}
	if (right <= h->nnodes && h->nodes[largest].key > h->nodes[right].key) {
	    largest = right;
	}
	if (largest == index)
	    break;
	heap_swap(h, index, largest);
	index = largest;
    }
}

int heap_decrease_key(struct heap *h, int value, int key)
{
    int index = h->Vtoidx[value];
    if (h->nodes[index].key < key)
	return -1;
    h->nodes[index].key = key;
    for ( ; index > 1 && h->nodes[index].key < h->nodes[index / 2].key; index = index / 2) {
	heap_swap(h, index, index / 2);
    }
    h->Vtoidx[value] = index;
    return 0;
}
Beispiel #14
0
int heap_heapify( heap_t *heap_in, long idx_in )
{
	byte_t *start = (byte_t*) heap_in->start;
	int step = heap_in->step;
	long m = idx_in;
	const long l = heap_left( idx_in );
	const long r = heap_right( idx_in );
	if( ( l < heap_in->size ) && heap_in->cmp( start + l * step, start + idx_in * step ) == 1 )
		m = l;
	if( ( r < heap_in->size ) && heap_in->cmp( start + r * step, start + m * step ) == 1 )
		m = r;
	if( m != idx_in )
	{
		if( heap_swap( heap_in, idx_in, m ) != 0 )
			return -1;
		if( heap_heapify( heap_in, m ) != 0 )
			return -2;
	}
	return 0;
}
Beispiel #15
0
void heap_heapify(heap *h, int i)
{
  int left, right, largest;
  heapItem tmp;
  assert(h);
  // left and right children
  left = (i*2)+1;
  right = left+1;
  // find "largest" element
  if(left<h->size && h->comparator(h->items[left], h->items[i])<0)
    largest = left;
  else
    largest = i;
  if(right<h->size && h->comparator(h->items[right], h->items[largest])<0)
    largest = right;
  // swap and recurse, if necessary
  if(largest!=i)
  {
    tmp = h->items[i];
    h->items[i] = h->items[largest];
    h->items[largest] = tmp;
    heap_heapify(h, largest);
  }
}
Beispiel #16
0
/*
 * Return an element from the heap, located at the given index
 */
static HeapElement *
heap_delete(Heap * h,int idx)
{
    HeapElement *he,*helast;
    int		 pidx;
    HeapInternCmp cmp_func;

    DBG(debug("heap_delete(h=%p,idx=%d)\n",h,idx));

    LLOG(HSIZE(h));

    if (idx < 0 || idx >= HSIZE(h))
	{ LLOG(idx); return NULL; }

    if (h->hpMode == HEAP_MAXIMIZE)
	cmp_func = heap_larger;
    else 
    	cmp_func = heap_smaller;

    /* Remember the current element */
    he = HARRAY(h,idx);
    /* Remember the last element */
    helast = HLAST(h);

    h->hpFilled--;

    if (idx == HSIZE(h))
    	/* This is the last element */
	goto end_label;

    /* Put the last element in the position of the current */

    HARRAY(h,idx) = helast;

    if (h->hpChgFunc)
	h->hpChgFunc(HARRAY(h,idx)->heData,idx);

    /* Heapify the new subtree. Then if the root of the subtree 
     * is larger than its parent, propagate it up the tree until
     * it finds is proper location */
    heap_heapify(h,idx);

    pidx = HPARENT(idx);
    LLOG(pidx);

    if (idx > 0)
    {
	while (cmp_func(h,HARRAY(h,idx),HARRAY(h,pidx)))
	{
	    heap_swap(h,idx,pidx);
	    idx = pidx;
	    if (idx == 0)
		break;
	    pidx = HPARENT(idx);
	}
    }

end_label:


    if (NEEDS2SHRINK(h))
    	heap_shrink(h);

    return he;
}
Beispiel #17
0
enum search_ret impact_ord_eval(struct index *idx, struct query *query, 
  struct chash *accumulators, unsigned int acc_limit, struct alloc *alloc, 
  unsigned int mem) {
    double norm_B;
    unsigned int i,
                 terms = 0,
                 blockfine,
                 blocks_read,
                 postings_read = 0,
                 postings = 0,
                 bytes = 0,
                 bytes_read = 0;
    struct term_data *term,
                     *largest;
    struct disksrc *dsrc;

    if (query->terms == 0) {
        /* no terms to process */
        return SEARCH_OK;
    /* allocate space for array */
    } else if (!(term = malloc(sizeof(*term) * query->terms))) {
        return SEARCH_ENOMEM;
    }

    /* sort by selectivity (by inverse t_f) */
    qsort(query->term, query->terms, sizeof(*query->term), f_t_cmp);

    norm_B = pow(idx->impact_stats.w_qt_max / idx->impact_stats.w_qt_min,
        idx->impact_stats.w_qt_min 
          / (idx->impact_stats.w_qt_max - idx->impact_stats.w_qt_min));

    /* initialise data for each query term */
    for (i = 0; i < query->terms; i++) {
        unsigned int termfine;
        double w_qt;

        /* initialise src/vec for term */
        term[i].v.pos = term[i].v.end = NULL;
        term[i].src = NULL;

        w_qt = (1 + log(query->term[i].f_qt)) *
          log(1 + (idx->impact_stats.avg_f_t / query->term[i].f_t));
        w_qt = impact_normalise(w_qt, norm_B, 
            idx->impact_stats.slope, idx->impact_stats.w_qt_max, 
            idx->impact_stats.w_qt_min);
        term[i].w_qt = impact_quantise(w_qt, 
            idx->impact_stats.quant_bits, idx->impact_stats.w_qt_max, 
            idx->impact_stats.w_qt_min);

        /* apply term fine to term impact */
        termfine = (i < 2) ? 0 : i - 2;
        if (termfine < term[i].w_qt) {
            term[i].w_qt -= termfine;
            /* initialise to highest impact, so we'll select and initialise this
             * term before real processing */
            term[i].impact = INT_MAX;
            terms++;
        } else {
            /* we won't use this term */
            term[i].w_qt = 0;
            term[i].impact = 0;
        }
        term[i].blocksize = 0;

        /* XXX */
        postings += query->term[i].f_t;
        bytes += query->term[i].term.vocab.size;
    }

    /* get sources for each term (do this in a seperate loop so we've already
     * excluded lists that we won't use) */
    for (i = 0; i < terms; i++) {
        unsigned int memsize = mem / (terms - i);

        if (memsize > query->term[i].term.vocab.size) {
            memsize = query->term[i].term.vocab.size;
        }

        if (!(term[i].src 
          = search_term_src(idx, &query->term[i].term, alloc, memsize))) {
            source_delete(term, terms);
            free(term);
            return SEARCH_EINVAL;
        }

        mem -= memsize;
    }

    blockfine = blocks_read = 0;
    heap_heapify(term, terms, sizeof(*term), term_data_cmp);

    do {
        largest = heap_pop(term, &terms, sizeof(*term), term_data_cmp);

        if (largest && (largest->impact > blockfine)) {
            postings_read += largest->blocksize;
            if (chash_size(accumulators) < acc_limit) {
                /* reserve enough memory for accumulators and decode */
                if (chash_reserve(accumulators, largest->blocksize) 
                  >= largest->blocksize) {
                    impact_decode_block(accumulators, largest, blockfine);
                } else {
                    assert(!CRASH); ERROR("impact_ord_eval()");
                    source_delete(term, terms);
                    free(term);
                    return SEARCH_EINVAL;
                }
            } else {
                impact_decode_block_and(accumulators, largest, blockfine);
            }

            if (VEC_LEN(&largest->v) < 2 * VEC_VBYTE_MAX) {
                /* need to read more data */
                unsigned int bytes;
                enum search_ret sret;

                if ((sret 
                  = largest->src->readlist(largest->src, VEC_LEN(&largest->v), 
                    (void **) &largest->v.pos, &bytes)) == SEARCH_OK) {

                    /* read succeeded */
                    largest->v.end = largest->v.pos + bytes;
                } else if (sret == SEARCH_FINISH) {
                    if (VEC_LEN(&largest->v) || largest->blocksize) {
                        /* didn't finish properly */
                        assert(!CRASH); ERROR("impact_ord_eval()");
                        source_delete(term, terms);
                        free(term);
                        return SEARCH_EINVAL;
                    }
                    /* otherwise it will be finished below */
                } else {
                    assert(!CRASH); ERROR("impact_ord_eval()");
                    source_delete(term, terms);
                    free(term);
                    return sret;
                }
            }

            if (!largest->blocksize) {
                /* need to read the start of the next block */
                unsigned long int tmp_bsize,
                                  tmp_impact;

                if (vec_vbyte_read(&largest->v, &tmp_bsize)
                  && (vec_vbyte_read(&largest->v, &tmp_impact) 
                    /* second read failed, rewind past first vbyte */
                    || ((largest->v.pos -= vec_vbyte_len(tmp_bsize)), 0))) {

                    blocks_read++;
                    if (blocks_read > terms) {
                        blockfine++;
                    }

                    largest->blocksize = tmp_bsize;
                    largest->impact = (tmp_impact + 1) * largest->w_qt;
                    largest->docno = -1;
                    heap_insert(term, &terms, sizeof(*term), term_data_cmp, 
                      largest);
                } else if (!VEC_LEN(&largest->v)) {
                    /* finished, don't put back on the heap */
                    dsrc = (void *) largest->src; bytes_read += dsrc->pos;
                    largest->src->delet(largest->src);
                    largest->src = NULL;
                } else if (largest->impact != INT_MAX) {
                    /* ensure that this vector is chosen next, as we need the
                     * next impact score */
                    largest->impact = INT_MAX;
                    assert(largest->blocksize == 0);
                    heap_insert(term, &terms, sizeof(*term), term_data_cmp, 
                      largest);
                } else {
                    /* huh? */
                    assert(!CRASH); ERROR("impact_ord_eval()");
                    source_delete(term, terms);
                    free(term);
                    return SEARCH_EINVAL;
                }
            } else {
                heap_insert(term, &terms, sizeof(*term), term_data_cmp, 
                  largest);
            }
        }
    } while (largest && (largest->impact > blockfine));

    for (i = 0; i < terms; i++) {
        dsrc = (void *) term[i].src; bytes_read += dsrc->pos;
    }

    if (largest) {
        largest->src->delet(largest->src);
        largest->src = NULL;
    }

    /* end of ranking */
    source_delete(term, terms);
    free(term);
    return SEARCH_OK;
}
Beispiel #18
0
void 
heap_changedhead (void *heap, int size, int num, heap_comp hc)
{
  heap_heapify (heap, size, num, 1, hc);
}