hash.c revision a3b6849ec9a7e7cb209d0e330211aed6395daabd
/* GLIB - Library of useful routines for C programming
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/*
* Modified by the GLib Team and others 1997-1999. See the AUTHORS
* file for a list of people on the GLib Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GLib at ftp://ftp.gtk.org/pub/gtk/.
*/
/* several modifications Copyright (C) 2002 by Timo Sirainen */
#include "lib.h"
#include "hash.h"
#include "primes.h"
#include <ctype.h>
#define HASH_TABLE_MIN_SIZE 11
#define HASH_TABLE_MAX_SIZE 13845163
typedef struct _HashNode {
void *key;
void *value;
int destroyed;
} HashNode;
struct _HashTable {
unsigned int size;
unsigned int nodes_count, nodes_destroyed;
int frozen;
};
static int foreach_stop;
static unsigned int direct_hash(const void *p)
{
/* NOTE: may truncate the value, but that doesn't matter. */
return POINTER_TO_UINT(p);
}
const void *value)
{
return node;
}
{
}
}
{
return table;
}
{
unsigned int i;
return;
}
{
unsigned int i;
}
}
static inline HashNode **
{
/* Hash table lookup needs to be fast.
We therefore remove the extra conditional of testing
whether to call the key_compare_func or not from
the inner loop. */
if (table->key_compare_func) {
break;
}
} else {
}
return node;
}
{
}
{
return FALSE;
return TRUE;
}
const void *value, int replace_key)
{
table->nodes_count++;
} else {
}
}
}
{
}
{
}
{
table->nodes_count--;
table->nodes_destroyed++;
} else {
}
}
}
{
}
{
}
{
unsigned int i;
if (foreach_stop) {
return;
}
}
}
}
}
void hash_foreach_stop(void)
{
foreach_stop = TRUE;
}
/* Returns the number of elements contained in the hash table. */
{
return table->nodes_count;
}
{
float nodes_per_list;
return FALSE;
} else {
}
}
}
table->nodes_destroyed = 0;
return TRUE;
}
{
unsigned int i;
if (hash_resize(table))
return;
if (table->nodes_destroyed == 0)
return;
/* find the destroyed nodes from hash table and remove them */
/* next points to free'd memory area now,
fix it */
if (--table->nodes_destroyed == 0)
return;
}
}
}
}
/* a char* hash function from ASU -- from glib */
unsigned int str_hash(const void *p)
{
const unsigned char *s = p;
unsigned int g, h = 0;
while (*s != '\0') {
h = (h << 4) + *s;
if ((g = h & 0xf0000000UL)) {
h = h ^ (g >> 24);
h = h ^ g;
}
s++;
}
return h;
}
/* a char* hash function from ASU -- from glib */
unsigned int strcase_hash(const void *p)
{
const unsigned char *s = p;
unsigned int g, h = 0;
while (*s != '\0') {
h = (h << 4) + i_toupper(*s);
if ((g = h & 0xf0000000UL)) {
h = h ^ (g >> 24);
h = h ^ g;
}
s++;
}
return h;
}