From 9db8b33c61d99934c2533d33566a026e5bc53586 Mon Sep 17 00:00:00 2001 From: Yuichi Nishiwaki Date: Thu, 25 Jun 2015 07:58:58 +0900 Subject: [PATCH] abandon xhash --- extlib/benz/include/picrin.h | 1 - extlib/benz/include/picrin/xhash.h | 416 ----------------------------- extlib/benz/write.c | 75 +++--- 3 files changed, 38 insertions(+), 454 deletions(-) delete mode 100644 extlib/benz/include/picrin/xhash.h diff --git a/extlib/benz/include/picrin.h b/extlib/benz/include/picrin.h index feac5362..e19ced8b 100644 --- a/extlib/benz/include/picrin.h +++ b/extlib/benz/include/picrin.h @@ -37,7 +37,6 @@ extern "C" { #include "picrin/compat.h" #include "picrin/kvec.h" #include "picrin/khash.h" -#include "picrin/xhash.h" #include "picrin/value.h" diff --git a/extlib/benz/include/picrin/xhash.h b/extlib/benz/include/picrin/xhash.h deleted file mode 100644 index 253c25f2..00000000 --- a/extlib/benz/include/picrin/xhash.h +++ /dev/null @@ -1,416 +0,0 @@ -#ifndef XHASH_H -#define XHASH_H - -/* - * Copyright (c) 2013-2014 by Yuichi Nishiwaki - */ - -#if defined(__cplusplus) -extern "C" { -#endif - -#define XHASH_ALLOCATOR pic->allocf - -/* simple object to object hash table */ - -#define XHASH_INIT_SIZE 11 -#define XHASH_RESIZE_RATIO(x) ((x) * 3 / 4) - -#define XHASH_ALIGNMENT 3 /* quad word alignment */ -#define XHASH_MASK (~(size_t)((1 << XHASH_ALIGNMENT) - 1)) -#define XHASH_ALIGN(i) ((((i) - 1) & XHASH_MASK) + (1 << XHASH_ALIGNMENT)) - -typedef struct xh_entry { - struct xh_entry *next; - int hash; - struct xh_entry *fw, *bw; - const void *key; - void *val; -} xh_entry; - -#define xh_key(e,type) (*(type *)((e)->key)) -#define xh_val(e,type) (*(type *)((e)->val)) - -typedef int (*xh_hashf)(const void *, void *); -typedef int (*xh_equalf)(const void *, const void *, void *); -typedef void *(*xh_allocf)(void *, size_t); - -typedef struct xhash { - xh_allocf allocf; - xh_entry **buckets; - size_t size, count, kwidth, vwidth; - size_t koffset, voffset; - xh_hashf hashf; - xh_equalf equalf; - xh_entry *head, *tail; - void *data; -} xhash; - -/** Protected Methods: - * static inline void xh_init_(xhash *x, size_t, size_t, xh_hashf, xh_equalf, void *); - * static inline xh_entry *xh_get_(xhash *x, const void *key); - * static inline xh_entry *xh_put_(xhash *x, const void *key, void *val); - * static inline void xh_del_(xhash *x, const void *key); - */ - -/* string map */ -PIC_INLINE xh_entry *xh_get_str(xhash *x, const char *key); -PIC_INLINE xh_entry *xh_put_str(xhash *x, const char *key, void *); -PIC_INLINE void xh_del_str(xhash *x, const char *key); - -/* object map */ -PIC_INLINE xh_entry *xh_get_ptr(xhash *x, const void *key); -PIC_INLINE xh_entry *xh_put_ptr(xhash *x, const void *key, void *); -PIC_INLINE void xh_del_ptr(xhash *x, const void *key); - -/* int map */ -PIC_INLINE xh_entry *xh_get_int(xhash *x, int key); -PIC_INLINE xh_entry *xh_put_int(xhash *x, int key, void *); -PIC_INLINE void xh_del_int(xhash *x, int key); - -PIC_INLINE size_t xh_size(xhash *x); -PIC_INLINE void xh_clear(xhash *x); -PIC_INLINE void xh_destroy(xhash *x); - -PIC_INLINE xh_entry *xh_begin(xhash *x); -PIC_INLINE xh_entry *xh_next(xh_entry *e); - - -PIC_INLINE void -xh_bucket_alloc(xhash *x, size_t newsize) -{ - x->size = newsize; - x->buckets = x->allocf(NULL, (x->size + 1) * sizeof(xh_entry *)); - memset(x->buckets, 0, (x->size + 1) * sizeof(xh_entry *)); -} - -PIC_INLINE void -xh_init_(xhash *x, xh_allocf allocf, size_t kwidth, size_t vwidth, xh_hashf hashf, xh_equalf equalf, void *data) -{ - x->allocf = allocf; - x->size = 0; - x->buckets = NULL; - x->count = 0; - x->kwidth = kwidth; - x->vwidth = vwidth; - x->koffset = XHASH_ALIGN(sizeof(xh_entry)); - x->voffset = XHASH_ALIGN(sizeof(xh_entry)) + XHASH_ALIGN(kwidth); - x->hashf = hashf; - x->equalf = equalf; - x->head = NULL; - x->tail = NULL; - x->data = data; - - xh_bucket_alloc(x, XHASH_INIT_SIZE); -} - -PIC_INLINE xh_entry * -xh_get_(xhash *x, const void *key) -{ - int hash; - size_t idx; - xh_entry *e; - - hash = x->hashf(key, x->data); - idx = ((unsigned)hash) % x->size; - for (e = x->buckets[idx]; e; e = e->next) { - if (e->hash == hash && x->equalf(key, e->key, x->data)) - break; - } - return e; -} - -PIC_INLINE void -xh_resize_(xhash *x, size_t newsize) -{ - xhash y; - xh_entry *it; - size_t idx; - - xh_init_(&y, x->allocf, x->kwidth, x->vwidth, x->hashf, x->equalf, x->data); - xh_bucket_alloc(&y, newsize); - - for (it = xh_begin(x); it != NULL; it = xh_next(it)) { - idx = ((unsigned)it->hash) % y.size; - /* reuse entry object */ - it->next = y.buckets[idx]; - y.buckets[idx] = it; - y.count++; - } - - y.head = x->head; - y.tail = x->tail; - - x->allocf(x->buckets, 0); - - /* copy all members from y to x */ - memcpy(x, &y, sizeof(xhash)); -} - -PIC_INLINE xh_entry * -xh_put_(xhash *x, const void *key, void *val) -{ - int hash; - size_t idx; - xh_entry *e; - - if ((e = xh_get_(x, key))) { - memcpy(e->val, val, x->vwidth); - return e; - } - - if (x->count + 1 > XHASH_RESIZE_RATIO(x->size)) { - xh_resize_(x, x->size * 2 + 1); - } - - hash = x->hashf(key, x->data); - idx = ((unsigned)hash) % x->size; - e = x->allocf(NULL, x->voffset + x->vwidth); - e->next = x->buckets[idx]; - e->hash = hash; - e->key = ((char *)e) + x->koffset; - e->val = ((char *)e) + x->voffset; - memcpy((void *)e->key, key, x->kwidth); - memcpy(e->val, val, x->vwidth); - - if (x->head == NULL) { - x->head = x->tail = e; - e->fw = e->bw = NULL; - } else { - x->tail->bw = e; - e->fw = x->tail; - e->bw = NULL; - x->tail = e; - } - - x->count++; - - return x->buckets[idx] = e; -} - -PIC_INLINE void -xh_del_(xhash *x, const void *key) -{ - int hash; - size_t idx; - xh_entry *p, *q, *r; - - hash = x->hashf(key, x->data); - idx = ((unsigned)hash) % x->size; - if (x->buckets[idx]->hash == hash && x->equalf(key, x->buckets[idx]->key, x->data)) { - q = x->buckets[idx]; - if (q->fw == NULL) { - x->head = q->bw; - } else { - q->fw->bw = q->bw; - } - if (q->bw == NULL) { - x->tail = q->fw; - } else { - q->bw->fw = q->fw; - } - r = q->next; - x->allocf(q, 0); - x->buckets[idx] = r; - } - else { - for (p = x->buckets[idx]; ; p = p->next) { - if (p->next->hash == hash && x->equalf(key, p->next->key, x->data)) - break; - } - q = p->next; - if (q->fw == NULL) { - x->head = q->bw; - } else { - q->fw->bw = q->bw; - } - if (q->bw == NULL) { - x->tail = q->fw; - } else { - q->bw->fw = q->fw; - } - r = q->next; - x->allocf(q, 0); - p->next = r; - } - - x->count--; -} - -PIC_INLINE size_t -xh_size(xhash *x) -{ - return x->count; -} - -PIC_INLINE void -xh_clear(xhash *x) -{ - size_t i; - xh_entry *e, *d; - - for (i = 0; i < x->size; ++i) { - e = x->buckets[i]; - while (e) { - d = e->next; - x->allocf(e, 0); - e = d; - } - x->buckets[i] = NULL; - } - - x->head = x->tail = NULL; - x->count = 0; -} - -PIC_INLINE void -xh_destroy(xhash *x) -{ - xh_clear(x); - x->allocf(x->buckets, 0); -} - -/* string map */ - -PIC_INLINE int -xh_str_hash(const void *key, void *data) -{ - const char *str = *(const char **)key; - int hash = 0; - - (void)data; - - while (*str) { - hash = hash * 31 + *str++; - } - return hash; -} - -PIC_INLINE int -xh_str_equal(const void *key1, const void *key2, void *data) -{ - const char *s1 = *(const char **)key1, *s2 = *(const char **)key2; - - (void)data; - - return strcmp(s1, s2) == 0; -} - -#define xh_init_str(x, width) \ - xh_init_(x, XHASH_ALLOCATOR, sizeof(const char *), width, xh_str_hash, xh_str_equal, NULL); - -PIC_INLINE xh_entry * -xh_get_str(xhash *x, const char *key) -{ - return xh_get_(x, &key); -} - -PIC_INLINE xh_entry * -xh_put_str(xhash *x, const char *key, void *val) -{ - return xh_put_(x, &key, val); -} - -PIC_INLINE void -xh_del_str(xhash *x, const char *key) -{ - xh_del_(x, &key); -} - -/* object map */ - -PIC_INLINE int -xh_ptr_hash(const void *key, void *data) -{ - (void)data; - - return (int)(size_t)*(const void **)key; -} - -PIC_INLINE int -xh_ptr_equal(const void *key1, const void *key2, void *data) -{ - (void) data; - - return *(const void **)key1 == *(const void **)key2; -} - -#define xh_init_ptr(x, width) \ - xh_init_(x, XHASH_ALLOCATOR, sizeof(const void *), width, xh_ptr_hash, xh_ptr_equal, NULL); - -PIC_INLINE xh_entry * -xh_get_ptr(xhash *x, const void *key) -{ - return xh_get_(x, &key); -} - -PIC_INLINE xh_entry * -xh_put_ptr(xhash *x, const void *key, void *val) -{ - return xh_put_(x, &key, val); -} - -PIC_INLINE void -xh_del_ptr(xhash *x, const void *key) -{ - xh_del_(x, &key); -} - -/* int map */ - -PIC_INLINE int -xh_int_hash(const void *key, void *data) -{ - (void)data; - - return *(int *)key; -} - -PIC_INLINE int -xh_int_equal(const void *key1, const void *key2, void *data) -{ - (void)data; - - return *(int *)key1 == *(int *)key2; -} - -#define xh_init_int(x, width) \ - xh_init_(x, XHASH_ALLOCATOR, sizeof(int), width, xh_int_hash, xh_int_equal, NULL); - -PIC_INLINE xh_entry * -xh_get_int(xhash *x, int key) -{ - return xh_get_(x, &key); -} - -PIC_INLINE xh_entry * -xh_put_int(xhash *x, int key, void *val) -{ - return xh_put_(x, &key, val); -} - -PIC_INLINE void -xh_del_int(xhash *x, int key) -{ - xh_del_(x, &key); -} - -/** iteration */ - -PIC_INLINE xh_entry * -xh_begin(xhash *x) -{ - return x->head; -} - -PIC_INLINE xh_entry * -xh_next(xh_entry *e) -{ - return e->bw; -} - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/extlib/benz/write.c b/extlib/benz/write.c index 39bc4058..8eb08fd8 100644 --- a/extlib/benz/write.c +++ b/extlib/benz/write.c @@ -36,12 +36,17 @@ is_quasiquote(pic_state *pic, pic_value pair) return is_tagged(pic, pic->sQUASIQUOTE, pair); } +KHASH_DECLARE(l, void *, int) +KHASH_DECLARE(v, void *, int) +KHASH_DEFINE2(l, void *, int, 1, kh_ptr_hash_func, kh_ptr_hash_equal) +KHASH_DEFINE2(v, void *, int, 0, kh_ptr_hash_func, kh_ptr_hash_equal) + struct writer_control { pic_state *pic; xFILE *file; int mode; - xhash labels; /* object -> int */ - xhash visited; /* object -> int */ + khash_t(l) labels; /* object -> int */ + khash_t(v) visited; /* object -> int */ int cnt; }; @@ -55,35 +60,36 @@ writer_control_init(struct writer_control *p, pic_state *pic, xFILE *file, int m p->file = file; p->mode = mode; p->cnt = 0; - xh_init_ptr(&p->labels, sizeof(int)); - xh_init_ptr(&p->visited, sizeof(int)); + kh_init(l, &p->labels); + kh_init(v, &p->visited); } static void writer_control_destroy(struct writer_control *p) { - xh_destroy(&p->labels); - xh_destroy(&p->visited); + pic_state *pic = p->pic; + kh_destroy(l, &p->labels); + kh_destroy(v, &p->visited); } static void traverse_shared(struct writer_control *p, pic_value obj) { - xh_entry *e; + pic_state *pic = p->pic; + khash_t(l) *h = &p->labels; + khiter_t it; size_t i; - int c; + int ret; switch (pic_type(obj)) { case PIC_TT_PAIR: case PIC_TT_VECTOR: - e = xh_get_ptr(&p->labels, pic_obj_ptr(obj)); - if (e == NULL) { - c = -1; - xh_put_ptr(&p->labels, pic_obj_ptr(obj), &c); + it = kh_put(l, h, pic_obj_ptr(obj), &ret); + if (ret != 0) { + kh_val(h, it) = -1; } - else if (xh_val(e, int) == -1) { - c = p->cnt++; - xh_put_ptr(&p->labels, pic_obj_ptr(obj), &c); + else if (kh_val(h, it) == -1) { + kh_val(h, it) = p->cnt++; break; } else { @@ -112,8 +118,10 @@ static void write_pair(struct writer_control *p, struct pic_pair *pair) { pic_state *pic = p->pic; - xh_entry *e; - int c; + khash_t(l) *lh = &p->labels; + khash_t(v) *vh = &p->visited; + khiter_t it; + int ret; write_core(p, pair->car); @@ -123,18 +131,15 @@ write_pair(struct writer_control *p, struct pic_pair *pair) else if (pic_pair_p(pair->cdr)) { /* shared objects */ - if ((e = xh_get_ptr(&p->labels, pic_obj_ptr(pair->cdr))) && xh_val(e, int) != -1) { + if ((it = kh_get(l, lh, pic_ptr(pair->cdr))) != kh_end(lh) && kh_val(lh, it) != -1) { xfprintf(pic, p->file, " . "); - if ((xh_get_ptr(&p->visited, pic_obj_ptr(pair->cdr)))) { - xfprintf(pic, p->file, "#%d#", xh_val(e, int)); + kh_put(v, vh, pic_ptr(pair->cdr), &ret); + if (ret == 0) { /* if exists */ + xfprintf(pic, p->file, "#%d#", kh_val(lh, it)); return; } - else { - xfprintf(pic, p->file, "#%d=", xh_val(e, int)); - c = 1; - xh_put_ptr(&p->visited, pic_obj_ptr(pair->cdr), &c); - } + xfprintf(pic, p->file, "#%d=", kh_val(lh, it)); } else { xfprintf(pic, p->file, " "); @@ -167,29 +172,25 @@ static void write_core(struct writer_control *p, pic_value obj) { pic_state *pic = p->pic; + khash_t(l) *lh = &p->labels; + khash_t(v) *vh = &p->visited; xFILE *file = p->file; size_t i; pic_sym *sym; - xh_entry *e; khiter_t it; - int c; + int ret; #if PIC_ENABLE_FLOAT double f; #endif /* shared objects */ - if (pic_vtype(obj) == PIC_VTYPE_HEAP - && (e = xh_get_ptr(&p->labels, pic_obj_ptr(obj))) - && xh_val(e, int) != -1) { - if ((xh_get_ptr(&p->visited, pic_obj_ptr(obj)))) { - xfprintf(pic, file, "#%d#", xh_val(e, int)); + if (pic_vtype(obj) == PIC_VTYPE_HEAP && ((it = kh_get(l, lh, pic_ptr(obj))) != kh_end(lh)) && kh_val(lh, it) != -1) { + kh_put(v, vh, pic_ptr(obj), &ret); + if (ret == 0) { /* if exists */ + xfprintf(pic, file, "#%d#", kh_val(lh, it)); return; } - else { - xfprintf(pic, file, "#%d=", xh_val(e, int)); - c = 1; - xh_put_ptr(&p->visited, pic_obj_ptr(obj), &c); - } + xfprintf(pic, file, "#%d=", kh_val(lh, it)); } switch (pic_type(obj)) {