wxWidgets/wxPython/wxSWIG/SWIG/hash.cxx

360 lines
8.5 KiB
C++
Raw Normal View History

/*******************************************************************************
* Simplified Wrapper and Interface Generator (SWIG)
*
* Author : David Beazley
*
* Department of Computer Science
* University of Chicago
* 1100 E 58th Street
* Chicago, IL 60637
* beazley@cs.uchicago.edu
*
* Please read the file LICENSE for the copyright and terms by which SWIG
* can be used and distributed.
*******************************************************************************/
#include "internal.h"
/*******************************************************************************
* $Header$
*
* File : hash.cxx
*
* A very simple Hash table class. Could probably make it more elegant with
* templates, but templates are pure evil...
*******************************************************************************/
#define INIT_SIZE 119
// -----------------------------------------------------------------------------
// Hash::Hash()
//
// Constructor. Creates a new hash table.
//
// Inputs : None
//
// Output : New Hash object.
//
// Side Effects : None
// -----------------------------------------------------------------------------
Hash::Hash() {
int i;
hashsize = INIT_SIZE;
hashtable = new Node *[hashsize];
for (i = 0; i < hashsize; i++) {
hashtable[i] = 0;
}
index = -1;
current = 0;
}
// -----------------------------------------------------------------------------
// Hash::~Hash()
//
// Destructor.
//
// Inputs : None
//
// Output : None
//
// Side Effects : Total destruction.
// -----------------------------------------------------------------------------
Hash::~Hash() {
int i;
Node *n,*next;
for (i = 0; i < hashsize; i++) {
if (hashtable[i]) {
n = hashtable[i];
while (n) {
next = n->next;
delete n;
n = next;
}
}
}
delete [] hashtable;
}
// -----------------------------------------------------------------------------
// int Hash::h1(const char *key)
//
// Hashing function.
//
// Inputs : ASCII character string.
//
// Output : Hash table index.
//
// Side Effects : None
// -----------------------------------------------------------------------------
int Hash::h1(const char *key) {
int h = 0;
const char *c;
c = key;
while (*c) {
h = (128*h + *c) % hashsize;
c++;
}
return h;
}
// -----------------------------------------------------------------------------
// int Hash::add(const char *k, void *obj)
//
// Adds a new object to the hash table.
//
// Inputs :
// k = Hash key
// obj = Pointer to an object
//
// Output : 0 on success, -1 if item is already in hash table.
//
// Side Effects :
// Makes a new hash table entry.
// -----------------------------------------------------------------------------
int Hash::add(const char *k, void *obj) {
int hv;
Node *n,*prev;
hv = h1(k); // Get hash value
n = hashtable[hv];
prev = n;
while (n) {
if (strcmp(n->key,k) == 0) return -1; // Already in hash table
prev = n;
n = n->next;
}
// Safe to add this to the table
n = new Node(k,obj,0);
if (prev) prev->next = n;
else hashtable[hv] = n;
return 0;
}
// -----------------------------------------------------------------------------
// int Hash::add(const char *k, void *obj, void (*d)(void *))
//
// Adds a new object to the hash table. Allows additional specification of
// a callback function for object deletion.
//
// Inputs :
// k = Hash key
// obj = Object pointer
// d = Deletion function
//
// Output : 0 on success, -1 if item is already in hash table.
//
// Side Effects :
// Adds an entry to the hash table
// -----------------------------------------------------------------------------
int Hash::add(const char *k, void *obj, void (*d)(void *)) {
int hv;
Node *n,*prev;
hv = h1(k); // Get hash value
n = hashtable[hv];
prev = n;
while (n) {
if (strcmp(n->key,k) == 0) return -1; // Already in hash table
prev = n;
n = n->next;
}
// Safe to add this to the table
n = new Node(k,obj,d);
if (prev) prev->next = n;
else hashtable[hv] = n;
return 0;
}
// -----------------------------------------------------------------------------
// void *Hash::lookup(const char *k)
//
// Looks up a value in the hash table. Returns a pointer to the object if found.
//
// Inputs : k = key value
//
// Output : Pointer to object or NULL if not found.
//
// Side Effects : None
// -----------------------------------------------------------------------------
void *Hash::lookup(const char *k) {
int hv;
Node *n;
hv = h1(k); // Get hash value
n = hashtable[hv];
while (n) {
if (strcmp(n->key,k) == 0) return n->object;
n = n->next;
}
return 0;
}
// -----------------------------------------------------------------------------
// void Hash::remove(const char *k)
//
// Removes an item from the hash table. Does nothing if item isn't in the
// hash table to begin with.
//
// Inputs : k = Key value
//
// Output : None
//
// Side Effects : Deletes item from hash table.
// -----------------------------------------------------------------------------
void Hash::remove(const char *k) {
int hv;
Node *n,*prev;
hv = h1(k); // Get hash value
n = hashtable[hv];
prev = 0;
while (n) {
if (strcmp(n->key,k) == 0) {
// Found it, kill the thing
if (prev) {
prev->next = n->next;
} else {
hashtable[hv] = n->next;
}
delete n;
return;
}
prev = n;
n = n->next;
}
}
// -----------------------------------------------------------------------------
// void *Hash::first()
//
// Gets the first item from the hash table or NULL if empty.
//
// Inputs : None
//
// Output : First object in hash table or NULL if hash table is empty.
//
// Side Effects : Resets an internal iterator variable on the hash table.
// -----------------------------------------------------------------------------
void *Hash::first() {
index = 0;
current = 0;
while (!hashtable[index] && (index < hashsize))
index++;
if (index >= hashsize) return 0;
current = hashtable[index];
return current->object;
}
// -----------------------------------------------------------------------------
// char *Hash::firstkey()
//
// Gets the first key from the hash table or NULL if empty.
//
// Inputs : None
//
// Output : First key in hash table or NULL if hash table is empty.
//
// Side Effects : Resets an internal iterator variable on the hash table.
// -----------------------------------------------------------------------------
char *Hash::firstkey() {
index = 0;
current = 0;
while ((index < hashsize) && (!hashtable[index]))
index++;
if (index >= hashsize) return 0;
current = hashtable[index];
return current->key;
}
// -----------------------------------------------------------------------------
// void *Hash::next()
//
// Returns the next item in the hash table or NULL if there are no more entries.
// A call to first() should generally be made before using this function.
//
// Inputs : None
//
// Output : Pointer to next object or NULL if there are no more objects.
//
// Side Effects : Updates an iterator variable private to the hash table.
// -----------------------------------------------------------------------------
void *Hash::next() {
if (index < 0) return first();
// Try to move to the next entry
current = current->next;
if (current) {
return current->object;
} else {
index++;
while ((index < hashsize) && (!hashtable[index]))
index++;
if (index >= hashsize) return 0;
current = hashtable[index];
return current->object;
}
}
// -----------------------------------------------------------------------------
// char *Hash::nextkey()
//
// Returns the next key in the hash table or NULL if there are no more entries.
// A call to firstkey() should generally be made before using this function.
//
// Inputs : None
//
// Output : Pointer to next key or NULL if there are no more objects.
//
// Side Effects : Updates an iterator variable private to the hash table.
// -----------------------------------------------------------------------------
char *Hash::nextkey() {
if (index < 0) return firstkey();
// Try to move to the next entry
current = current->next;
if (current) {
return current->key;
} else {
index++;
while (!hashtable[index] && (index < hashsize))
index++;
if (index >= hashsize) return 0;
current = hashtable[index];
return current->key;
}
}