home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 February
/
CHIP_2_98.iso
/
misc
/
src
/
install
/
hash.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-09-17
|
3KB
|
160 lines
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "hash.h"
#define CHUNK 4
struct bucket {
char **data;
int allocated;
int firstFree; /* as in data[firstFree] */
};
struct hash_table {
int size;
int entries;
int totalData;
int overHead;
struct bucket *bucket;
};
struct hash_table *htNewTable(int size)
{
struct hash_table *res;
int i = 0;
res = malloc(sizeof(struct hash_table));
res->bucket = malloc(sizeof(struct bucket) * size);
res->size = size;
res->totalData = 0;
res->entries = 0;
res->overHead = sizeof(struct bucket) * size + CHUNK * sizeof(char *);
while (i < size) {
res->bucket[i].data = malloc(CHUNK * sizeof(char *));
res->bucket[i].allocated = CHUNK;
res->bucket[i].firstFree = 0;
i++;
}
return res;
}
void htFreeHashTable(struct hash_table *ht)
{
while (ht->size--) {
free(ht->bucket[ht->size].data);
}
free(ht->bucket);
free(ht);
}
void htHashStats(struct hash_table *t)
{
int i = 0;
int empty = 0;
while (i < t->size) {
if (t->bucket[i].firstFree != 0) {
/*printf("Bucket %d used %d\n", i, t->bucket[i].firstFree);*/
} else {
empty++;
}
i++;
}
printf("Total Buckets : %d\n", t->size);
printf("Empty Buckets : %d\n", empty);
printf("Total Entries : %d\n", t->entries);
printf("Total Data : %d\n", t->totalData);
printf("Total Overhead: %d\n", t->overHead);
printf("Avergage Depth: %f\n", (double)t->entries / (double)t->size);
}
static unsigned int htHashString(char *s)
{
unsigned int res = 0;
while (*s)
res = ((res<<1) + (int)(*(s++)));
return res;
}
static char *in_table_aux(struct hash_table *t, int hash, char *s)
{
int x;
x = 0;
while (x < t->bucket[hash].firstFree) {
if (! strcmp(t->bucket[hash].data[x], s)) {
return t->bucket[hash].data[x];
}
x++;
}
return NULL;
}
char *htInTable(struct hash_table *t, char *s)
{
int hash;
hash = htHashString(s) % t->size;
return in_table_aux(t, hash, s);
}
void htAddToTable(struct hash_table *t, char *s)
{
int hash;
hash = htHashString(s) % t->size;
if (in_table_aux(t, hash, s)) {
return;
}
if (t->bucket[hash].firstFree == t->bucket[hash].allocated) {
t->bucket[hash].allocated += CHUNK;
t->bucket[hash].data =
realloc(t->bucket[hash].data,
t->bucket[hash].allocated * sizeof(char *));
/*printf("Bucket %d grew to %d\n", hash, t->bucket[hash].allocated);*/
t->overHead += sizeof(char *) * CHUNK;
}
/*printf("In bucket %d, item %d\n", hash, t->bucket[hash].firstFree);*/
t->bucket[hash].data[t->bucket[hash].firstFree++] = strdup(s);
t->totalData += strlen(s) + 1;
t->entries++;
}
int htNumEntries(struct hash_table *t) {
return t->entries;
}
void htIterStart(htIterator * iter) {
iter->bucket = 0;
iter->item = -1;
}
int htIterGetNext(struct hash_table * t, htIterator * iter, char ** s) {
iter->item++;
while (iter->bucket < t->size) {
if (iter->item < t->bucket[iter->bucket].firstFree) {
*s = t->bucket[iter->bucket].data[iter->item];
return 1;
}
iter->item++;
if (iter->item >= t->bucket[iter->bucket].firstFree) {
iter->bucket++;
iter->item = 0;
}
}
return 0;
}