forked from vieter-v/libvieter
108 lines
2.6 KiB
C
108 lines
2.6 KiB
C
|
#include "vieter_cat_heap_internal.h"
|
||
|
|
||
|
vieter_cat_heap *vieter_cat_heap_init() {
|
||
|
return calloc(1, sizeof(vieter_cat_heap));
|
||
|
}
|
||
|
|
||
|
void vieter_cat_heap_free(vieter_cat_heap **ptp) {
|
||
|
vieter_cat_heap *cheap = *ptp;
|
||
|
|
||
|
if (cheap->cat_count > 0) {
|
||
|
for (uint64_t i = 0; i < cheap->cat_count; i++) {
|
||
|
free(cheap->categories[i]);
|
||
|
vieter_heap_free(cheap->heaps[i]);
|
||
|
}
|
||
|
|
||
|
free(cheap->categories);
|
||
|
free(cheap->heaps);
|
||
|
}
|
||
|
|
||
|
free(cheap);
|
||
|
*ptp = NULL;
|
||
|
}
|
||
|
|
||
|
uint64_t vieter_cat_heap_size(vieter_cat_heap *cheap) {
|
||
|
uint64_t total = 0;
|
||
|
|
||
|
for (uint64_t i = 0; i < cheap->cat_count; i++) {
|
||
|
total += vieter_heap_size(cheap->heaps[i]);
|
||
|
}
|
||
|
|
||
|
return total;
|
||
|
}
|
||
|
|
||
|
vieter_cat_heap_error vieter_cat_heap_insert(vieter_cat_heap *cheap,
|
||
|
char *category, uint64_t key,
|
||
|
void *data) {
|
||
|
uint64_t i = 0;
|
||
|
|
||
|
// For now, we do a linear search through all categories. This is more than
|
||
|
// fast enough for most usecases.
|
||
|
while (i < cheap->cat_count && strcmp(category, cheap->categories[i]) != 0) {
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
if (i == cheap->cat_count) {
|
||
|
if (cheap->cat_count == 0) {
|
||
|
cheap->categories = malloc(sizeof(char *));
|
||
|
cheap->heaps = malloc(sizeof(vieter_heap *));
|
||
|
} else {
|
||
|
cheap->categories =
|
||
|
realloc(cheap->categories, sizeof(char *) * (cheap->cat_count + 1));
|
||
|
cheap->heaps =
|
||
|
realloc(cheap->heaps, sizeof(vieter_heap *) * (cheap->cat_count + 1));
|
||
|
}
|
||
|
|
||
|
cheap->cat_count++;
|
||
|
|
||
|
cheap->categories[i] = strdup(category);
|
||
|
cheap->heaps[i] = vieter_heap_init();
|
||
|
}
|
||
|
|
||
|
vieter_heap_insert(cheap->heaps[i], key, data);
|
||
|
|
||
|
return vieter_cat_heap_ok;
|
||
|
}
|
||
|
|
||
|
vieter_cat_heap_error vieter_cat_heap_pop(void **out, vieter_cat_heap *cheap,
|
||
|
char *category) {
|
||
|
uint64_t i = 0;
|
||
|
|
||
|
while (i < cheap->cat_count && strcmp(category, cheap->categories[i]) != 0) {
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
if (i == cheap->cat_count) {
|
||
|
return vieter_cat_heap_arch_not_found;
|
||
|
}
|
||
|
|
||
|
vieter_heap_error res = vieter_heap_pop(out, cheap->heaps[i]);
|
||
|
|
||
|
if (res != vieter_heap_ok) {
|
||
|
return vieter_cat_heap_arch_empty;
|
||
|
}
|
||
|
|
||
|
return vieter_cat_heap_ok;
|
||
|
}
|
||
|
|
||
|
vieter_cat_heap_error vieter_cat_heap_peek(void **out, vieter_cat_heap *cheap,
|
||
|
char *category) {
|
||
|
uint64_t i = 0;
|
||
|
|
||
|
while (i < cheap->cat_count && strcmp(category, cheap->categories[i]) != 0) {
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
if (i == cheap->cat_count) {
|
||
|
return vieter_cat_heap_arch_not_found;
|
||
|
}
|
||
|
|
||
|
vieter_heap_error res = vieter_heap_peek(out, cheap->heaps[i]);
|
||
|
|
||
|
if (res != vieter_heap_ok) {
|
||
|
return vieter_cat_heap_arch_empty;
|
||
|
}
|
||
|
|
||
|
return vieter_cat_heap_ok;
|
||
|
}
|