dict

Dictionary for sd_t's
git clone git://www.tkruger.se/dict.git
Log | Files | Refs | README

commit b5311852537e210aa4da7463f8d5dd972d4952b6
Author: olikru <olikru@tkruger.se>
Date:   Mon,  8 Jan 2024 15:25:08 +0100

initial

Diffstat:
AMakefile | 43+++++++++++++++++++++++++++++++++++++++++++
AREADME | 4++++
ATODO | 2++
Adict.c | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adict.h | 33+++++++++++++++++++++++++++++++++
Atest_dict.c | 8++++++++
6 files changed, 172 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -0,0 +1,43 @@ +.SUFFIXES: .c .o .so +CC=clang +CFLAGS+=-std=c99 -pedantic -Wall -Werror -Wstrict-prototypes +CFLAGS+=-Wmissing-prototypes -Wmissing-declarations -Wshadow +CFLAGS+=-Wpointer-arith -Wcast-qual -Wsign-compare +CFLAGS+=-O2 -g +CFLAGS+=-fstack-protector-all -Wtype-limits -fno-common +CFLAGS+=-fno-builtin +CFLAGS+=-I/usr/local/include + +CFLAGS+=-I$(HOME)/.local/include +LFLAGS+=-L$(HOME)/.local/lib -lstack_sd -lsd + +INSTALL_PATH=$(HOME)/.local +BUILD=build + +TEST_SOURCE=test_dict.c +HEADER=dict.h +OBJS=dict.o +SHARED=dict.so +LIBSHARED=libdict.so + +all: build $(OBJS) $(SHARED) test + +.c.o: + $(CC) $(CFLAGS) -c $< -o $(BUILD)/$@ + +.o.so: + $(CC) -shared -fPIC $(BUILD)/$< -o $(BUILD)/$@ $(LFLAGS) + +test: $(TEST_SOURCE) + $(CC) $(CFLAGS) -o $(BUILD)/test $(TEST_SOURCE) $(BUILD)/$(OBJS) $(LFLAGS) + +build: + mkdir -p $(BUILD) + +install: + cp $(BUILD)/$(SHARED) $(INSTALL_PATH)/lib/$(LIBSHARED) + chmod 644 $(INSTALL_PATH)/lib/$(LIBSHARED) + cp $(HEADER) $(INSTALL_PATH)/include/ + +clean: + rm -rf $(BUILD) diff --git a/README b/README @@ -0,0 +1,4 @@ +dict +==== + +Small dictionary type for sd_t's. diff --git a/TODO b/TODO @@ -0,0 +1,2 @@ +* Implement unit tests +* Documentation diff --git a/dict.c b/dict.c @@ -0,0 +1,82 @@ +#include "dict.h" + +static inline void stack_ptr_init_size(stack_ptr *d, const size_t alloc) { + d->nmemb = 0; + d->alloc = alloc; + + d->data = calloc(d->alloc, sizeof(*(d->data))); +} + +static inline void stack_ptr_clear(stack_ptr *d) { + d->nmemb = 0; + free(d->data); + d->data = NULL; +} + +static inline void stack_ptr_push(stack_ptr *d, void *x) { + if (d->alloc <= d->nmemb) { + d->alloc <<= 1; + d->data = realloc(d->data, d->alloc * sizeof(*(d->data))); + } + + d->data[d->nmemb] = x; + d->nmemb++; +} + +void dict_init_size(dict_t *d, const size_t alloc) { + d->nalloc = alloc; + d->nelts = 0; + d->keys = calloc(d->nalloc, sizeof(*d->keys)); + d->values = calloc(d->nalloc, sizeof(*d->values)); + + size_t i; + for (i = 0; i < d->nalloc; i++) { + stack_sd_init_size(&d->keys[i], DICT_DEFAULT_STACK_SIZE); + stack_ptr_init_size(&d->values[i], DICT_DEFAULT_STACK_SIZE); + } +} + +void dict_init(dict_t *d) { dict_init_size(d, DICT_DEFAULT_SIZE); } + +void dict_clear(dict_t *d) { + size_t i; + for (i = 0; i < d->nalloc; i++) { + stack_sd_clear(&d->keys[i]); + stack_ptr_clear(&d->values[i]); + } + + d->nalloc = 0; + d->nelts = 0; + free(d->keys); + free(d->values); + d->keys = NULL; + d->values = NULL; +} + +void *dict_lookup(dict_t *d, sd_t k) { + uint64_t h = sd_hash(&k); + size_t i = h % d->nalloc; + int stack_idx = stack_sd_lookup(&d->keys[i], k); + + if (stack_idx == STACK_SD_LOOKUP_NOT_FOUND) { + return NULL; + } + + return (d->values[i]).data[stack_idx]; +} + +#include <stdio.h> + +void dict_insert(dict_t *d, sd_t k, void *value) { + uint64_t h = sd_hash(&k); + size_t i = h % d->nalloc; + int stack_idx = stack_sd_lookup(&d->keys[i], k); + + if (stack_idx == STACK_SD_LOOKUP_NOT_FOUND) { + stack_sd_push(&(d->keys[i]), k); + stack_ptr_push(&(d->values[i]), value); + d->nelts++; + } else { + (d->values[i]).data[stack_idx] = value; + } +} diff --git a/dict.h b/dict.h @@ -0,0 +1,33 @@ +#ifndef DICT_H +#define DICT_H + +#include "stack_sd.h" + +#define DICT_DEFAULT_SIZE 255 +#define DICT_DEFAULT_STACK_SIZE 2 +#define STACK_PTR_EMPTY_POP (NULL) +#define DICT_LOOKUP_NOT_FOUND (STACK_SD_LOOKUP_NOT_FOUND) // == -1 + +typedef struct { + size_t nmemb; + size_t alloc; + + void **data; +} stack_ptr; + +typedef struct { + size_t nelts; + size_t nalloc; + + stack_sd_t *keys; + stack_ptr *values; +} dict_t; + +void dict_init_size(dict_t *d, const size_t alloc); +void dict_init(dict_t *d); +void dict_clear(dict_t *d); +void *dict_lookup(dict_t *d, sd_t k); +void dict_insert(dict_t *t, sd_t k, void *v); +void print_dict(dict_t *d); + +#endif diff --git a/test_dict.c b/test_dict.c @@ -0,0 +1,8 @@ +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include "fheap.h" + +int main() { + printf("test unimplemented\n"); +}