00001
00006
00007
00008
00009
00010
00011
00012
00013
00153 #include "host.h"
00154 #include <assert.h>
00155
00156 #ifndef VL_HEAP_prefix
00157 #error "VL_HEAP_prefix must be defined"
00158 #endif
00159
00160 #ifndef VL_HEAP_array
00161 #ifndef VL_HEAP_type
00162 #error "VL_HEAP_type must be defined if VL_HEAP_array is not"
00163 #endif
00164 #define VL_HEAP_array VL_HEAP_type*
00165 #define VL_HEAP_array_const VL_HEAP_type const*
00166 #endif
00167
00168 #ifndef VL_HEAP_array_const
00169 #define VL_HEAP_array_const VL_HEAP_array
00170 #endif
00171
00172 #ifdef __DOXYGEN__
00173 #define VL_HEAP_prefix HeapObject
00174 #define VL_HEAP_type HeapType
00175 #define VL_HEAP_array HeapType*
00176 #define VL_HEAP_array HeapType const*
00177 #endif
00178
00179
00180
00181 #ifndef VL_HEAP_DEF_H
00182 #define VL_HEAP_DEF_H
00183
00189 VL_INLINE vl_uindex
00190 vl_heap_parent (vl_uindex index)
00191 {
00192 if (index == 0) return 0 ;
00193 return (index - 1) / 2 ;
00194 }
00195
00201 VL_INLINE vl_uindex
00202 vl_heap_left_child (vl_uindex index)
00203 {
00204 return 2 * index + 1 ;
00205 }
00206
00212 VL_INLINE vl_uindex
00213 vl_heap_right_child (vl_uindex index)
00214 {
00215 return vl_heap_left_child (index) + 1 ;
00216 }
00217
00218
00219 #endif
00220
00221
00222
00223 #if ! defined(VL_HEAP_cmp) || defined(__DOXYGEN__)
00224 #define VL_HEAP_cmp VL_XCAT(VL_HEAP_prefix, _cmp)
00225
00234 VL_INLINE VL_HEAP_type
00235 VL_HEAP_cmp
00236 (VL_HEAP_array_const array,
00237 vl_uindex indexA,
00238 vl_uindex indexB)
00239 {
00240 return array[indexA] - array[indexB] ;
00241 }
00242
00243
00244 #endif
00245
00246
00247
00248 #if ! defined(VL_HEAP_swap) || defined(__DOXYGEN__)
00249 #define VL_HEAP_swap VL_XCAT(VL_HEAP_prefix, _swap)
00250
00262 VL_INLINE void
00263 VL_HEAP_swap
00264 (VL_HEAP_array array,
00265 vl_uindex indexA,
00266 vl_uindex indexB)
00267 {
00268 VL_HEAP_type t = array [indexA] ;
00269 array [indexA] = array [indexB] ;
00270 array [indexB] = t ;
00271 }
00272
00273
00274 #endif
00275
00276
00277
00278 #if ! defined(VL_HEAP_up) || defined(__DOXYGEN__)
00279 #define VL_HEAP_up VL_XCAT(VL_HEAP_prefix, _up)
00280
00287 VL_INLINE void
00288 VL_HEAP_up
00289 (VL_HEAP_array array, vl_size heapSize, vl_uindex index)
00290 {
00291 vl_uindex leftIndex = vl_heap_left_child (index) ;
00292 vl_uindex rightIndex = vl_heap_right_child (index) ;
00293
00294
00295 if (leftIndex >= heapSize) return ;
00296
00297
00298 if (rightIndex >= heapSize) {
00299 if (VL_HEAP_cmp (array, index, leftIndex) > 0) {
00300 VL_HEAP_swap (array, index, leftIndex) ;
00301 }
00302 return ;
00303 }
00304
00305
00306 {
00307 if (VL_HEAP_cmp (array, leftIndex, rightIndex) < 0) {
00308
00309 if (VL_HEAP_cmp (array, index, leftIndex) > 0) {
00310 VL_HEAP_swap (array, index, leftIndex) ;
00311 VL_HEAP_up (array, heapSize, leftIndex) ;
00312 }
00313 } else {
00314
00315 if (VL_HEAP_cmp (array, index, rightIndex) > 0) {
00316 VL_HEAP_swap (array, index, rightIndex) ;
00317 VL_HEAP_up (array, heapSize, rightIndex) ;
00318 }
00319 }
00320 }
00321 }
00322
00323
00324 #endif
00325
00326
00327
00328 #if ! defined(VL_HEAP_down) || defined(__DOXYGEN__)
00329 #define VL_HEAP_down VL_XCAT(VL_HEAP_prefix, _down)
00330
00336 VL_INLINE void
00337 VL_HEAP_down
00338 (VL_HEAP_array array, vl_uindex index)
00339 {
00340 vl_uindex parentIndex ;
00341
00342 if (index == 0) return ;
00343
00344 parentIndex = vl_heap_parent (index) ;
00345
00346 if (VL_HEAP_cmp (array, index, parentIndex) < 0) {
00347 VL_HEAP_swap (array, index, parentIndex) ;
00348 VL_HEAP_down (array, parentIndex) ;
00349 }
00350 }
00351
00352
00353 #endif
00354
00355
00356
00357 #if ! defined(VL_HEAP_push) || defined(__DOXYGEN__)
00358 #define VL_HEAP_push VL_XCAT(VL_HEAP_prefix, _push)
00359
00368 VL_INLINE void
00369 VL_HEAP_push
00370 (VL_HEAP_array array, vl_size *heapSize)
00371 {
00372 VL_HEAP_down (array, *heapSize) ;
00373 *heapSize += 1 ;
00374 }
00375
00376
00377 #endif
00378
00379
00380
00381 #if ! defined(VL_HEAP_pop) || defined(__DOXYGEN__)
00382 #define VL_HEAP_pop VL_XCAT(VL_HEAP_prefix, _pop)
00383
00399 VL_INLINE vl_uindex
00400 VL_HEAP_pop
00401 (VL_HEAP_array array, vl_size *heapSize)
00402 {
00403 assert (*heapSize) ;
00404
00405 *heapSize -= 1 ;
00406
00407 VL_HEAP_swap (array, 0, *heapSize) ;
00408
00409 if (*heapSize > 1) {
00410 VL_HEAP_up (array, *heapSize, 0) ;
00411 }
00412
00413 return *heapSize ;
00414 }
00415
00416
00417 #endif
00418
00419
00420
00421 #if ! defined(VL_HEAP_update) || defined(__DOXYGEN__)
00422 #define VL_HEAP_update VL_XCAT(VL_HEAP_prefix, _update)
00423
00439 VL_INLINE void
00440 VL_HEAP_update
00441 (VL_HEAP_array array,
00442 vl_size heapSize,
00443 vl_uindex index)
00444 {
00445 VL_HEAP_up (array, heapSize, index) ;
00446 VL_HEAP_down (array, index) ;
00447 }
00448
00449
00450 #endif
00451
00452
00453
00454 #undef VL_HEAP_cmp
00455 #undef VL_HEAP_swap
00456 #undef VL_HEAP_up
00457 #undef VL_HEAP_down
00458 #undef VL_HEAP_push
00459 #undef VL_HEAP_pop
00460 #undef VL_HEAP_update
00461 #undef VL_HEAP_prefix
00462 #undef VL_HEAP_type
00463 #undef VL_HEAP_array
00464 #undef VL_HEAP_array_const