stclib / STC

A modern, user friendly, generic, type-safe and fast C99 container library: String, Vector, Sorted and Unordered Map and Set, Deque, Forward List, Smart Pointers, Bitset and Random numbers.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Priorityqueue is buggy

matthieugras opened this issue · comments

My use case is that I use the pq as a reorder buffer for a fixed number of elements.
Each element in the pq has a timestamp (uint64) and some data.
New elements are pushed to the pq, if the pq has a certain size the top element is popped.
I also supplied a function to free the associated data.

while (!cpque_pq_val_empty(ctx->buf) &&
            cpque_pq_val_size(ctx->buf) > env.rob_size) {
  pq_val *curr = cpque_pq_val_top(&ctx->buf);
  consume_single_elem(ctx, curr->event_data);
  cpque_pq_val_pop(&ctx->buf);
}

This code seems to cause a problem. The order of the curr elements seems to be fine (smallest items first). But the order in which elements are freed by the pop call is inverted with respect to the priority (oldest elements are freed first).

Thanks for reporting. Priority queue has been the least tested, and this was a silly bug that I think I have introduced a while back. Fixed in last commit.

#include <stdio.h>

#define i_val int64_t
#define i_tag i
#define i_cmp -c_default_compare  // min-heap (increasing values)
#define i_del(x) printf("del %d\n", *(x))
#define i_from(x) (x)             // required because i_del is defined
#include <stc/cpque.h>

int main() {
    c_auto (cpque_i, heap)
    {
        c_apply(cpque_i, push, &heap, {231, 32, 873, 4, 343});

        puts("Extract the elements.");
        c_forrange (cpque_i_size(heap)) {
            printf("%zd ", *cpque_i_top(&heap));
            cpque_i_pop(&heap);
        }
    }
}

Gives correct output:

4 del 4
32 del 32
231 del 231
343 del 343
873 del 873