#include "config.h"
#if STDC_HEADERS
#include <string.h>
#include <stdlib.h>
#define memzero(a, b) memset((a), 0, (b))
#else
#ifdef HAVE_MEMCPY
#define memzero(a, b) memset((a), 0, (b))
#else
#define memcpy(a, b, c) bcopy((b), (a), (c))
#define memzero(a, b) bzero((a), (b))
#define memcmp(a, b, c) bcmp((a), (b), (c))
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h>
#else
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#endif
void *malloc();
void free();
char *strdup();
#endif
#ifndef NULL
#define NULL 0
#endif
#ifdef HAVE_MATH_H
#include <math.h>
#endif
#if !HAVE_PID_T
typedef long pid_t;
#endif
#if !HAVE_ID_T
typedef long id_t;
#endif
#include "hash.h"
static int
next_prime(int x)
{
double i, j;
int f;
i = x;
while (i++)
{
f=1;
for (j=2; j<i; j++)
{
if ((i/j)==floor(i/j))
{
f=0;
break;
}
}
if (f)
{
return (int)i;
}
}
return 1;
}
static int
string_hash(hash_table *ht, char *key)
{
unsigned long s = 0;
unsigned char ch;
int shifting = 24;
while ((ch = (unsigned char)*key++) != '\0')
{
if (shifting == 0)
{
s = s + ch;
shifting = 24;
}
else
{
s = s + (ch << shifting);
shifting -= 8;
}
}
return (s % ht->num_buckets);
}
void ll_init(llist *q)
{
q->head = NULL;
q->count = 0;
}
llistitem *ll_newitem(int size)
{
llistitem *qi;
qi = (llistitem *)malloc(sizeof(llistitem) + size);
qi->datum = ((void *)qi + sizeof(llistitem));
return qi;
}
void ll_freeitem(llistitem *li)
{
free(li);
}
void ll_add(llist *q, llistitem *new)
{
new->next = q->head;
q->head = new;
q->count++;
}
void ll_extract(llist *q, llistitem *qi, llistitem *last)
{
if (last == NULL)
{
q->head = qi->next;
}
else
{
last->next = qi->next;
}
qi->next = NULL;
q->count--;
}
#define LL_FIRST(q) ((q)->head)
llistitem *
ll_first(llist *q)
{
return q->head;
}
#define LL_NEXT(q, qi) ((qi) != NULL ? (qi)->next : NULL)
llistitem *
ll_next(llist *q, llistitem *qi)
{
return (qi != NULL ? qi->next : NULL);
}
#define LL_ISEMPTY(ll) ((ll)->count == 0)
int
ll_isempty(llist *ll)
{
return (ll->count == 0);
}
hash_table *
hash_create(int num)
{
hash_table *result;
bucket_t *b;
int bytes;
int i;
result = (hash_table *)malloc(sizeof(hash_table));
num = next_prime(num);
bytes = sizeof(bucket_t) * num;
result->buckets = b = (bucket_t *)malloc(bytes);
result->num_buckets = num;
i = num;
while (--i >= 0)
{
ll_init(&(b->list));
b++;
}
return result;
}
unsigned int
hash_count(hash_table *ht)
{
register int i = 0;
register int cnt = 0;
register bucket_t *bucket;
bucket = ht->buckets;
while (i++ < ht->num_buckets)
{
cnt += bucket->list.count;
bucket++;
}
return cnt;
}
void
hash_sizeinfo(unsigned int *sizes, int max, hash_table *ht)
{
register int i;
register int idx;
register bucket_t *bucket;
memzero(sizes, max * sizeof(unsigned int));
bucket = ht->buckets;
i = 0;
while (i++ < ht->num_buckets)
{
idx = bucket->list.count;
sizes[idx >= max ? max-1 : idx]++;
bucket++;
}
}
void *
hash_add_uint(hash_table *ht, unsigned int key, void *value)
{
bucket_t *bucket;
hash_item_uint *hi;
hash_item_uint *h;
llist *ll;
llistitem *li;
llistitem *newli;
unsigned int k1;
newli = ll_newitem(sizeof(hash_item_uint));
hi = (hash_item_uint *)newli->datum;
hi->key = key;
hi->value = value;
bucket = &(ht->buckets[(key % ht->num_buckets)]);
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
h = (hash_item_uint *)li->datum;
k1 = h->key;
if (key == k1)
{
break;
}
li = LL_NEXT(ll, li);
}
li = NULL;
if (li == NULL)
{
ll_add(&(bucket->list), newli);
return NULL;
}
else
{
ll_freeitem(newli);
return ((hash_item_uint *)(li->datum))->value;
}
}
void *
hash_replace_uint(hash_table *ht, unsigned int key, void *value)
{
bucket_t *bucket;
hash_item_uint *hi;
llist *ll;
llistitem *li;
void *result = NULL;
unsigned int k1;
bucket = &(ht->buckets[(key % ht->num_buckets)]);
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
hi = (hash_item_uint *)li->datum;
k1 = hi->key;
if (key == k1)
{
result = hi->value;
hi->value = value;
break;
}
li = LL_NEXT(ll, li);
}
if (result == NULL)
{
li = ll_newitem(sizeof(hash_item_uint));
hi = (hash_item_uint *)li->datum;
hi->key = key;
hi->value = value;
ll_add(&(bucket->list), li);
}
return result;
}
void *
hash_lookup_uint(hash_table *ht, unsigned int key)
{
bucket_t *bucket;
llist *ll;
llistitem *li;
hash_item_uint *h;
void *result;
unsigned int k1;
result = NULL;
if ((bucket = &(ht->buckets[(key % ht->num_buckets)])) != NULL)
{
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
h = (hash_item_uint *)li->datum;
k1 = h->key;
if (key == k1)
{
result = h->value;
break;
}
li = LL_NEXT(ll, li);
}
}
return result;
}
void *
hash_remove_uint(hash_table *ht, unsigned int key)
{
bucket_t *bucket;
llist *ll;
llistitem *li;
llistitem *lilast;
hash_item_uint *hi;
void *result;
unsigned int k1;
result = NULL;
if ((bucket = &(ht->buckets[(key % ht->num_buckets)])) != NULL)
{
ll = &(bucket->list);
li = LL_FIRST(ll);
lilast = NULL;
while (li != NULL)
{
hi = (hash_item_uint *)li->datum;
k1 = hi->key;
if (key == k1)
{
ll_extract(ll, li, lilast);
result = hi->value;
key = hi->key;
;
ll_freeitem(li);
break;
}
lilast = li;
li = LL_NEXT(ll, li);
}
}
return result;
}
hash_item_uint *
hash_first_uint(hash_table *ht, hash_pos *pos)
{
pos->num_buckets = ht->num_buckets;
pos->hash_bucket = ht->buckets;
pos->curr = 0;
pos->ll_last = NULL;
while(pos->hash_bucket->list.count == 0)
{
pos->hash_bucket++;
if (++pos->curr >= pos->num_buckets)
{
return NULL;
}
}
pos->ll_item = LL_FIRST(&(pos->hash_bucket->list));
return (hash_item_uint *)pos->ll_item->datum;
}
hash_item_uint *
hash_next_uint(hash_pos *pos)
{
llistitem *li;
if ((pos->ll_last = pos->ll_item) == NULL)
{
if (pos->curr >= pos->num_buckets)
{
return NULL;
}
li = LL_FIRST(&(pos->hash_bucket->list));
}
else
{
li = LL_NEXT(&(pos->hash_bucket->list), pos->ll_item);
}
while (li == NULL)
{
pos->ll_last = NULL;
pos->hash_bucket++;
if (++pos->curr >= pos->num_buckets)
{
pos->ll_item = NULL;
return NULL;
}
li = LL_FIRST(&(pos->hash_bucket->list));
}
pos->ll_item = li;
return (hash_item_uint *)li->datum;
}
void *
hash_remove_pos_uint(hash_pos *pos)
{
llistitem *li;
void *ans;
hash_item_uint *hi;
unsigned int key;
if (pos == NULL || pos->ll_last == pos->ll_item)
{
return NULL;
}
li = pos->ll_item;
ll_extract(&(pos->hash_bucket->list), li, pos->ll_last);
hi = (hash_item_uint *)li->datum;
ans = hi->value;
key = hi->key;
;
ll_freeitem(li);
pos->ll_item = pos->ll_last;
return ans;
}
void *
hash_add_pid(hash_table *ht, pid_t key, void *value)
{
bucket_t *bucket;
hash_item_pid *hi;
hash_item_pid *h;
llist *ll;
llistitem *li;
llistitem *newli;
pid_t k1;
newli = ll_newitem(sizeof(hash_item_pid));
hi = (hash_item_pid *)newli->datum;
hi->key = key;
hi->value = value;
bucket = &(ht->buckets[(key % ht->num_buckets)]);
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
h = (hash_item_pid *)li->datum;
k1 = h->key;
if (key == k1)
{
break;
}
li = LL_NEXT(ll, li);
}
li = NULL;
if (li == NULL)
{
ll_add(&(bucket->list), newli);
return NULL;
}
else
{
ll_freeitem(newli);
return ((hash_item_pid *)(li->datum))->value;
}
}
void *
hash_replace_pid(hash_table *ht, pid_t key, void *value)
{
bucket_t *bucket;
hash_item_pid *hi;
llist *ll;
llistitem *li;
void *result = NULL;
pid_t k1;
bucket = &(ht->buckets[(key % ht->num_buckets)]);
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
hi = (hash_item_pid *)li->datum;
k1 = hi->key;
if (key == k1)
{
result = hi->value;
hi->value = value;
break;
}
li = LL_NEXT(ll, li);
}
if (result == NULL)
{
li = ll_newitem(sizeof(hash_item_pid));
hi = (hash_item_pid *)li->datum;
hi->key = key;
hi->value = value;
ll_add(&(bucket->list), li);
}
return result;
}
void *
hash_lookup_pid(hash_table *ht, pid_t key)
{
bucket_t *bucket;
llist *ll;
llistitem *li;
hash_item_pid *h;
void *result;
pid_t k1;
result = NULL;
if ((bucket = &(ht->buckets[(key % ht->num_buckets)])) != NULL)
{
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
h = (hash_item_pid *)li->datum;
k1 = h->key;
if (key == k1)
{
result = h->value;
break;
}
li = LL_NEXT(ll, li);
}
}
return result;
}
void *
hash_remove_pid(hash_table *ht, pid_t key)
{
bucket_t *bucket;
llist *ll;
llistitem *li;
llistitem *lilast;
hash_item_pid *hi;
void *result;
pid_t k1;
result = NULL;
if ((bucket = &(ht->buckets[(key % ht->num_buckets)])) != NULL)
{
ll = &(bucket->list);
li = LL_FIRST(ll);
lilast = NULL;
while (li != NULL)
{
hi = (hash_item_pid *)li->datum;
k1 = hi->key;
if (key == k1)
{
ll_extract(ll, li, lilast);
result = hi->value;
key = hi->key;
;
ll_freeitem(li);
break;
}
lilast = li;
li = LL_NEXT(ll, li);
}
}
return result;
}
hash_item_pid *
hash_first_pid(hash_table *ht, hash_pos *pos)
{
pos->num_buckets = ht->num_buckets;
pos->hash_bucket = ht->buckets;
pos->curr = 0;
pos->ll_last = NULL;
while(pos->hash_bucket->list.count == 0)
{
pos->hash_bucket++;
if (++pos->curr >= pos->num_buckets)
{
return NULL;
}
}
pos->ll_item = LL_FIRST(&(pos->hash_bucket->list));
return (hash_item_pid *)pos->ll_item->datum;
}
hash_item_pid *
hash_next_pid(hash_pos *pos)
{
llistitem *li;
if ((pos->ll_last = pos->ll_item) == NULL)
{
if (pos->curr >= pos->num_buckets)
{
return NULL;
}
li = LL_FIRST(&(pos->hash_bucket->list));
}
else
{
li = LL_NEXT(&(pos->hash_bucket->list), pos->ll_item);
}
while (li == NULL)
{
pos->ll_last = NULL;
pos->hash_bucket++;
if (++pos->curr >= pos->num_buckets)
{
pos->ll_item = NULL;
return NULL;
}
li = LL_FIRST(&(pos->hash_bucket->list));
}
pos->ll_item = li;
return (hash_item_pid *)li->datum;
}
void *
hash_remove_pos_pid(hash_pos *pos)
{
llistitem *li;
void *ans;
hash_item_pid *hi;
pid_t key;
if (pos == NULL || pos->ll_last == pos->ll_item)
{
return NULL;
}
li = pos->ll_item;
ll_extract(&(pos->hash_bucket->list), li, pos->ll_last);
hi = (hash_item_pid *)li->datum;
ans = hi->value;
key = hi->key;
;
ll_freeitem(li);
pos->ll_item = pos->ll_last;
return ans;
}
void *
hash_add_string(hash_table *ht, char * key, void *value)
{
bucket_t *bucket;
hash_item_string *hi;
hash_item_string *h;
llist *ll;
llistitem *li;
llistitem *newli;
char * k1;
newli = ll_newitem(sizeof(hash_item_string));
hi = (hash_item_string *)newli->datum;
hi->key = strdup(key);
hi->value = value;
bucket = &(ht->buckets[string_hash(ht, key)]);
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
h = (hash_item_string *)li->datum;
k1 = h->key;
if (strcmp(key, k1) == 0)
{
break;
}
li = LL_NEXT(ll, li);
}
li = NULL;
if (li == NULL)
{
ll_add(&(bucket->list), newli);
return NULL;
}
else
{
ll_freeitem(newli);
return ((hash_item_string *)(li->datum))->value;
}
}
void *
hash_replace_string(hash_table *ht, char * key, void *value)
{
bucket_t *bucket;
hash_item_string *hi;
llist *ll;
llistitem *li;
void *result = NULL;
char * k1;
bucket = &(ht->buckets[string_hash(ht, key)]);
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
hi = (hash_item_string *)li->datum;
k1 = hi->key;
if (strcmp(key, k1) == 0)
{
result = hi->value;
hi->value = value;
break;
}
li = LL_NEXT(ll, li);
}
if (result == NULL)
{
li = ll_newitem(sizeof(hash_item_string));
hi = (hash_item_string *)li->datum;
hi->key = strdup(key);
hi->value = value;
ll_add(&(bucket->list), li);
}
return result;
}
void *
hash_lookup_string(hash_table *ht, char * key)
{
bucket_t *bucket;
llist *ll;
llistitem *li;
hash_item_string *h;
void *result;
char * k1;
result = NULL;
if ((bucket = &(ht->buckets[string_hash(ht, key)])) != NULL)
{
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
h = (hash_item_string *)li->datum;
k1 = h->key;
if (strcmp(key, k1) == 0)
{
result = h->value;
break;
}
li = LL_NEXT(ll, li);
}
}
return result;
}
void *
hash_remove_string(hash_table *ht, char * key)
{
bucket_t *bucket;
llist *ll;
llistitem *li;
llistitem *lilast;
hash_item_string *hi;
void *result;
char * k1;
result = NULL;
if ((bucket = &(ht->buckets[string_hash(ht, key)])) != NULL)
{
ll = &(bucket->list);
li = LL_FIRST(ll);
lilast = NULL;
while (li != NULL)
{
hi = (hash_item_string *)li->datum;
k1 = hi->key;
if (strcmp(key, k1) == 0)
{
ll_extract(ll, li, lilast);
result = hi->value;
key = hi->key;
free(key);
ll_freeitem(li);
break;
}
lilast = li;
li = LL_NEXT(ll, li);
}
}
return result;
}
hash_item_string *
hash_first_string(hash_table *ht, hash_pos *pos)
{
pos->num_buckets = ht->num_buckets;
pos->hash_bucket = ht->buckets;
pos->curr = 0;
pos->ll_last = NULL;
while(pos->hash_bucket->list.count == 0)
{
pos->hash_bucket++;
if (++pos->curr >= pos->num_buckets)
{
return NULL;
}
}
pos->ll_item = LL_FIRST(&(pos->hash_bucket->list));
return (hash_item_string *)pos->ll_item->datum;
}
hash_item_string *
hash_next_string(hash_pos *pos)
{
llistitem *li;
if ((pos->ll_last = pos->ll_item) == NULL)
{
if (pos->curr >= pos->num_buckets)
{
return NULL;
}
li = LL_FIRST(&(pos->hash_bucket->list));
}
else
{
li = LL_NEXT(&(pos->hash_bucket->list), pos->ll_item);
}
while (li == NULL)
{
pos->ll_last = NULL;
pos->hash_bucket++;
if (++pos->curr >= pos->num_buckets)
{
pos->ll_item = NULL;
return NULL;
}
li = LL_FIRST(&(pos->hash_bucket->list));
}
pos->ll_item = li;
return (hash_item_string *)li->datum;
}
void *
hash_remove_pos_string(hash_pos *pos)
{
llistitem *li;
void *ans;
hash_item_string *hi;
char * key;
if (pos == NULL || pos->ll_last == pos->ll_item)
{
return NULL;
}
li = pos->ll_item;
ll_extract(&(pos->hash_bucket->list), li, pos->ll_last);
hi = (hash_item_string *)li->datum;
ans = hi->value;
key = hi->key;
free(key);
ll_freeitem(li);
pos->ll_item = pos->ll_last;
return ans;
}
void *
hash_add_pidthr(hash_table *ht, pidthr_t key, void *value)
{
bucket_t *bucket;
hash_item_pidthr *hi;
hash_item_pidthr *h;
llist *ll;
llistitem *li;
llistitem *newli;
pidthr_t k1;
newli = ll_newitem(sizeof(hash_item_pidthr));
hi = (hash_item_pidthr *)newli->datum;
hi->key = key;
hi->value = value;
bucket = &(ht->buckets[((key.k_thr * 10000 + key.k_pid) % ht->num_buckets)]);
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
h = (hash_item_pidthr *)li->datum;
k1 = h->key;
if ((key.k_pid == k1.k_pid && key.k_thr == k1.k_thr))
{
break;
}
li = LL_NEXT(ll, li);
}
li = NULL;
if (li == NULL)
{
ll_add(&(bucket->list), newli);
return NULL;
}
else
{
ll_freeitem(newli);
return ((hash_item_pidthr *)(li->datum))->value;
}
}
void *
hash_replace_pidthr(hash_table *ht, pidthr_t key, void *value)
{
bucket_t *bucket;
hash_item_pidthr *hi;
llist *ll;
llistitem *li;
void *result = NULL;
pidthr_t k1;
bucket = &(ht->buckets[((key.k_thr * 10000 + key.k_pid) % ht->num_buckets)]);
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
hi = (hash_item_pidthr *)li->datum;
k1 = hi->key;
if ((key.k_pid == k1.k_pid && key.k_thr == k1.k_thr))
{
result = hi->value;
hi->value = value;
break;
}
li = LL_NEXT(ll, li);
}
if (result == NULL)
{
li = ll_newitem(sizeof(hash_item_pidthr));
hi = (hash_item_pidthr *)li->datum;
hi->key = key;
hi->value = value;
ll_add(&(bucket->list), li);
}
return result;
}
void *
hash_lookup_pidthr(hash_table *ht, pidthr_t key)
{
bucket_t *bucket;
llist *ll;
llistitem *li;
hash_item_pidthr *h;
void *result;
pidthr_t k1;
result = NULL;
if ((bucket = &(ht->buckets[((key.k_thr * 10000 + key.k_pid) % ht->num_buckets)])) != NULL)
{
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
h = (hash_item_pidthr *)li->datum;
k1 = h->key;
if ((key.k_pid == k1.k_pid && key.k_thr == k1.k_thr))
{
result = h->value;
break;
}
li = LL_NEXT(ll, li);
}
}
return result;
}
void *
hash_remove_pidthr(hash_table *ht, pidthr_t key)
{
bucket_t *bucket;
llist *ll;
llistitem *li;
llistitem *lilast;
hash_item_pidthr *hi;
void *result;
pidthr_t k1;
result = NULL;
if ((bucket = &(ht->buckets[((key.k_thr * 10000 + key.k_pid) % ht->num_buckets)])) != NULL)
{
ll = &(bucket->list);
li = LL_FIRST(ll);
lilast = NULL;
while (li != NULL)
{
hi = (hash_item_pidthr *)li->datum;
k1 = hi->key;
if ((key.k_pid == k1.k_pid && key.k_thr == k1.k_thr))
{
ll_extract(ll, li, lilast);
result = hi->value;
key = hi->key;
;
ll_freeitem(li);
break;
}
lilast = li;
li = LL_NEXT(ll, li);
}
}
return result;
}
hash_item_pidthr *
hash_first_pidthr(hash_table *ht, hash_pos *pos)
{
pos->num_buckets = ht->num_buckets;
pos->hash_bucket = ht->buckets;
pos->curr = 0;
pos->ll_last = NULL;
while(pos->hash_bucket->list.count == 0)
{
pos->hash_bucket++;
if (++pos->curr >= pos->num_buckets)
{
return NULL;
}
}
pos->ll_item = LL_FIRST(&(pos->hash_bucket->list));
return (hash_item_pidthr *)pos->ll_item->datum;
}
hash_item_pidthr *
hash_next_pidthr(hash_pos *pos)
{
llistitem *li;
if ((pos->ll_last = pos->ll_item) == NULL)
{
if (pos->curr >= pos->num_buckets)
{
return NULL;
}
li = LL_FIRST(&(pos->hash_bucket->list));
}
else
{
li = LL_NEXT(&(pos->hash_bucket->list), pos->ll_item);
}
while (li == NULL)
{
pos->ll_last = NULL;
pos->hash_bucket++;
if (++pos->curr >= pos->num_buckets)
{
pos->ll_item = NULL;
return NULL;
}
li = LL_FIRST(&(pos->hash_bucket->list));
}
pos->ll_item = li;
return (hash_item_pidthr *)li->datum;
}
void *
hash_remove_pos_pidthr(hash_pos *pos)
{
llistitem *li;
void *ans;
hash_item_pidthr *hi;
pidthr_t key;
if (pos == NULL || pos->ll_last == pos->ll_item)
{
return NULL;
}
li = pos->ll_item;
ll_extract(&(pos->hash_bucket->list), li, pos->ll_last);
hi = (hash_item_pidthr *)li->datum;
ans = hi->value;
key = hi->key;
;
ll_freeitem(li);
pos->ll_item = pos->ll_last;
return ans;
}
#if HAVE_LWPID_T
void *
hash_add_lwpid(hash_table *ht, lwpid_t key, void *value)
{
bucket_t *bucket;
hash_item_lwpid *hi;
hash_item_lwpid *h;
llist *ll;
llistitem *li;
llistitem *newli;
lwpid_t k1;
newli = ll_newitem(sizeof(hash_item_lwpid));
hi = (hash_item_lwpid *)newli->datum;
hi->key = key;
hi->value = value;
bucket = &(ht->buckets[(key % ht->num_buckets)]);
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
h = (hash_item_lwpid *)li->datum;
k1 = h->key;
if (key == k1)
{
break;
}
li = LL_NEXT(ll, li);
}
li = NULL;
if (li == NULL)
{
ll_add(&(bucket->list), newli);
return NULL;
}
else
{
ll_freeitem(newli);
return ((hash_item_lwpid *)(li->datum))->value;
}
}
void *
hash_replace_lwpid(hash_table *ht, lwpid_t key, void *value)
{
bucket_t *bucket;
hash_item_lwpid *hi;
llist *ll;
llistitem *li;
void *result = NULL;
lwpid_t k1;
bucket = &(ht->buckets[(key % ht->num_buckets)]);
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
hi = (hash_item_lwpid *)li->datum;
k1 = hi->key;
if (key == k1)
{
result = hi->value;
hi->value = value;
break;
}
li = LL_NEXT(ll, li);
}
if (result == NULL)
{
li = ll_newitem(sizeof(hash_item_lwpid));
hi = (hash_item_lwpid *)li->datum;
hi->key = key;
hi->value = value;
ll_add(&(bucket->list), li);
}
return result;
}
void *
hash_lookup_lwpid(hash_table *ht, lwpid_t key)
{
bucket_t *bucket;
llist *ll;
llistitem *li;
hash_item_lwpid *h;
void *result;
lwpid_t k1;
result = NULL;
if ((bucket = &(ht->buckets[(key % ht->num_buckets)])) != NULL)
{
ll = &(bucket->list);
li = LL_FIRST(ll);
while (li != NULL)
{
h = (hash_item_lwpid *)li->datum;
k1 = h->key;
if (key == k1)
{
result = h->value;
break;
}
li = LL_NEXT(ll, li);
}
}
return result;
}
void *
hash_remove_lwpid(hash_table *ht, lwpid_t key)
{
bucket_t *bucket;
llist *ll;
llistitem *li;
llistitem *lilast;
hash_item_lwpid *hi;
void *result;
lwpid_t k1;
result = NULL;
if ((bucket = &(ht->buckets[(key % ht->num_buckets)])) != NULL)
{
ll = &(bucket->list);
li = LL_FIRST(ll);
lilast = NULL;
while (li != NULL)
{
hi = (hash_item_lwpid *)li->datum;
k1 = hi->key;
if (key == k1)
{
ll_extract(ll, li, lilast);
result = hi->value;
key = hi->key;
;
ll_freeitem(li);
break;
}
lilast = li;
li = LL_NEXT(ll, li);
}
}
return result;
}
hash_item_lwpid *
hash_first_lwpid(hash_table *ht, hash_pos *pos)
{
pos->num_buckets = ht->num_buckets;
pos->hash_bucket = ht->buckets;
pos->curr = 0;
pos->ll_last = NULL;
while(pos->hash_bucket->list.count == 0)
{
pos->hash_bucket++;
if (++pos->curr >= pos->num_buckets)
{
return NULL;
}
}
pos->ll_item = LL_FIRST(&(pos->hash_bucket->list));
return (hash_item_lwpid *)pos->ll_item->datum;
}
hash_item_lwpid *
hash_next_lwpid(hash_pos *pos)
{
llistitem *li;
if ((pos->ll_last = pos->ll_item) == NULL)
{
if (pos->curr >= pos->num_buckets)
{
return NULL;
}
li = LL_FIRST(&(pos->hash_bucket->list));
}
else
{
li = LL_NEXT(&(pos->hash_bucket->list), pos->ll_item);
}
while (li == NULL)
{
pos->ll_last = NULL;
pos->hash_bucket++;
if (++pos->curr >= pos->num_buckets)
{
pos->ll_item = NULL;
return NULL;
}
li = LL_FIRST(&(pos->hash_bucket->list));
}
pos->ll_item = li;
return (hash_item_lwpid *)li->datum;
}
void *
hash_remove_pos_lwpid(hash_pos *pos)
{
llistitem *li;
void *ans;
hash_item_lwpid *hi;
lwpid_t key;
if (pos == NULL || pos->ll_last == pos->ll_item)
{
return NULL;
}
li = pos->ll_item;
ll_extract(&(pos->hash_bucket->list), li, pos->ll_last);
hi = (hash_item_lwpid *)li->datum;
ans = hi->value;
key = hi->key;
;
ll_freeitem(li);
pos->ll_item = pos->ll_last;
return ans;
}
#endif