ref: 10e157391eb2e75c3d38620529b356b302c4a2e5
parent: 4f2262847fa6940fcfded7c36e6ed3a6772ec872
author: Ori Bernstein <[email protected]>
date: Tue Jan 3 14:06:55 EST 2012
Add hash table impl
--- a/parse/Makefile
+++ b/parse/Makefile
@@ -1,7 +1,8 @@
BIN=pt
-OBJ=dump.o \
- ds.o \
+OBJ=bitset.o \
+ dump.o \
gram.o \
+ htab.o \
infer.o \
main.o \
names.o \
--- /dev/null
+++ b/parse/bitset.c
@@ -1,0 +1,115 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
+#include "parse.h"
+
+#define Uintbits (CHAR_BIT*sizeof(int))
+
+static void eqsz(Bitset *a, Bitset *b)
+{
+ int sz;
+
+ if (a->nchunks > b->nchunks)
+ sz = a->nchunks;
+ else
+ sz = b->nchunks;
+ a->chunks = zrealloc(a->chunks, a->nchunks*sizeof(uint), sz*sizeof(uint));
+ a->nchunks = sz;
+ b->chunks = zrealloc(b->chunks, a->nchunks*sizeof(uint), sz*sizeof(uint));
+ b->nchunks = sz;
+}
+
+Bitset *mkbs()
+{
+ Bitset *bs;
+
+ bs = xalloc(sizeof(Bitset));
+ bs->nchunks = 1;
+ bs->chunks = zalloc(1*sizeof(uint));
+ return bs;
+}
+
+Bitset *dupbs(Bitset *a)
+{
+ Bitset *bs;
+
+ bs = xalloc(sizeof(Bitset));
+ bs->nchunks = a->nchunks;
+ bs->chunks = xalloc(a->nchunks*sizeof(uint));
+ memcpy(bs->chunks, a->chunks, a->nchunks*sizeof(uint));
+ return bs;
+}
+
+int bscount(Bitset *bs)
+{
+ int i, j, n;
+
+ n = 0;
+ for (i = 0; i < bs->nchunks; i++)
+ for (j = 1; j < sizeof(uint)*CHAR_BIT; j++)
+ if (bs->chunks[i] & 1 << j)
+ n++;
+ return n;
+}
+
+void delbs(Bitset *bs)
+{
+ free(bs->chunks);
+ free(bs);
+}
+
+void bsput(Bitset *bs, uint elt)
+{
+ size_t sz;
+ if (elt >= bs->nchunks*Uintbits) {
+ sz = (elt/Uintbits)+1;
+ bs->chunks = zrealloc(bs->chunks, bs->nchunks*sizeof(uint), sz*sizeof(uint));
+ bs->nchunks = sz;
+ }
+ bs->chunks[elt/Uintbits] |= 1 << (elt % Uintbits);
+}
+
+void bsdel(Bitset *bs, uint elt)
+{
+ if (elt < bs->nchunks*Uintbits)
+ bs->chunks[elt/Uintbits] &= ~(1 << (elt % Uintbits));
+}
+
+int bshas(Bitset *bs, uint elt)
+{
+ if (elt >= bs->nchunks*Uintbits)
+ return 0;
+ else
+ return bs->chunks[elt/Uintbits] & (1 << (elt % Uintbits));
+}
+
+void bsunion(Bitset *a, Bitset *b)
+{
+ int i;
+
+ eqsz(a, b);
+ for (i = 0; i < a->nchunks; i++)
+ a->chunks[i] |= b->chunks[i];
+}
+
+void bsintersect(Bitset *a, Bitset *b)
+{
+ int i;
+
+ eqsz(a, b);
+ for (i = 0; i < a->nchunks; i++)
+ a->chunks[i] &= b->chunks[i];
+}
+
+void bsdiff(Bitset *a, Bitset *b)
+{
+ int i;
+
+ eqsz(a, b);
+ for (i = 0; i < a->nchunks; i++)
+ a->chunks[i] &= ~b->chunks[i];
+}
--- a/parse/ds.c
+++ /dev/null
@@ -1,116 +1,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <assert.h>
-#include <limits.h>
-#include <string.h>
-
-#include "parse.h"
-
-#define Uintbits (CHAR_BIT*sizeof(int))
-
-static void eqsz(Bitset *a, Bitset *b)
-{
- int sz;
-
- if (a->nchunks > b->nchunks)
- sz = a->nchunks;
- else
- sz = b->nchunks;
- a->chunks = zrealloc(a->chunks, a->nchunks*sizeof(uint), sz*sizeof(uint));
- a->nchunks = sz;
- b->chunks = zrealloc(b->chunks, a->nchunks*sizeof(uint), sz*sizeof(uint));
- b->nchunks = sz;
-}
-
-Bitset *mkbs()
-{
- Bitset *bs;
-
- bs = xalloc(sizeof(Bitset));
- bs->nchunks = 1;
- bs->chunks = zalloc(1*sizeof(uint));
- return bs;
-}
-
-Bitset *dupbs(Bitset *a)
-{
- Bitset *bs;
-
- bs = xalloc(sizeof(Bitset));
- bs->nchunks = a->nchunks;
- bs->chunks = xalloc(a->nchunks*sizeof(uint));
- memcpy(bs->chunks, a->chunks, a->nchunks*sizeof(uint));
- return bs;
-}
-
-int bscount(Bitset *bs)
-{
- int i, j, n;
-
- n = 0;
- for (i = 0; i < bs->nchunks; i++)
- for (j = 1; j < sizeof(uint)*CHAR_BIT; j++)
- if (bs->chunks[i] & 1 << j)
- n++;
- return n;
-}
-
-void delbs(Bitset *bs)
-{
- free(bs->chunks);
- free(bs);
-}
-
-void bsput(Bitset *bs, uint elt)
-{
- size_t sz;
- if (elt >= bs->nchunks*Uintbits) {
- sz = (elt/Uintbits)+1;
- bs->chunks = zrealloc(bs->chunks, bs->nchunks*sizeof(uint), sz*sizeof(uint));
- bs->nchunks = sz;
- }
- bs->chunks[elt/Uintbits] |= 1 << (elt % Uintbits);
-}
-
-void bsdel(Bitset *bs, uint elt)
-{
- if (elt < bs->nchunks*Uintbits)
- bs->chunks[elt/Uintbits] &= ~(1 << (elt % Uintbits));
-}
-
-int bshas(Bitset *bs, uint elt)
-{
- if (elt >= bs->nchunks*Uintbits)
- return 0;
- else
- return bs->chunks[elt/Uintbits] & (1 << (elt % Uintbits));
-}
-
-void bsunion(Bitset *a, Bitset *b)
-{
- int i;
-
- eqsz(a, b);
- for (i = 0; i < a->nchunks; i++)
- a->chunks[i] |= b->chunks[i];
-}
-
-void bsintersect(Bitset *a, Bitset *b)
-{
- int i;
-
- eqsz(a, b);
- for (i = 0; i < a->nchunks; i++)
- a->chunks[i] &= b->chunks[i];
-}
-
-void bsdiff(Bitset *a, Bitset *b)
-{
- int i;
-
- eqsz(a, b);
- for (i = 0; i < a->nchunks; i++)
- a->chunks[i] &= ~b->chunks[i];
-}
-
--- /dev/null
+++ b/parse/htab.c
@@ -1,0 +1,136 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
+#include "parse.h"
+
+#define Initsz 16
+
+Htab *mkht(ulong (*hash)(void *key), int (*cmp)(void *k1, void *k2))
+{
+ Htab *ht;
+
+ ht = xalloc(sizeof(Htab));
+ ht->nelt = 0;
+ ht->sz = Initsz;
+ ht->hash = hash;
+ ht->cmp = cmp;
+ ht->keys = zalloc(Initsz*sizeof(void*));
+ ht->vals = zalloc(Initsz*sizeof(void*));
+ ht->hashes = zalloc(Initsz*sizeof(void*));
+
+ return ht;
+}
+
+static ulong hash(Htab *ht, void *k)
+{
+ ulong h;
+ h = ht->hash(k);
+ if (h == 0)
+ return 1;
+ else
+ return h;
+}
+
+static void grow(Htab *ht, int sz)
+{
+ void **oldk;
+ void **oldv;
+ ulong *oldh;
+ int oldsz;
+ int i;
+
+ oldk = ht->keys;
+ oldv = ht->vals;
+ oldh = ht->hashes;
+ oldsz = ht->sz;
+
+ ht->nelt = 0;
+ ht->sz = sz;
+ ht->keys = zalloc(sz*sizeof(void*));
+ ht->vals = zalloc(sz*sizeof(void*));
+ ht->hashes = zalloc(sz*sizeof(void*));
+
+ for (i = 0; i < oldsz; i++)
+ if (oldh[i])
+ htput(ht, oldk[i], oldv[i]);
+ free(oldh);
+ free(oldk);
+ free(oldv);
+}
+
+int htput(Htab *ht, void *k, void *v)
+{
+ int i;
+ ulong h;
+ int di;
+
+ h = hash(ht, k);
+ i = h & (ht->sz - 1);
+ while (ht->hashes[i]) {
+ /* second insertion overwrites first */
+ if (ht->hashes[i] == h && ht->cmp(ht->keys[i], k))
+ break;
+ di++;
+ i = (h + di) & (ht->sz - 1);
+ }
+ ht->hashes[i] = h;
+ ht->keys[i] = k;
+ ht->vals[i] = v;
+ ht->nelt++;
+ if (ht->sz < ht->nelt*2)
+ grow(ht, ht->sz*2);
+ return 1;
+}
+
+ssize_t htidx(Htab *ht, void *k)
+{
+ int i;
+ ulong h;
+ int di;
+
+ h = hash(ht, k);
+ i = h & (ht->sz - 1);
+ while (ht->hashes[i] && ht->hashes[i] != h) {
+searchmore:
+ di++;
+ i = (h + di) & (ht->sz - 1);
+ }
+ if (!ht->hashes[i])
+ return -1;
+ if (!ht->cmp(ht->keys[i], k))
+ goto searchmore; /* collision */
+ return i;
+}
+
+void *htget(Htab *ht, void *k)
+{
+ ssize_t i;
+
+ i = htidx(ht, k);
+ if (i < 0)
+ return NULL;
+ else
+ return ht->vals[i];
+}
+
+int hthas(Htab *ht, void *k)
+{
+ return htidx(ht, k) >= 0;
+}
+
+void **htkeys(Htab *ht)
+{
+ void **k;
+ int i, j;
+
+ j = 0;
+ k = xalloc(sizeof(void*)*ht->nelt);
+ for (i = 0; i < ht->sz; i++)
+ if (ht->hashes[i])
+ k[j++] = ht->keys[i];
+ return k;
+}
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -4,6 +4,7 @@
typedef unsigned long long uvlong;
typedef struct Bitset Bitset;
+typedef struct Htab Htab;
typedef struct Tok Tok;
typedef struct Node Node;
@@ -54,6 +55,16 @@
uint *chunks;
};
+struct Htab {
+ size_t nelt;
+ size_t sz;
+ ulong (*hash)(void *k);
+ int (*cmp)(void *a, void *b);
+ void **keys;
+ void **vals;
+ ulong *hashes;
+};
+
struct Tok {
int type;
int line;
@@ -214,6 +225,15 @@
void bsintersect(Bitset *a, Bitset *b);
void bsdiff(Bitset *a, Bitset *b);
int bscount(Bitset *bs);
+
+Htab *mkht(ulong (*hash)(void *key), int (*cmp)(void *k1, void *k2));
+int htput(Htab *ht, void *k, void *v);
+void *htget(Htab *ht, void *k);
+int hthas(Htab *ht, void *k);
+void **htkeys(Htab *ht);
+/* useful key types */
+ulong strhash(void *str);
+ulong streq(void *s1, void *s2);
/* util functions */
void *zalloc(size_t size);