Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpriorityq-heap.c
Go to the documentation of this file.
00001 /* 00002 ** License Applicability. Except to the extent portions of this file are 00003 ** made subject to an alternative license as permitted in the SGI Free 00004 ** Software License B, Version 1.1 (the "License"), the contents of this 00005 ** file are subject only to the provisions of the License. You may not use 00006 ** this file except in compliance with the License. You may obtain a copy 00007 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 00008 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: 00009 ** 00010 ** http://oss.sgi.com/projects/FreeB 00011 ** 00012 ** Note that, as provided in the License, the Software is distributed on an 00013 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS 00014 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND 00015 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A 00016 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 00017 ** 00018 ** Original Code. The Original Code is: OpenGL Sample Implementation, 00019 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, 00020 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. 00021 ** Copyright in any portions created by third parties is as indicated 00022 ** elsewhere herein. All Rights Reserved. 00023 ** 00024 ** Additional Notice Provisions: The application programming interfaces 00025 ** established by SGI in conjunction with the Original Code are The 00026 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released 00027 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version 00028 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X 00029 ** Window System(R) (Version 1.3), released October 19, 1998. This software 00030 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation 00031 ** published by SGI, but has not been independently verified as being 00032 ** compliant with the OpenGL(R) version 1.2.1 Specification. 00033 ** 00034 */ 00035 /* 00036 ** Author: Eric Veach, July 1994. 00037 ** 00038 ** $Date: 2007-10-19 23:21:45 +0000 (Fri, 19 Oct 2007) $ $Revision: 1.1 $ 00039 ** $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/glu32/libtess/priorityq-heap.c,v 1.1 2004/02/02 16:39:15 navaraf Exp $ 00040 */ 00041 00042 #include <stddef.h> 00043 #include <assert.h> 00044 #include "priorityq-heap.h" 00045 #include "memalloc.h" 00046 00047 #define INIT_SIZE 32 00048 00049 #define TRUE 1 00050 #define FALSE 0 00051 00052 #ifdef FOR_TRITE_TEST_PROGRAM 00053 #define LEQ(x,y) (*pq->leq)(x,y) 00054 #else 00055 /* Violates modularity, but a little faster */ 00056 #include "geom.h" 00057 #define LEQ(x,y) VertLeq((GLUvertex *)x, (GLUvertex *)y) 00058 #endif 00059 00060 /* really __gl_pqHeapNewPriorityQ */ 00061 PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) ) 00062 { 00063 PriorityQ *pq = (PriorityQ *)memAlloc( sizeof( PriorityQ )); 00064 if (pq == NULL) return NULL; 00065 00066 pq->size = 0; 00067 pq->max = INIT_SIZE; 00068 pq->nodes = (PQnode *)memAlloc( (INIT_SIZE + 1) * sizeof(pq->nodes[0]) ); 00069 if (pq->nodes == NULL) { 00070 memFree(pq); 00071 return NULL; 00072 } 00073 00074 pq->handles = (PQhandleElem *)memAlloc( (INIT_SIZE + 1) * sizeof(pq->handles[0]) ); 00075 if (pq->handles == NULL) { 00076 memFree(pq->nodes); 00077 memFree(pq); 00078 return NULL; 00079 } 00080 00081 pq->initialized = FALSE; 00082 pq->freeList = 0; 00083 pq->leq = leq; 00084 00085 pq->nodes[1].handle = 1; /* so that Minimum() returns NULL */ 00086 pq->handles[1].key = NULL; 00087 return pq; 00088 } 00089 00090 /* really __gl_pqHeapDeletePriorityQ */ 00091 void pqDeletePriorityQ( PriorityQ *pq ) 00092 { 00093 memFree( pq->handles ); 00094 memFree( pq->nodes ); 00095 memFree( pq ); 00096 } 00097 00098 00099 static void FloatDown( PriorityQ *pq, long curr ) 00100 { 00101 PQnode *n = pq->nodes; 00102 PQhandleElem *h = pq->handles; 00103 PQhandle hCurr, hChild; 00104 long child; 00105 00106 hCurr = n[curr].handle; 00107 for( ;; ) { 00108 child = curr << 1; 00109 if( child < pq->size && LEQ( h[n[child+1].handle].key, 00110 h[n[child].handle].key )) { 00111 ++child; 00112 } 00113 00114 assert(child <= pq->max); 00115 00116 hChild = n[child].handle; 00117 if( child > pq->size || LEQ( h[hCurr].key, h[hChild].key )) { 00118 n[curr].handle = hCurr; 00119 h[hCurr].node = curr; 00120 break; 00121 } 00122 n[curr].handle = hChild; 00123 h[hChild].node = curr; 00124 curr = child; 00125 } 00126 } 00127 00128 00129 static void FloatUp( PriorityQ *pq, long curr ) 00130 { 00131 PQnode *n = pq->nodes; 00132 PQhandleElem *h = pq->handles; 00133 PQhandle hCurr, hParent; 00134 long parent; 00135 00136 hCurr = n[curr].handle; 00137 for( ;; ) { 00138 parent = curr >> 1; 00139 hParent = n[parent].handle; 00140 if( parent == 0 || LEQ( h[hParent].key, h[hCurr].key )) { 00141 n[curr].handle = hCurr; 00142 h[hCurr].node = curr; 00143 break; 00144 } 00145 n[curr].handle = hParent; 00146 h[hParent].node = curr; 00147 curr = parent; 00148 } 00149 } 00150 00151 /* really __gl_pqHeapInit */ 00152 void pqInit( PriorityQ *pq ) 00153 { 00154 long i; 00155 00156 /* This method of building a heap is O(n), rather than O(n lg n). */ 00157 00158 for( i = pq->size; i >= 1; --i ) { 00159 FloatDown( pq, i ); 00160 } 00161 pq->initialized = TRUE; 00162 } 00163 00164 /* really __gl_pqHeapInsert */ 00165 /* returns LONG_MAX iff out of memory */ 00166 PQhandle pqInsert( PriorityQ *pq, PQkey keyNew ) 00167 { 00168 long curr; 00169 PQhandle free; 00170 00171 curr = ++ pq->size; 00172 if( (curr*2) > pq->max ) { 00173 PQnode *saveNodes= pq->nodes; 00174 PQhandleElem *saveHandles= pq->handles; 00175 00176 /* If the heap overflows, double its size. */ 00177 pq->max <<= 1; 00178 pq->nodes = (PQnode *)memRealloc( pq->nodes, 00179 (size_t) 00180 ((pq->max + 1) * sizeof( pq->nodes[0] ))); 00181 if (pq->nodes == NULL) { 00182 pq->nodes = saveNodes; /* restore ptr to free upon return */ 00183 return LONG_MAX; 00184 } 00185 pq->handles = (PQhandleElem *)memRealloc( pq->handles, 00186 (size_t) 00187 ((pq->max + 1) * 00188 sizeof( pq->handles[0] ))); 00189 if (pq->handles == NULL) { 00190 pq->handles = saveHandles; /* restore ptr to free upon return */ 00191 return LONG_MAX; 00192 } 00193 } 00194 00195 if( pq->freeList == 0 ) { 00196 free = curr; 00197 } else { 00198 free = pq->freeList; 00199 pq->freeList = pq->handles[free].node; 00200 } 00201 00202 pq->nodes[curr].handle = free; 00203 pq->handles[free].node = curr; 00204 pq->handles[free].key = keyNew; 00205 00206 if( pq->initialized ) { 00207 FloatUp( pq, curr ); 00208 } 00209 assert(free != LONG_MAX); 00210 return free; 00211 } 00212 00213 /* really __gl_pqHeapExtractMin */ 00214 PQkey pqExtractMin( PriorityQ *pq ) 00215 { 00216 PQnode *n = pq->nodes; 00217 PQhandleElem *h = pq->handles; 00218 PQhandle hMin = n[1].handle; 00219 PQkey min = h[hMin].key; 00220 00221 if( pq->size > 0 ) { 00222 n[1].handle = n[pq->size].handle; 00223 h[n[1].handle].node = 1; 00224 00225 h[hMin].key = NULL; 00226 h[hMin].node = pq->freeList; 00227 pq->freeList = hMin; 00228 00229 if( -- pq->size > 0 ) { 00230 FloatDown( pq, 1 ); 00231 } 00232 } 00233 return min; 00234 } 00235 00236 /* really __gl_pqHeapDelete */ 00237 void pqDelete( PriorityQ *pq, PQhandle hCurr ) 00238 { 00239 PQnode *n = pq->nodes; 00240 PQhandleElem *h = pq->handles; 00241 long curr; 00242 00243 assert( hCurr >= 1 && hCurr <= pq->max && h[hCurr].key != NULL ); 00244 00245 curr = h[hCurr].node; 00246 n[curr].handle = n[pq->size].handle; 00247 h[n[curr].handle].node = curr; 00248 00249 if( curr <= -- pq->size ) { 00250 if( curr <= 1 || LEQ( h[n[curr>>1].handle].key, h[n[curr].handle].key )) { 00251 FloatDown( pq, curr ); 00252 } else { 00253 FloatUp( pq, curr ); 00254 } 00255 } 00256 h[hCurr].key = NULL; 00257 h[hCurr].node = pq->freeList; 00258 pq->freeList = hCurr; 00259 } Generated on Sat May 26 2012 04:22:20 for ReactOS by
1.7.6.1
|