Skip to content

Instantly share code, notes, and snippets.

@z-rui
Created November 2, 2018 19:59
Show Gist options
  • Save z-rui/8cbf07d72dd228e9a6860c18b25f2bea to your computer and use it in GitHub Desktop.
Save z-rui/8cbf07d72dd228e9a6860c18b25f2bea to your computer and use it in GitHub Desktop.
Open addressing, linear probing hash table
#include "hash.h"
#include <assert.h>
void **hash_find(void **base, size_t n, void *key,
size_t hash, int (*equal)(const void *, const void *))
{
void **p, **q, **end;
p = q = base + hash % n;
end = base + n;
while (*p && !(*equal)(key, *p))
if (++p == end)
p = base;
else
assert(p != q);
return p;
}
void hash_del(void **base, size_t n, void **p,
size_t (*hasher)(const void *))
{
void **q, **r, **end;
q = p;
end = base + n;
erase:
*p = NULL;
for (;;) {
if (++q == end)
q = base;
if (*q == NULL)
break;
r = base + (*hasher)(*q) % n;
if ((r <= p) + (q < r) + (p < q) == 2) {
*p = *q;
p = q;
goto erase;
}
}
}
void hash_copy(void **dst, size_t ndst, void **src, size_t nsrc,
size_t (*hasher)(const void *))
{
void **p, **end;
end = dst + ndst;
assert(dst != src);
for (; nsrc--; src++) {
if (*src) {
p = dst + (*hasher)(*src) % ndst;
while (*p)
if (++p == end)
p = dst;
*p = *src;
}
}
}
/*
* Hash Table
*/
#ifndef HASH_H
#define HASH_H
#include <stddef.h>
extern void **hash_find(void **base, size_t n, void *key,
size_t hash, int (*equal)(const void *, const void *));
extern void hash_del(void **base, size_t n, void **p,
size_t (*hasher)(const void *));
extern void hash_copy(void **dst, size_t ndst, void **src, size_t nsrc,
size_t (*hasher)(const void *));
#endif /* HASH_H */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment