This commit was generated by cvs2svn to compensate for changes in r2,
[btb/d2x.git] / misc / hash.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14 #ifdef RCS
15 static char rcsid[] = "$Id: hash.c,v 1.1.1.1 2001-01-19 03:30:14 bradleyb Exp $";
16 #endif
17
18 #include <conf.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22
23 #include "u_mem.h"
24 #include "strutil.h"
25 #include "error.h"
26 #include "hash.h"
27         
28 int hashtable_init( hashtable *ht, int size )   {
29         int i;
30
31         ht->size=0;
32
33         for (i=1; i<13; i++ )   {
34                 if ( (1<<i) >= size )   {
35                         ht->bitsize = i;
36                         ht->size = 1<<i;
37                         break;
38                 }
39         }
40         size = ht->size;
41         ht->and_mask = ht->size - 1;
42         if (ht->size==0)
43                 Error( "Hashtable has size of 0" );
44
45         ht->key = (char **)d_malloc( size * sizeof(char *) );
46         if (ht->key==NULL)
47                 Error( "Not enough memory to create a hash table of size %d", size );
48
49         for (i=0; i<size; i++ )
50                 ht->key[i] = NULL;
51
52         // Use calloc cause we want zero'd array.
53         ht->value = d_malloc( size*sizeof(int) );
54         if (ht->value==NULL)    {
55                 d_free(ht->key);
56                 Error( "Not enough memory to create a hash table of size %d\n", size );
57         }
58
59         ht->nitems = 0;
60
61         return 0;
62 }
63
64 void hashtable_free( hashtable *ht )    {
65         if (ht->key != NULL )
66                 d_free( ht->key );
67         if (ht->value != NULL )
68                 d_free( ht->value );
69         ht->size = 0;
70 }
71
72 int hashtable_getkey( char *key )       {
73         int k = 0, i=0;
74
75         while( *key )   {
76                 k^=((int)(*key++))<<i;
77                 i++;
78         }
79         return k;
80 }
81
82 int hashtable_search( hashtable *ht, char *key )        {
83         int i,j,k;
84
85         strlwr( key );
86
87         k = hashtable_getkey( key );
88         i = 0;
89         
90         while(i < ht->size )    {
91                 j = (k+(i++)) & ht->and_mask;
92                 if ( ht->key[j] == NULL )
93                         return -1;
94                 if (!stricmp(ht->key[j], key ))
95                         return ht->value[j];
96         }
97         return -1;
98 }
99
100 void hashtable_insert( hashtable *ht, char *key, int value )    {
101         int i,j,k;
102
103         strlwr( key );
104         k = hashtable_getkey( key );
105         i = 0;
106
107         while(i < ht->size)     {
108                 j = (k+(i++)) & ht->and_mask;
109                 if ( ht->key[j] == NULL )       {
110                         ht->nitems++;
111                         ht->key[j] = key;
112                         ht->value[j] = value;
113                         return;
114                 } else if (!stricmp( key, ht->key[j] )) {
115                         return;
116                 }
117         }
118         Error( "Out of hash slots\n" );
119 }