00001 
00011 #ifndef _GK_MKPQUEUE_H
00012 #define _GK_MKPQUEUE_H
00013 
00014 
00015 #define GK_MKPQUEUE(FPRFX, PQT, KVT, KT, VT, KVMALLOC, KMAX, KEY_LT)\
00016 \
00017 \
00018 \
00019 PQT *FPRFX ## Create(size_t maxnodes)\
00020 {\
00021   PQT *queue; \
00022 \
00023   queue = (PQT *)gk_malloc(sizeof(PQT), "gk_pqCreate: queue");\
00024   FPRFX ## Init(queue, maxnodes);\
00025 \
00026   return queue;\
00027 }\
00028 \
00029 \
00030 \
00031 \
00032 \
00033 void FPRFX ## Init(PQT *queue, size_t maxnodes)\
00034 {\
00035   queue->nnodes = 0;\
00036   queue->maxnodes = maxnodes;\
00037 \
00038   queue->heap    = KVMALLOC(maxnodes, "gk_PQInit: heap");\
00039   queue->locator = gk_idxsmalloc(maxnodes, -1, "gk_PQInit: locator");\
00040 }\
00041 \
00042 \
00043 \
00044 \
00045 \
00046 void FPRFX ## Reset(PQT *queue)\
00047 {\
00048   gk_idx_t i;\
00049   gk_idx_t *locator=queue->locator;\
00050   KVT *heap=queue->heap;\
00051 \
00052   for (i=queue->nnodes-1; i>=0; i--)\
00053     locator[heap[i].val] = -1;\
00054   queue->nnodes = 0;\
00055 }\
00056 \
00057 \
00058 \
00059 \
00060 \
00061 void FPRFX ## Free(PQT *queue)\
00062 {\
00063   if (queue == NULL) return;\
00064   gk_free((void **)&queue->heap, &queue->locator, LTERM);\
00065   queue->maxnodes = 0;\
00066 }\
00067 \
00068 \
00069 \
00070 \
00072 \
00073 void FPRFX ## Destroy(PQT *queue)\
00074 {\
00075   if (queue == NULL) return;\
00076   FPRFX ## Free(queue);\
00077   gk_free((void **)&queue, LTERM);\
00078 }\
00079 \
00080 \
00081 \
00082 \
00083 \
00084 size_t FPRFX ## Length(PQT *queue)\
00085 {\
00086   return queue->nnodes;\
00087 }\
00088 \
00089 \
00090 \
00091 \
00092 \
00093 int FPRFX ## Insert(PQT *queue, VT node, KT key)\
00094 {\
00095   gk_idx_t i, j;\
00096   gk_idx_t *locator=queue->locator;\
00097   KVT *heap=queue->heap;\
00098 \
00099   ASSERT2(FPRFX ## CheckHeap(queue));\
00100 \
00101   ASSERT(locator[node] == -1);\
00102 \
00103   i = queue->nnodes++;\
00104   while (i > 0) {\
00105     j = (i-1)>>1;\
00106     if (KEY_LT(key, heap[j].key)) {\
00107       heap[i] = heap[j];\
00108       locator[heap[i].val] = i;\
00109       i = j;\
00110     }\
00111     else\
00112       break;\
00113   }\
00114   ASSERT(i >= 0);\
00115   heap[i].key   = key;\
00116   heap[i].val   = node;\
00117   locator[node] = i;\
00118 \
00119   ASSERT2(FPRFX ## CheckHeap(queue));\
00120 \
00121   return 0;\
00122 }\
00123 \
00124 \
00125 \
00126 \
00127 \
00128 int FPRFX ## Delete(PQT *queue, VT node)\
00129 {\
00130   gk_idx_t i, j, nnodes;\
00131   KT newkey, oldkey;\
00132   gk_idx_t *locator=queue->locator;\
00133   KVT *heap=queue->heap;\
00134 \
00135   ASSERT(locator[node] != -1);\
00136   ASSERT(heap[locator[node]].val == node);\
00137 \
00138   ASSERT2(FPRFX ## CheckHeap(queue));\
00139 \
00140   i = locator[node];\
00141   locator[node] = -1;\
00142 \
00143   if (--queue->nnodes > 0 && heap[queue->nnodes].val != node) {\
00144     node   = heap[queue->nnodes].val;\
00145     newkey = heap[queue->nnodes].key;\
00146     oldkey = heap[i].key;\
00147 \
00148     if (KEY_LT(newkey, oldkey)) { \
00149       while (i > 0) {\
00150         j = (i-1)>>1;\
00151         if (KEY_LT(newkey, heap[j].key)) {\
00152           heap[i] = heap[j];\
00153           locator[heap[i].val] = i;\
00154           i = j;\
00155         }\
00156         else\
00157           break;\
00158       }\
00159     }\
00160     else { \
00161       nnodes = queue->nnodes;\
00162       while ((j=(i<<1)+1) < nnodes) {\
00163         if (KEY_LT(heap[j].key, newkey)) {\
00164           if (j+1 < nnodes && KEY_LT(heap[j+1].key, heap[j].key))\
00165             j++;\
00166           heap[i] = heap[j];\
00167           locator[heap[i].val] = i;\
00168           i = j;\
00169         }\
00170         else if (j+1 < nnodes && KEY_LT(heap[j+1].key, newkey)) {\
00171           j++;\
00172           heap[i] = heap[j];\
00173           locator[heap[i].val] = i;\
00174           i = j;\
00175         }\
00176         else\
00177           break;\
00178       }\
00179     }\
00180 \
00181     heap[i].key   = newkey;\
00182     heap[i].val   = node;\
00183     locator[node] = i;\
00184   }\
00185 \
00186   ASSERT2(FPRFX ## CheckHeap(queue));\
00187 \
00188   return 0;\
00189 }\
00190 \
00191 \
00192 \
00193  \
00194 \
00195 void FPRFX ## Update(PQT *queue, VT node, KT newkey)\
00196 {\
00197   gk_idx_t i, j, nnodes;\
00198   KT oldkey;\
00199   gk_idx_t *locator=queue->locator;\
00200   KVT *heap=queue->heap;\
00201 \
00202   oldkey = heap[locator[node]].key;\
00203 \
00204   ASSERT(locator[node] != -1);\
00205   ASSERT(heap[locator[node]].val == node);\
00206   ASSERT2(FPRFX ## CheckHeap(queue));\
00207 \
00208   i = locator[node];\
00209 \
00210   if (KEY_LT(newkey, oldkey)) { \
00211     while (i > 0) {\
00212       j = (i-1)>>1;\
00213       if (KEY_LT(newkey, heap[j].key)) {\
00214         heap[i] = heap[j];\
00215         locator[heap[i].val] = i;\
00216         i = j;\
00217       }\
00218       else\
00219         break;\
00220     }\
00221   }\
00222   else { \
00223     nnodes = queue->nnodes;\
00224     while ((j=(i<<1)+1) < nnodes) {\
00225       if (KEY_LT(heap[j].key, newkey)) {\
00226         if (j+1 < nnodes && KEY_LT(heap[j+1].key, heap[j].key))\
00227           j++;\
00228         heap[i] = heap[j];\
00229         locator[heap[i].val] = i;\
00230         i = j;\
00231       }\
00232       else if (j+1 < nnodes && KEY_LT(heap[j+1].key, newkey)) {\
00233         j++;\
00234         heap[i] = heap[j];\
00235         locator[heap[i].val] = i;\
00236         i = j;\
00237       }\
00238       else\
00239         break;\
00240     }\
00241   }\
00242 \
00243   heap[i].key   = newkey;\
00244   heap[i].val   = node;\
00245   locator[node] = i;\
00246 \
00247   ASSERT2(FPRFX ## CheckHeap(queue));\
00248 \
00249   return;\
00250 }\
00251 \
00252 \
00253 \
00254 \
00256 \
00257 VT FPRFX ## GetTop(PQT *queue)\
00258 {\
00259   gk_idx_t i, j;\
00260   gk_idx_t *locator;\
00261   KVT *heap;\
00262   VT vtx, node;\
00263   KT key;\
00264 \
00265   ASSERT2(FPRFX ## CheckHeap(queue));\
00266 \
00267   if (queue->nnodes == 0)\
00268     return -1;\
00269 \
00270   queue->nnodes--;\
00271 \
00272   heap    = queue->heap;\
00273   locator = queue->locator;\
00274 \
00275   vtx = heap[0].val;\
00276   locator[vtx] = -1;\
00277 \
00278   if ((i = queue->nnodes) > 0) {\
00279     key  = heap[i].key;\
00280     node = heap[i].val;\
00281     i = 0;\
00282     while ((j=2*i+1) < queue->nnodes) {\
00283       if (KEY_LT(heap[j].key, key)) {\
00284         if (j+1 < queue->nnodes && KEY_LT(heap[j+1].key, heap[j].key))\
00285           j = j+1;\
00286         heap[i] = heap[j];\
00287         locator[heap[i].val] = i;\
00288         i = j;\
00289       }\
00290       else if (j+1 < queue->nnodes && KEY_LT(heap[j+1].key, key)) {\
00291         j = j+1;\
00292         heap[i] = heap[j];\
00293         locator[heap[i].val] = i;\
00294         i = j;\
00295       }\
00296       else\
00297         break;\
00298     }\
00299 \
00300     heap[i].key   = key;\
00301     heap[i].val   = node;\
00302     locator[node] = i;\
00303   }\
00304 \
00305   ASSERT2(FPRFX ## CheckHeap(queue));\
00306   return vtx;\
00307 }\
00308 \
00309 \
00310 \
00311 \
00313 \
00314 VT FPRFX ## SeeTopVal(PQT *queue)\
00315 {\
00316   return (queue->nnodes == 0 ? -1 : queue->heap[0].val);\
00317 }\
00318 \
00319 \
00320 \
00321 \
00323 \
00324 KT FPRFX ## SeeTopKey(PQT *queue)\
00325 {\
00326   return (queue->nnodes == 0 ? KMAX : queue->heap[0].key);\
00327 }\
00328 \
00329 \
00330 \
00331 \
00332 \
00333 KT FPRFX ## SeeKey(PQT *queue, VT node)\
00334 {\
00335   gk_idx_t *locator;\
00336   KVT *heap;\
00337 \
00338   heap    = queue->heap;\
00339   locator = queue->locator;\
00340 \
00341   return heap[locator[node]].key;\
00342 }\
00343 \
00344 \
00345 \
00346 \
00349 \
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 \
00376 \
00377 \
00378 \
00379 \
00380 \
00381 int FPRFX ## CheckHeap(PQT *queue)\
00382 {\
00383   gk_idx_t i, j;\
00384   size_t nnodes;\
00385   gk_idx_t *locator;\
00386   KVT *heap;\
00387 \
00388   heap    = queue->heap;\
00389   locator = queue->locator;\
00390   nnodes  = queue->nnodes;\
00391 \
00392   if (nnodes == 0)\
00393     return 1;\
00394 \
00395   ASSERT(locator[heap[0].val] == 0);\
00396   for (i=1; i<nnodes; i++) {\
00397     ASSERT(locator[heap[i].val] == i);\
00398     ASSERT(!KEY_LT(heap[i].key, heap[(i-1)/2].key));\
00399   }\
00400   for (i=1; i<nnodes; i++)\
00401     ASSERT(!KEY_LT(heap[i].key, heap[0].key));\
00402 \
00403   for (j=i=0; i<queue->maxnodes; i++) {\
00404     if (locator[i] != -1)\
00405       j++;\
00406   }\
00407   ASSERTP(j == nnodes, ("%jd %jd\n", (intmax_t)j, (intmax_t)nnodes));\
00408 \
00409   return 1;\
00410 }\
00411 
00412 
00413 #define GK_MKPQUEUE_PROTO(FPRFX, PQT, KT, VT)\
00414   PQT *  FPRFX ## Create(size_t maxnodes);\
00415   void   FPRFX ## Init(PQT *queue, size_t maxnodes);\
00416   void   FPRFX ## Reset(PQT *queue);\
00417   void   FPRFX ## Free(PQT *queue);\
00418   void   FPRFX ## Destroy(PQT *queue);\
00419   size_t FPRFX ## Length(PQT *queue);\
00420   int    FPRFX ## Insert(PQT *queue, VT node, KT key);\
00421   int    FPRFX ## Delete(PQT *queue, VT node);\
00422   void   FPRFX ## Update(PQT *queue, VT node, KT newkey);\
00423   VT     FPRFX ## GetTop(PQT *queue);\
00424   VT     FPRFX ## SeeTopVal(PQT *queue);\
00425   KT     FPRFX ## SeeTopKey(PQT *queue);\
00426   KT     FPRFX ## SeeKey(PQT *queue, VT node);\
00427   VT     FPRFX ## SeeConstraintTop(PQT *queue, KT maxwgt, KT *wgts);\
00428   int    FPRFX ## CheckHeap(PQT *queue);\
00429 
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 #endif