diff --git a/table.c b/table.c index e6096a5..175e076 100644 --- a/table.c +++ b/table.c @@ -20,14 +20,14 @@ void TableInit(struct Table *Tbl, struct TableEntry **HashTable, int Size, int O } /* check a hash table entry for a key */ -static int TableSearch(struct Table *Tbl, const char *Key, int Len, int *AddAt) +static int TableSearch(struct Table *Tbl, const char *Key, int *AddAt) { struct TableEntry *Entry; - int HashValue = TableHash(Key, Len) % Tbl->Size; + int HashValue = ((unsigned long)Key) % Tbl->Size; for (Entry = Tbl->HashTable[HashValue]; Entry != NULL; Entry = Entry->Next) { - if (strncmp(Entry->Key, Key, Len) == 0 && Entry->Key[Len] == '\0') + if (Entry->p.v.Key == Key) return HashValue; /* found */ } @@ -35,18 +35,18 @@ static int TableSearch(struct Table *Tbl, const char *Key, int Len, int *AddAt) return -1; } -/* set an identifier to a value. returns FALSE if it already exists */ +/* set an identifier to a value. returns FALSE if it already exists. + * Key must be a shared string from StrRegister() */ int TableSet(struct Table *Tbl, const char *Key, struct Value *Val) { int AddAt; - int KeyLen = strlen(Key); - int HashPos = TableSearch(Tbl, Key, KeyLen, &AddAt); + int HashPos = TableSearch(Tbl, Key, &AddAt); if (HashPos == -1) { /* add it to the table */ struct TableEntry *NewEntry = VariableAlloc(NULL, sizeof(struct TableEntry), Tbl->OnHeap); - NewEntry->Key = Key; - NewEntry->Val = Val; + NewEntry->p.v.Key = Key; + NewEntry->p.v.Val = Val; NewEntry->Next = Tbl->HashTable[AddAt]; Tbl->HashTable[AddAt] = NewEntry; return TRUE; @@ -55,34 +55,49 @@ int TableSet(struct Table *Tbl, const char *Key, struct Value *Val) return FALSE; } -/* find a value in a table. returns FALSE if not found */ +/* find a value in a table. returns FALSE if not found. + * Key must be a shared string from StrRegister() */ int TableGet(struct Table *Tbl, const char *Key, struct Value **Val) { int AddAt; - int HashPos = TableSearch(Tbl, Key, strlen(Key), &AddAt); + int HashPos = TableSearch(Tbl, Key, &AddAt); if (HashPos == -1) return FALSE; - *Val = Tbl->HashTable[HashPos]->Val; + *Val = Tbl->HashTable[HashPos]->p.v.Val; return TRUE; } +/* check a hash table entry for an identifier */ +static int TableSearchIdentifier(struct Table *Tbl, const char *Key, int Len, int *AddAt) +{ + struct TableEntry *Entry; + int HashValue = TableHash(Key, Len) % Tbl->Size; + + for (Entry = Tbl->HashTable[HashValue]; Entry != NULL; Entry = Entry->Next) + { + if (strncmp(Entry->p.Key, Key, Len) == 0 && Entry->p.Key[Len] == '\0') + return HashValue; /* found */ + } + + *AddAt = HashValue; /* didn't find it in the chain */ + return -1; +} + /* set an identifier and return the identifier. share if possible */ -const char *TableSetKey(struct Table *Tbl, const char *Ident, int IdentLen) +const char *TableSetIdentifier(struct Table *Tbl, const char *Ident, int IdentLen) { int AddAt; - int HashPos = TableSearch(Tbl, Ident, IdentLen, &AddAt); + int HashPos = TableSearchIdentifier(Tbl, Ident, IdentLen, &AddAt); if (HashPos != -1) - return Tbl->HashTable[HashPos]->Key; + return Tbl->HashTable[HashPos]->p.Key; else - { /* add it to the table */ - struct TableEntry *NewEntry = HeapAlloc(sizeof(struct TableEntry) + IdentLen + 1); - NewEntry->Key = (void *)NewEntry + sizeof(struct TableEntry); - strncpy((char *)NewEntry->Key, Ident, IdentLen); - NewEntry->Val = NULL; + { /* add it to the table - we economise by not allocating the whole structure here */ + struct TableEntry *NewEntry = HeapAlloc(sizeof(struct TableEntry *) + IdentLen + 1); + strncpy((char *)NewEntry->p.Key, Ident, IdentLen); NewEntry->Next = Tbl->HashTable[AddAt]; Tbl->HashTable[AddAt] = NewEntry; - return NewEntry->Key; + return NewEntry->p.Key; } }