.
This commit is contained in:
4
Makefile
4
Makefile
@@ -30,7 +30,7 @@ endif
|
|||||||
|
|
||||||
# debug and release flags
|
# debug and release flags
|
||||||
|
|
||||||
DEBUG_CFLAGS=-O0 -Og -ggdb3 ${WARNINGS} -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined \
|
DEBUG_CFLAGS=-Og -ggdb3 ${WARNINGS} -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined \
|
||||||
-fno-sanitize-recover=all -fstack-protector-strong -fstack-clash-protection -fno-common ${ADD_DBG_FLAGS} \
|
-fno-sanitize-recover=all -fstack-protector-strong -fstack-clash-protection -fno-common ${ADD_DBG_FLAGS} \
|
||||||
-DCHECK_TYCHE_BUGS=1
|
-DCHECK_TYCHE_BUGS=1
|
||||||
DEBUG_LDFLAGS=-fsanitize=address -fsanitize=undefined
|
DEBUG_LDFLAGS=-fsanitize=address -fsanitize=undefined
|
||||||
@@ -45,7 +45,7 @@ endif
|
|||||||
RELEASE_CFLAGS=-O3 -flto=auto -march=native -mtune=native -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -fstack-protector-strong
|
RELEASE_CFLAGS=-O3 -flto=auto -march=native -mtune=native -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -fstack-protector-strong
|
||||||
RELEASE_LDFLAGS=-flto=auto
|
RELEASE_LDFLAGS=-flto=auto
|
||||||
|
|
||||||
CFLAGS+=-std=c99 -fPIC -fvisibility=hidden
|
CFLAGS+=-std=c99 -D_GNU_SOURCE -fPIC -fvisibility=hidden
|
||||||
LDFLAGS+=
|
LDFLAGS+=
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
74
lib/heap.c
74
lib/heap.c
@@ -1,23 +1,85 @@
|
|||||||
#include "stack.c"
|
#include "stack.c"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "khash.h"
|
#include "khash.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef int HEAP_KEY;
|
||||||
} HeapValue;
|
|
||||||
KHASH_MAP_INIT_INT(heap, HeapValue)
|
typedef enum {
|
||||||
|
TH_STRING, TH_ARRAY, TH_TABLE,
|
||||||
|
} TYC_HEAP_TYPE;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
khash_t(heap) *items;
|
TYC_HEAP_TYPE type;
|
||||||
|
union {
|
||||||
|
char* str;
|
||||||
|
// TODO - array and table
|
||||||
|
} value;
|
||||||
|
} HeapValue;
|
||||||
|
KHASH_MAP_INIT_INT(HEAP, HeapValue)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
khash_t(HEAP) *items;
|
||||||
} Heap;
|
} Heap;
|
||||||
|
|
||||||
static void heap_init(Heap* h)
|
static void heap_init(Heap* h)
|
||||||
{
|
{
|
||||||
h->items = kh_init(heap);
|
h->items = kh_init(HEAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void heap_finalize(Heap* h)
|
static void heap_finalize(Heap* h)
|
||||||
{
|
{
|
||||||
kh_destroy(heap, h->items);
|
for (khiter_t k = kh_begin(h->items); k != kh_end(h->items); ++k) {
|
||||||
|
HeapValue value = kh_value(h->items, k);
|
||||||
|
switch (value.type) {
|
||||||
|
case TH_STRING:
|
||||||
|
free(value.value.str);
|
||||||
|
break;
|
||||||
|
case TH_ARRAY:
|
||||||
|
abort(); // not implemented yet
|
||||||
|
break;
|
||||||
|
case TH_TABLE:
|
||||||
|
abort(); // not implemented yet
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kh_destroy(HEAP, h->items);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HEAP_KEY heap_add_string(Heap* h, const char* value)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
khiter_t k;
|
||||||
|
HEAP_KEY key;
|
||||||
|
|
||||||
|
do {
|
||||||
|
key = rand();
|
||||||
|
k = kh_get(HEAP, h->items, key);
|
||||||
|
} while (k != kh_end(h->items));
|
||||||
|
|
||||||
|
k = kh_put(HEAP, h->items, key, &ret);
|
||||||
|
kh_value(h->items, k) = (HeapValue) {
|
||||||
|
.type = TH_STRING,
|
||||||
|
.value = { .str = strdup(value) }
|
||||||
|
};
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
static TYC_RESULT heap_get_string(Heap* h, HEAP_KEY key, const char** value)
|
||||||
|
{
|
||||||
|
khiter_t k = kh_get(HEAP, h->items, key);
|
||||||
|
bool is_missing = (k == kh_end(h->items));
|
||||||
|
if (is_missing)
|
||||||
|
return T_ERR_HEAP_KEY_NOT_FOUND;
|
||||||
|
*value = kh_value(h->items, k).value.str;
|
||||||
|
return T_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t heap_size(Heap* h)
|
||||||
|
{
|
||||||
|
return kh_size(h->items);
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@ typedef enum {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
T_OK = 0,
|
T_OK = 0,
|
||||||
T_ERR_STACK_UNDERFLOW = -1, T_ERR_STACK_FP_UNDERFLOW = -2, T_ERR_STACK_ACCESS_OUT_OF_RANGE = -3,
|
T_ERR_STACK_UNDERFLOW = -1, T_ERR_STACK_FP_UNDERFLOW = -2, T_ERR_STACK_ACCESS_OUT_OF_RANGE = -3,
|
||||||
|
T_ERR_HEAP_KEY_NOT_FOUND = -10,
|
||||||
} TYC_RESULT;
|
} TYC_RESULT;
|
||||||
|
|
||||||
#endif //TYCHE_TYCHE_H
|
#endif //TYCHE_TYCHE_H
|
||||||
|
|||||||
17
test/tests.c
17
test/tests.c
@@ -92,5 +92,20 @@ int main()
|
|||||||
stack_finalize(&s);
|
stack_finalize(&s);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - stack set
|
{
|
||||||
|
printf("### Heap\n");
|
||||||
|
|
||||||
|
Heap h;
|
||||||
|
heap_init(&h);
|
||||||
|
|
||||||
|
HEAP_KEY key1 = heap_add_string(&h, "hello");
|
||||||
|
HEAP_KEY key2 = heap_add_string(&h, "world");
|
||||||
|
|
||||||
|
const char* value;
|
||||||
|
assert(heap_get_string(&h, key1, &value) == T_OK); assert(strcmp(value, "hello") == 0);
|
||||||
|
assert(heap_get_string(&h, key2, &value) == T_OK); assert(strcmp(value, "world") == 0);
|
||||||
|
assert(heap_get_string(&h, 1000, &value) == T_ERR_HEAP_KEY_NOT_FOUND);
|
||||||
|
|
||||||
|
heap_finalize(&h);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user