picoc/table.c
zik.saleeba 7bfc2c0be5 Initial checkin of picoc. Not working yet.
git-svn-id: http://picoc.googlecode.com/svn/trunk@2 21eae674-98b7-11dd-bd71-f92a316d2d60
2008-10-13 00:53:28 +00:00

123 lines
2.5 KiB
C

#include <string.h>
#include "picoc.h"
#ifdef USE_MALLOC
#include <stdlib.h>
static unsigned int TableHash(const Str *Key)
{
unsigned int Hash;
int Count;
int Offset;
const char *KeyPos;
Hash = Key->Len;
KeyPos = Key->Str;
Offset = 8;
for (Count = 0; Count < Key->Len; Count++, Offset+=7)
{
if (Offset > sizeof(unsigned int) * 8 - 7)
Offset -= (sizeof(unsigned int)-1) * 8;
Hash ^= *KeyPos++ << Offset;
}
return Hash;
}
void TableInit(struct Table *Tbl, struct TableEntry *HashTable, const char *Name, int Size)
{
Tbl->Name = Name;
Tbl->Size = Size;
Tbl->HashTable = HashTable;
memset(HashTable, '\0', sizeof(struct TableEntry) * Size);
}
static int TableCheckEntry(struct Table *Tbl, const Str *Key, int HashPos)
{
struct TableEntry *Entry = &Tbl->HashTable[HashPos];
if (Entry->Key.Len == 0)
return -1; /* empty */
else if (StrEqual(&Entry->Key, Key))
return HashPos; /* found */
else
return -2; /* wrong key */
}
static int TableSearch(struct Table *Tbl, const Str *Key, int *AddAt)
{
int HashValue;
int HashPos;
int Result;
HashValue = TableHash(Key) % Tbl->Size;
for (HashPos = HashValue; HashPos < Tbl->Size; HashPos++)
{
*AddAt = HashPos;
if ( (Result = TableCheckEntry(Tbl, Key, HashPos)) != -2)
return Result;
}
for (HashPos = 0; HashPos < HashValue; HashPos++)
{
*AddAt = HashPos;
if ( (Result = TableCheckEntry(Tbl, Key, HashPos)) != -2)
return Result;
}
/* not found and table is full */
*AddAt = -1;
return -1;
}
void TableSet(struct Table *Tbl, const Str *Key, void *Value)
{
int HashPos;
int AddAt;
HashPos = TableSearch(Tbl, Key, &AddAt);
if (HashPos != -1)
Tbl->HashTable[HashPos].Value = Value; /* found - update value */
else
{
if (AddAt == -1)
Fail("table '%s' is full\n", Tbl->Name);
else
{ /* add it to the table */
struct TableEntry *Entry = &Tbl->HashTable[AddAt];
Entry->Key = *Key;
Entry->Value = Value;
}
}
}
void *TableLookup(struct Table *Tbl, const Str *Key)
{
int HashPos;
int AddAt;
HashPos = TableSearch(Tbl, Key, &AddAt);
if (HashPos == -1)
return NULL;
else
return Tbl->HashTable[HashPos].Value;
}
#endif