parent
440e4499c7
commit
6503897ece
@ -1,17 +1,16 @@ |
||||
CC = gcc
|
||||
LDFLAGS = -lm -lgrapheme -lSDL2 -lGLEW -lGL
|
||||
CFLAGS = -g -Wall -Wextra -pedantic -fno-omit-frame-pointer
|
||||
CFLAGS = -ggdb3 -Wall -Wextra -pedantic -fno-omit-frame-pointer
|
||||
|
||||
.PHONY: clean all |
||||
all: test |
||||
|
||||
font.o: font.c font.h stb_truetype.h stb_image_write.h util.h \
|
||||
generic_cache.h hash.h
|
||||
hash.o: hash.c hash.h util.h |
||||
generic_cache.h generic_hash.h
|
||||
main.o: main.c ren.h util.h |
||||
ren.o: ren.c util.h font.h ren.h generic_stack.h |
||||
util.o: util.c util.h |
||||
test: font.o hash.o main.o ren.o util.o |
||||
${CC} ${LDFLAGS} -o test font.o hash.o main.o ren.o util.o
|
||||
test: font.o main.o ren.o util.o |
||||
${CC} ${LDFLAGS} -o test font.o main.o ren.o util.o
|
||||
clean: |
||||
rm -f test font.o hash.o main.o ren.o util.o
|
||||
rm -f test font.o main.o ren.o util.o
|
||||
|
@ -1,77 +0,0 @@ |
||||
#define _POSIX_C_SOURCE 200809l |
||||
#define _DEFAULT_SOURCE |
||||
|
||||
#include <stdlib.h> |
||||
#include <stdint.h> |
||||
#include <string.h> |
||||
|
||||
#include "hash.h" |
||||
#include "util.h" |
||||
|
||||
#define MAXSIZE 4096 |
||||
|
||||
|
||||
static unsigned int hash(unsigned int code) |
||||
{ |
||||
// identity map the ascii range
|
||||
if (code < 128) return code; |
||||
return (uint32_t)((uint64_t)(code*2654435761)>>32); |
||||
} |
||||
|
||||
|
||||
struct hm_ref * hm_create(unsigned int size) |
||||
{ |
||||
if (!size || size > MAXSIZE) |
||||
return NULL; |
||||
|
||||
// round to the greater power of two
|
||||
size = 1<<__builtin_clz(size); |
||||
|
||||
// FIXME: check for intger overflow here
|
||||
struct hm_ref *h = emalloc(sizeof(struct hm_ref)+sizeof(struct hm_entry)*size); |
||||
if (h) { |
||||
h->items = 0; |
||||
h->size = size; |
||||
memset(h->bucket, 0, sizeof(struct hm_ref)*size); |
||||
} |
||||
return h; |
||||
} |
||||
|
||||
|
||||
void hm_destroy(struct hm_ref *hm) |
||||
{ |
||||
efree(hm); |
||||
} |
||||
|
||||
|
||||
static struct hm_entry * lookup(struct hm_ref *hm, unsigned int code) |
||||
{ |
||||
// fast modulo operation for power-of-2 size
|
||||
unsigned int mask = hm->size - 1; |
||||
unsigned int i = hash(code); |
||||
for (unsigned int j = 1; ; i += j++) { |
||||
if (!hm->bucket[i&mask].code || hm->bucket[i].code == code) |
||||
return &(hm->bucket[i&mask]); |
||||
} |
||||
return NULL; |
||||
} |
||||
|
||||
|
||||
struct hm_entry * hm_search(struct hm_ref *hm, unsigned int code) |
||||
{ |
||||
struct hm_entry *r = lookup(hm, code); |
||||
if (r) { |
||||
if (r->code == code) |
||||
return r; |
||||
return NULL; |
||||
} |
||||
return r; |
||||
} |
||||
|
||||
|
||||
struct hm_entry * hm_insert(struct hm_ref *hm, struct hm_entry *entry) |
||||
{ |
||||
struct hm_entry *r = lookup(hm, entry->code); |
||||
if (r) *r = *entry; |
||||
return r; |
||||
} |
@ -1,21 +0,0 @@ |
||||
#ifndef _HASH_H |
||||
#define _HASH_H |
||||
|
||||
struct hm_entry { |
||||
unsigned long code; |
||||
void *data; |
||||
}; |
||||
|
||||
|
||||
struct hm_ref { |
||||
unsigned int items, size; |
||||
struct hm_entry bucket[]; |
||||
}; |
||||
|
||||
|
||||
struct hm_ref * hm_create(unsigned int size); |
||||
void hm_destroy(struct hm_ref *hm); |
||||
struct hm_entry * hm_search(struct hm_ref *hm, unsigned int code); |
||||
struct hm_entry * hm_insert(struct hm_ref *hm, struct hm_entry *entry); |
||||
|
||||
#endif |
Loading…
Reference in new issue