2
* $Id: BLI_heap.c,v 1.1 2006/02/08 18:06:35 blendix Exp $
4
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version. The Blender
10
* Foundation also sells licenses for use in proprietary software under
11
* the Blender License. See http://www.blender.org/BL/ for information
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software Foundation,
21
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24
* All rights reserved.
26
* The Original Code is: none of this file.
28
* Contributor(s): Brecht Van Lommel
30
* ***** END GPL/BL DUAL LICENSE BLOCK *****
31
* A heap / priority queue ADT.
37
#include "MEM_guardedalloc.h"
38
#include "BLI_memarena.h"
58
#define SWAP(type, a, b) \
59
{ type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; }
60
#define HEAP_PARENT(i) ((i-1)>>1)
61
#define HEAP_LEFT(i) ((i<<1)+1)
62
#define HEAP_RIGHT(i) ((i<<1)+2)
63
#define HEAP_COMPARE(a, b) (a->value < b->value)
64
#define HEAP_EQUALS(a, b) (a->value == b->value)
65
#define HEAP_SWAP(heap, i, j) \
66
{ SWAP(int, heap->tree[i]->index, heap->tree[j]->index); \
67
SWAP(HeapNode*, heap->tree[i], heap->tree[j]); }
73
Heap *heap = (Heap*)MEM_callocN(sizeof(Heap), "BLIHeap");
75
heap->tree = (HeapNode**)MEM_mallocN(sizeof(HeapNode*), "BLIHeapTree");
76
heap->arena = BLI_memarena_new(1<<16);
81
void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp)
86
for (i = 0; i < heap->size; i++)
87
ptrfreefp(heap->tree[i]->ptr);
89
MEM_freeN(heap->tree);
90
BLI_memarena_free(heap->arena);
94
static void BLI_heap_down(Heap *heap, int i)
97
int size = heap->size, smallest;
99
int r = HEAP_RIGHT(i);
101
smallest = ((l < size) && HEAP_COMPARE(heap->tree[l], heap->tree[i]))? l: i;
103
if ((r < size) && HEAP_COMPARE(heap->tree[r], heap->tree[smallest]))
109
HEAP_SWAP(heap, i, smallest);
114
static void BLI_heap_up(Heap *heap, int i)
117
int p = HEAP_PARENT(i);
119
if (HEAP_COMPARE(heap->tree[p], heap->tree[i]))
122
HEAP_SWAP(heap, p, i);
127
HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr)
131
if ((heap->size + 1) > heap->bufsize) {
132
int newsize = heap->bufsize*2;
135
newtree = (HeapNode**)MEM_mallocN(newsize*sizeof(*newtree), "BLIHeapTree");
136
memcpy(newtree, heap->tree, sizeof(HeapNode*)*heap->size);
137
MEM_freeN(heap->tree);
139
heap->tree = newtree;
140
heap->bufsize = newsize;
143
if (heap->freenodes) {
144
node = heap->freenodes;
145
heap->freenodes = (HeapNode*)(((HeapNode*)heap->freenodes)->ptr);
148
node = (HeapNode*)BLI_memarena_alloc(heap->arena, sizeof *node);
152
node->index = heap->size;
154
heap->tree[node->index] = node;
158
BLI_heap_up(heap, heap->size-1);
163
int BLI_heap_empty(Heap *heap)
165
return (heap->size == 0);
168
int BLI_heap_size(Heap *heap)
173
HeapNode *BLI_heap_top(Heap *heap)
175
return heap->tree[0];
178
void *BLI_heap_popmin(Heap *heap)
180
void *ptr = heap->tree[0]->ptr;
182
heap->tree[0]->ptr = heap->freenodes;
183
heap->freenodes = heap->tree[0];
188
HEAP_SWAP(heap, 0, heap->size-1);
191
BLI_heap_down(heap, 0);
197
void BLI_heap_remove(Heap *heap, HeapNode *node)
202
int p = HEAP_PARENT(i);
204
HEAP_SWAP(heap, p, i);
208
BLI_heap_popmin(heap);
211
float BLI_heap_node_value(HeapNode *node)
216
void *BLI_heap_node_ptr(HeapNode *node)