/* * change object position and update references * XXX this one is never used! */ static void heap_move(struct dn_heap *h, uint64_t new_key, void *object) { int temp, i, max = h->elements-1; struct dn_heap_entry *p, buf; if (h->ofs <= 0) panic("cannot move items on this heap"); p = h->p; /* shortcut */ i = *((int *)((char *)object + h->ofs)); if (DN_KEY_LT(new_key, p[i].key) ) { /* must move up */ p[i].key = new_key; for (; i>0 && DN_KEY_LT(new_key, p[(temp = HEAP_FATHER(i))].key); i = temp ) { /* bubble up */ HEAP_SWAP(p[i], p[temp], buf); SET_OFFSET(h, i); } } else { /* must move down */ p[i].key = new_key; while ( (temp = HEAP_LEFT(i)) <= max ) { /* found left child */ if (temp != max && DN_KEY_LT(p[temp+1].key, p[temp].key)) temp++; /* select child with min key */ if (DN_KEY_LT(>p[temp].key, new_key)) { /* go down */ HEAP_SWAP(p[i], p[temp], buf); SET_OFFSET(h, i); } else break; i = temp; } }
int heap_insert(struct dn_heap *h, uint64_t key1, void *p) { int son = h->elements; //log("%s key %llu p %p\n", __FUNCTION__, key1, p); if (p == NULL) { /* data already there, set starting point */ son = key1; } else { /* insert new element at the end, possibly resize */ son = h->elements; if (son == h->size) /* need resize... */ // XXX expand by 16 or so if (heap_resize(h, h->elements+16) ) return 1; /* failure... */ h->p[son].object = p; h->p[son].key = key1; h->elements++; } /* make sure that son >= father along the path */ while (son > 0) { int father = HEAP_FATHER(son); struct dn_heap_entry tmp; if (DN_KEY_LT( h->p[father].key, h->p[son].key ) ) break; /* found right position */ /* son smaller than father, swap and repeat */ HEAP_SWAP(h->p[son], h->p[father], tmp); SET_OFFSET(h, son); son = father; } SET_OFFSET(h, son); return 0; }
static void BLI_heap_up(Heap *heap, int i) { while (i > 0) { int p = HEAP_PARENT(i); if (HEAP_COMPARE(heap->tree[p], heap->tree[i])) break; HEAP_SWAP(heap, p, i); i = p; } }
static void heapify(plane_t *h, uint32 index, uint32 size) { uint32 c; plane_t tmp; for (c = HEAP_LEFT(index); c < (size-1); index = c, c = HEAP_LEFT(index)) { if (h[c].plane.score > h[c+1].plane.score) c++; if (h[index].plane.score > h[c].plane.score) { HEAP_SWAP(h[index], h[c]); } else { return; } } if (c == (size-1) && h[index].plane.score > h[c].plane.score) { HEAP_SWAP(h[index], h[c]); } }
void BLI_heap_remove(Heap *heap, HeapNode *node) { int i = node->index; while (i > 0) { int p = HEAP_PARENT(i); HEAP_SWAP(heap, p, i); i = p; } BLI_heap_popmin(heap); }
void *BLI_heap_popmin(Heap *heap) { void *ptr = heap->tree[0]->ptr; heap->tree[0]->ptr = heap->freenodes; heap->freenodes = heap->tree[0]; if (heap->size == 1) heap->size--; else { HEAP_SWAP(heap, 0, heap->size-1); heap->size--; BLI_heap_down(heap, 0); } return ptr; }
static void BLI_heap_down(Heap *heap, int i) { while (1) { int size = heap->size, smallest; int l = HEAP_LEFT(i); int r = HEAP_RIGHT(i); smallest = ((l < size) && HEAP_COMPARE(heap->tree[l], heap->tree[i]))? l: i; if ((r < size) && HEAP_COMPARE(heap->tree[r], heap->tree[smallest])) smallest = r; if (smallest == i) break; HEAP_SWAP(heap, i, smallest); i = smallest; } }
static int fr_heap_bubble(fr_heap_t *hp, int child) { /* * Bubble up the element. */ while (child > 0) { int parent = HEAP_PARENT(child); /* * Parent is smaller than the child. We're done. */ if (hp->cmp(hp->p[parent], hp->p[child]) < 0) break; /* * Child is smaller than the parent, repeat. */ HEAP_SWAP(hp->p[child], hp->p[parent]); SET_OFFSET(hp, child); child = parent; } SET_OFFSET(hp, child); return 1; }