#ifndef __DHASH_H__ #define __DHASH_H__ typedef unsigned int hash_t; typedef struct { int flags; struct event_args *ev; } dhash_val_t; typedef struct { int size; int count; dhash_val_t *ary; } dhash_t; dhash_val_t EMPTY = { 0, NULL }; #define dhash_init(h) \ { \ Newz(0, (h)->ary, 4, dhash_val_t); \ (h)->size = 4; \ (h)->count = 0; \ } inline hash_t HASH(register hash_t k) { k += (k << 12); k ^= (k >> 22); k += (k << 4); k ^= (k >> 9); k += (k << 10); k ^= (k >> 2); k += (k << 7); k ^= (k >> 12); return k; } void dhash_insert(dhash_t *h, dhash_val_t val, hash_t hash) { while (h->ary[hash].ev && h->ary[hash].ev != val.ev) hash = ++hash % h->size; if (h->ary[hash].ev != val.ev) h->count++; h->ary[hash] = val; } void dhash_resize(dhash_t *h) { dhash_val_t *old; register int i; register hash_t hash; New(0, old, h->size, dhash_val_t); Copy(h->ary, old, h->size, dhash_val_t); h->size <<= 1; h->count = 0; Newz(0, h->ary, h->size, dhash_val_t); for (i = 0; i < h->size>>1; i++) { if (!old[i].ev) continue; hash = HASH(PTR2IV(old[i].ev)) % h->size; dhash_insert(h, old[i], hash); } Safefree(old); } void dhash_store(dhash_t *h, dhash_val_t val) { hash_t hash; if (h->count / h->size > 0.8) dhash_resize(h); hash = HASH(PTR2IV(val.ev)) & h->size; dhash_insert(h, val, hash); } dhash_val_t * dhash_find(dhash_t *h, struct event_args *ev) { hash_t hash = HASH(PTR2IV(ev)) % h->size; hash_t stop = hash; register int i; while (h->ary[hash].ev != ev) { hash = (hash + 1) % h->size; if (hash == stop) goto NOT_FOUND; } return &h->ary[hash]; NOT_FOUND: return NULL; } void dhash_delete(dhash_t *h, struct event_args *ev) { hash_t hash = HASH(PTR2IV(ev)) % h->size; dhash_val_t *found; if (found = dhash_find(h, ev)) { *found = EMPTY; h->count--; } } #endif