From a34f75d0fb42cebb34861fdb606320ac7355cfd1 Mon Sep 17 00:00:00 2001
From: cuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Date: Wed, 22 Oct 2003 18:13:07 +0000
Subject: [PATCH] Use the new hash table module

git-svn-id: svn://svn.cc65.org/cc65/trunk@2558 b7a2c559-68d2-44c3-8de9-860c34a00d81
---
 src/ca65/filetab.c | 109 ++++++++++++++++++++++++++++++++++-----------
 1 file changed, 83 insertions(+), 26 deletions(-)

diff --git a/src/ca65/filetab.c b/src/ca65/filetab.c
index 2ad8257c0..bcc51ad65 100644
--- a/src/ca65/filetab.c
+++ b/src/ca65/filetab.c
@@ -38,7 +38,7 @@
 /* common */
 #include "check.h"
 #include "coll.h"
-#include "hashstr.h"
+#include "hashtab.h"
 #include "xmalloc.h"
 
 /* ca65 */
@@ -49,17 +49,41 @@
 
 
 
+/*****************************************************************************/
+/*                                 Forwards                                  */
+/*****************************************************************************/
+
+
+
+static unsigned GenHash (const void* Index);
+/* Generate the hash over an index. */
+
+static const void* GetIndex (void* Entry);
+/* Given a pointer to the user entry data, return a pointer to the index */
+
+static HashNode* GetHashNode (void* Entry);
+/* Given a pointer to the user entry data, return a pointer to the hash node */
+
+static int Compare (const void* Index1, const void* Index2);
+/* Compare two indices for equality */
+
+
+
 /*****************************************************************************/
 /*     	       	    		     Data			   	     */
 /*****************************************************************************/
 
 
 
+/* Number of entries in the table and the mask to generate the hash */
+#define HASHTAB_MASK    0x1F
+#define HASHTAB_COUNT   (HASHTAB_MASK + 1)
+
 /* An entry in the file table */
 typedef struct FileEntry FileEntry;
 struct FileEntry {
+    HashNode            Node;
     unsigned            Name;           /* File name */
-    FileEntry* 	      	Next;		/* Next in hash list */
     unsigned	      	Index;		/* Index of entry */
     unsigned long     	Size;		/* Size of file */
     unsigned long     	MTime;		/* Time of last modification */
@@ -68,10 +92,54 @@ struct FileEntry {
 /* Array of all entries, listed by index */
 static Collection FileTab = STATIC_COLLECTION_INITIALIZER;
 
+/* Hash table functions */
+static const HashFunctions HashFunc = {
+    GenHash,
+    GetIndex,
+    GetHashNode,
+    Compare
+};
+
 /* Hash table, hashed by name */
-#define HASHTAB_MASK    0x1FU
-#define HASHTAB_SIZE   	(HASHTAB_MASK + 1)
-static FileEntry*	HashTab[HASHTAB_SIZE];
+static HashTable HashTab = STATIC_HASHTABLE_INITIALIZER (HASHTAB_COUNT, &HashFunc);
+
+
+
+/*****************************************************************************/
+/*                           Hash table functions                            */
+/*****************************************************************************/
+
+
+
+static unsigned GenHash (const void* Index)
+/* Generate the hash over an index. */
+{
+    return (*(const unsigned*)Index & HASHTAB_MASK);
+}
+
+
+
+static const void* GetIndex (void* Entry)
+/* Given a pointer to the user entry data, return a pointer to the index */
+{
+    return &((FileEntry*) Entry)->Name;
+}
+
+
+
+static HashNode* GetHashNode (void* Entry)
+/* Given a pointer to the user entry data, return a pointer to the hash node */
+{
+    return &((FileEntry*) Entry)->Node;
+}
+
+
+
+static int Compare (const void* Index1, const void* Index2)
+/* Compare two indices for equality */
+{
+    return (*(const unsigned*)Index1 == *(const unsigned*)Index2);
+}
 
 
 
@@ -84,13 +152,11 @@ static FileEntry*	HashTab[HASHTAB_SIZE];
 static FileEntry* NewFileEntry (unsigned Name, unsigned long Size, unsigned long MTime)
 /* Create a new FileEntry, insert it into the tables and return it */
 {
-    /* Get the hash over the name */
-    unsigned Hash = (Name & HASHTAB_MASK);
-
     /* Allocate memory for the entry */
     FileEntry* F = xmalloc (sizeof (FileEntry));
 
     /* Initialize the fields */
+    InitHashNode (&F->Node, F);
     F->Name     = Name;
     F->Index  	= CollCount (&FileTab) + 1;     /* First file has index #1 */
     F->Size   	= Size;
@@ -100,8 +166,7 @@ static FileEntry* NewFileEntry (unsigned Name, unsigned long Size, unsigned long
     CollAppend (&FileTab, F);
 
     /* Insert the entry into the hash table */
-    F->Next = HashTab[Hash];
-    HashTab[Hash] = F;
+    HT_Insert (&HashTab, &F->Node);
 
     /* Return the new entry */
     return F;
@@ -139,24 +204,16 @@ unsigned GetFileIndex (const char* Name)
     /* Get the string pool index from the name */
     unsigned NameIdx = GetStringId (Name);
 
-    /* Get the hash over the name */
-    unsigned Hash = (NameIdx & HASHTAB_MASK);
+    /* Search in the hash table for the name */
+    FileEntry* F = HT_FindEntry (&HashTab, &NameIdx);
 
-    /* Search the linear hash list */
-    FileEntry* F = HashTab[Hash];
-    while (F) {
-	/* Is it this one? */
-       	if (NameIdx == F->Name) {
-	    /* Found, return the index */
-	    return F->Index;
-	}
-	/* No, check next */
-	F = F->Next;
+    /* If we don't have this index, print a diagnostic and use the main file */
+    if (F == 0) {
+        Error (ERR_FILENAME_NOT_FOUND, Name);
+        return 0;
+    } else {
+        return F->Index;
     }
-
-    /* Not found, use main file */
-    Error (ERR_FILENAME_NOT_FOUND, Name);
-    return 0;
 }