home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
High Voltage Shareware
/
high1.zip
/
high1
/
DIR2
/
CBUFF09.ZIP
/
SRC.ZIP
/
STRTABLE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-16
|
5KB
|
224 lines
/* $Id$
*
* File strtable.c
* Part of ChessBase utilities file format (CBUFF)
* Author Anjo Anjewierden, anjo@swi.psy.uva.nl
* Purpose Hash table for strings
* Works with GNU CC 2.4.5
*
* Notice Copyright (c) 1993 Anjo Anjewierden
*
* History 17/07/93 (Created)
* 18/07/93 (Last modified)
*/
/*------------------------------------------------------------
* Directives
*------------------------------------------------------------*/
#include "cbuff.h"
static unsigned long hashStringTable(StringTable, char *);
static unsigned long nextKeyStringTable(StringTable, unsigned long key);
static void reallocStringTable(StringTable);
/*------------------------------------------------------------
* Initialisation
*------------------------------------------------------------*/
StringTable
newStringTable(long entries)
{ StringTable st;
long n;
st = alloc(sizeof(struct string_table));
st->count = 0;
st->allocated = entries;
st->entries = (char **) alloc(sizeof(char *) * entries);
st->values = (void **) alloc(sizeof(void *) * entries);
for (n=0; n<entries; n++)
{ st->entries[n] = (char *) NULL;
st->values[n] = (void *) NULL;
}
return st;
}
void
freeStringTable(StringTable st)
{ long n;
for (n=0; n<st->allocated; n++)
{ if (st->entries[n] != (char *) NULL)
unallocCharp(st->entries[n]);
}
unalloc(st->entries);
unalloc(st);
}
/*------------------------------------------------------------
* Private functions
*------------------------------------------------------------*/
static unsigned long
hashStringTable(StringTable st, char *s)
{ unsigned long key = 0;
int shift;
for (shift=0; *s; shift++)
key += ((unsigned long) *s++) << (shift % 24);
return key % st->allocated;
}
static unsigned long
nextKeyStringTable(StringTable st, unsigned long key)
{ key++;
if (key >= st->allocated)
return 0;
return key;
}
static void
reallocStringTable(StringTable st)
{ if ((st->count*3) > (st->allocated*2))
{ char **entries;
void **values;
long n, k;
unsigned long key;
long allocated = st->allocated;
st->allocated = allocated * 2;
entries = (char **) alloc(sizeof(char *) * st->allocated);
values = (void **) alloc(sizeof(void *) * st->allocated);
for (n=0; n<st->allocated; n++)
entries[n] = (char *) NULL;
for (n=0; n<allocated; n++)
{ if (st->entries[n])
{ key = hashStringTable(st, st->entries[n]);
if (entries[key] == NULL)
{ entries[key] = st->entries[n];
values[key] = st->values[n];
continue;
}
for (k=key+1; k<st->allocated; k++)
if (entries[k] == NULL)
{ entries[k] = st->entries[n];
values[k] = st->values[n];
break;
}
if (k >= st->allocated)
{ for (k=0; ; k++)
if (entries[k] == NULL)
{ entries[k] = st->entries[n];
values[k] = st->values[n];
break;
}
}
}
}
unalloc(st->entries);
unalloc(st->values);
st->entries = entries;
st->values = values;
}
}
/*------------------------------------------------------------
* Public interface
*------------------------------------------------------------*/
void *
findStringTable(StringTable st, char *s)
{ unsigned long key;
for (key=hashStringTable(st,s); ; key=nextKeyStringTable(st,key))
{ if (st->entries[key])
{ if (strcmp(st->entries[key], s) == 0)
return st->values[key];
continue;
}
return (void *) NULL;
}
}
bool
containsStringTableP(StringTable st, char *s)
{ unsigned long key;
for (key=hashStringTable(st,s); ; key=nextKeyStringTable(st,key))
{ if (st->entries[key] == NULL)
return FALSE;
if (strcmp(st->entries[key], s) == 0)
return TRUE;
}
}
void
editStringTable(StringTable st, char *s, void *p)
{ unsigned long key;
for (key=hashStringTable(st,s); ; key=nextKeyStringTable(st,key))
{ if (st->entries[key])
{ if (strcmp(st->entries[key], s) == 0)
{ st->values[key] = p;
return;
}
continue;
}
return;
}
}
char *
addStringTable(StringTable st, char *s, void *p)
{ unsigned long key;
reallocStringTable(st);
for (key=hashStringTable(st,s); ; key=nextKeyStringTable(st,key))
{ if (st->entries[key] == NULL)
{ st->entries[key] = allocCharp(s);
st->values[key] = p;
st->count++;
return st->entries[key];
}
}
}
void
incStringTable(StringTable st, char *s)
{ long count;
if (containsStringTableP(st, s))
{ count = (long) findStringTable(st, s);
editStringTable(st, s, (void *) (count+1));
} else
addStringTable(st, s, (void *) 1L);
}
void
printStringTable(StringTable st, char *format, FILE *fd)
{ unsigned long key;
for (key=0; key<st->allocated; key++)
{ if (st->entries[key])
{ fprintf(fd, format, st->values[key]);
fprintf(fd, " %s\n", st->entries[key]);
}
}
}