#ifndef VIETER_HEAP
#define VIETER_HEAP

#include <stdint.h>

typedef struct vieter_heap vieter_heap;

typedef enum vieter_heap_error {
  vieter_heap_ok = 0,
  vieter_heap_empty = 1
} vieter_heap_error;

/*
 * Allocate and initialize an empty heap.
 */
vieter_heap *vieter_heap_init();

/*
 * Deallocate a heap.
 */
void vieter_heap_free(vieter_heap *heap);

/*
 * Return how many elements are currently in the heap.
 */
uint64_t vieter_heap_size(vieter_heap *heap);

/*
 * Insert a new value into the heap.
 */
vieter_heap_error vieter_heap_insert(vieter_heap *heap, uint64_t key,
                                     void *data);

/*
 * Remove the smallest element from the heap.
 */
vieter_heap_error vieter_heap_pop(void **out, vieter_heap *heap);

/*
 * Get the smallest element in the heap without removing it.
 */
vieter_heap_error vieter_heap_peek(void **out, vieter_heap *heap);

/*
 * Acquire a read lock on the heap. Return value is the result of
 * pthread_rwlock_rdlock.
 */
int vieter_heap_rlock(vieter_heap *heap);

/*
 * Acquire a write lock on the heap. Return value is the result of
 * pthread_rwlock_wrlock.
 */
int vieter_heap_wlock(vieter_heap *heap);

/*
 * Unlock the lock after having acquired it. Return value is the result of
 * pthread_rwlock_unlock.
 */
int vieter_heap_unlock(vieter_heap *heap);

#endif