Use the new hash table module
git-svn-id: svn://svn.cc65.org/cc65/trunk@2558 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -38,7 +38,7 @@
|
|||||||
/* common */
|
/* common */
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
#include "coll.h"
|
#include "coll.h"
|
||||||
#include "hashstr.h"
|
#include "hashtab.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
||||||
/* ca65 */
|
/* 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 */
|
/* 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 */
|
/* An entry in the file table */
|
||||||
typedef struct FileEntry FileEntry;
|
typedef struct FileEntry FileEntry;
|
||||||
struct FileEntry {
|
struct FileEntry {
|
||||||
|
HashNode Node;
|
||||||
unsigned Name; /* File name */
|
unsigned Name; /* File name */
|
||||||
FileEntry* Next; /* Next in hash list */
|
|
||||||
unsigned Index; /* Index of entry */
|
unsigned Index; /* Index of entry */
|
||||||
unsigned long Size; /* Size of file */
|
unsigned long Size; /* Size of file */
|
||||||
unsigned long MTime; /* Time of last modification */
|
unsigned long MTime; /* Time of last modification */
|
||||||
@@ -68,10 +92,54 @@ struct FileEntry {
|
|||||||
/* Array of all entries, listed by index */
|
/* Array of all entries, listed by index */
|
||||||
static Collection FileTab = STATIC_COLLECTION_INITIALIZER;
|
static Collection FileTab = STATIC_COLLECTION_INITIALIZER;
|
||||||
|
|
||||||
|
/* Hash table functions */
|
||||||
|
static const HashFunctions HashFunc = {
|
||||||
|
GenHash,
|
||||||
|
GetIndex,
|
||||||
|
GetHashNode,
|
||||||
|
Compare
|
||||||
|
};
|
||||||
|
|
||||||
/* Hash table, hashed by name */
|
/* Hash table, hashed by name */
|
||||||
#define HASHTAB_MASK 0x1FU
|
static HashTable HashTab = STATIC_HASHTABLE_INITIALIZER (HASHTAB_COUNT, &HashFunc);
|
||||||
#define HASHTAB_SIZE (HASHTAB_MASK + 1)
|
|
||||||
static FileEntry* HashTab[HASHTAB_SIZE];
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* 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)
|
static FileEntry* NewFileEntry (unsigned Name, unsigned long Size, unsigned long MTime)
|
||||||
/* Create a new FileEntry, insert it into the tables and return it */
|
/* 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 */
|
/* Allocate memory for the entry */
|
||||||
FileEntry* F = xmalloc (sizeof (FileEntry));
|
FileEntry* F = xmalloc (sizeof (FileEntry));
|
||||||
|
|
||||||
/* Initialize the fields */
|
/* Initialize the fields */
|
||||||
|
InitHashNode (&F->Node, F);
|
||||||
F->Name = Name;
|
F->Name = Name;
|
||||||
F->Index = CollCount (&FileTab) + 1; /* First file has index #1 */
|
F->Index = CollCount (&FileTab) + 1; /* First file has index #1 */
|
||||||
F->Size = Size;
|
F->Size = Size;
|
||||||
@@ -100,8 +166,7 @@ static FileEntry* NewFileEntry (unsigned Name, unsigned long Size, unsigned long
|
|||||||
CollAppend (&FileTab, F);
|
CollAppend (&FileTab, F);
|
||||||
|
|
||||||
/* Insert the entry into the hash table */
|
/* Insert the entry into the hash table */
|
||||||
F->Next = HashTab[Hash];
|
HT_Insert (&HashTab, &F->Node);
|
||||||
HashTab[Hash] = F;
|
|
||||||
|
|
||||||
/* Return the new entry */
|
/* Return the new entry */
|
||||||
return F;
|
return F;
|
||||||
@@ -139,24 +204,16 @@ unsigned GetFileIndex (const char* Name)
|
|||||||
/* Get the string pool index from the name */
|
/* Get the string pool index from the name */
|
||||||
unsigned NameIdx = GetStringId (Name);
|
unsigned NameIdx = GetStringId (Name);
|
||||||
|
|
||||||
/* Get the hash over the name */
|
/* Search in the hash table for the name */
|
||||||
unsigned Hash = (NameIdx & HASHTAB_MASK);
|
FileEntry* F = HT_FindEntry (&HashTab, &NameIdx);
|
||||||
|
|
||||||
/* Search the linear hash list */
|
/* If we don't have this index, print a diagnostic and use the main file */
|
||||||
FileEntry* F = HashTab[Hash];
|
if (F == 0) {
|
||||||
while (F) {
|
|
||||||
/* Is it this one? */
|
|
||||||
if (NameIdx == F->Name) {
|
|
||||||
/* Found, return the index */
|
|
||||||
return F->Index;
|
|
||||||
}
|
|
||||||
/* No, check next */
|
|
||||||
F = F->Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Not found, use main file */
|
|
||||||
Error (ERR_FILENAME_NOT_FOUND, Name);
|
Error (ERR_FILENAME_NOT_FOUND, Name);
|
||||||
return 0;
|
return 0;
|
||||||
|
} else {
|
||||||
|
return F->Index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user