Fix issue in update of priority in priority queue:

* Rename _update_further into _update.
* it now supports increase or decrease of priority.
* _update_further is deprecated (and was broken).
This commit is contained in:
Patrick Pelissier committed 2020-11-14 23:48:08 +01:00
1 parent bd89e162fc
commit c1f99359be
1 file changed
+21 -4
+21 -4
View File
@@ -385,10 +385,9 @@
} \ } \
\ \
static inline void \ static inline void \
M_C(name, _update_further)(prioqueue_t p, type xold, type xnew) \ M_C(name, _update)(prioqueue_t p, type const xold, type const xnew) \
{ \ { \
/* This update assumes that the new position is further in the heap */ \ /* NOTE: xold can be the same pointer than xnew */ \
M_ASSERT (M_CALL_CMP(oplist, xold, xnew) > 0); \
/* First pass: search for an item EQUAL to x */ \ /* First pass: search for an item EQUAL to x */ \
size_t size = M_C(name, _array_size)(p->array); \ size_t size = M_C(name, _array_size)(p->array); \
size_t i = 0; \ size_t i = 0; \
@@ -398,9 +397,12 @@
} \ } \
/* We shall have found the item */ \ /* We shall have found the item */ \
M_ASSERT (i < size); \ M_ASSERT (i < size); \
/* Test if the position of the old data is further or nearer than the new */ \
int cmp = M_CALL_CMP(oplist, *M_C(name, _array_cget)(p->array, i), xnew); \
/* Set the found item to the new element */ \ /* Set the found item to the new element */ \
M_C(name, _array_set_at) (p->array, i, xnew); \ M_C(name, _array_set_at) (p->array, i, xnew); \
/* Move back the updated element to its right position in the heap */ \ if (cmp < 0) { \
/* Move back the updated element to its new position, further in the heap */ \
while (true) { \ while (true) { \
size_t child = M_C(name, _i_lchild)(i); \ size_t child = M_C(name, _i_lchild)(i); \
if (child >= size) break; \ if (child >= size) break; \
@@ -413,8 +415,23 @@
M_C(name, _array_swap_at) (p->array, i, child); \ M_C(name, _array_swap_at) (p->array, i, child); \
i = child; \ i = child; \
} \ } \
} else { \
/* Move back the updated element to its new position, nearest in the heap */ \
while (i > 0) { \
size_t parent = M_C(name, _i_parent)(i); \
if (M_C(name, _i_cmp)(p, parent, i) <= 0) break; \
M_C(name, _array_swap_at) (p->array, i, parent); \
i = parent; \
} \
} \
} \ } \
\ \
/* Obsolete function (never documented) */ \
static inline void \
M_C(name, _update_further)(prioqueue_t p, type const xold, type const xnew) \
{ \
M_C(name, _update)(p, xold, xnew); \
} \
, /* No EQUAL */ ) \ , /* No EQUAL */ ) \