root/src/ohtbl.cc

Revision 5, 2.4 KB (checked in by nick, 3 years ago)
Line 
1#include "apachetop.h"
2
3#include "inlines.cc"
4
5#define OACMP(a, b) (strcmp((char *)a, (char *)b) == 0) ? 1 : 0
6#define OA_H1(k) (TTHash(k) % positions)
7#define OA_H2(k) (1 + (StringHash(k) % (positions-2)))
8#define OA_HASH(k) (OA_H1(k) + (i * OA_H2(k))) % positions
9
10static int primes[] = {101, 241, 499, 1009, 2003, 3001, 4001, 5003,
11                       10007, 15013, 19381, 29131, 38011, 45589,
12                       80021, 100003, 150001, 200003, 500009, 5000011, 0};
13
14int OAHash::getNextPrime(int size)
15{
16        register int *prime;
17        for (prime = &primes[0] ; *prime ; prime++)
18                if (*prime > size)
19                        return *prime;
20       
21        return size*2; /* we're out of primes so give up */
22}
23
24int OAHash::create(int p_positions)
25{
26        unsigned int i;
27
28        /* use the next prime up from p_positions */
29        if ((p_positions = getNextPrime(p_positions)) == -1)
30                abort();
31       
32        if ((table = (ohEntry *)malloc(p_positions * sizeof(ohEntry))) == NULL)
33                return -1;
34       
35        positions = p_positions;
36
37        for(i = 0 ; i < positions ; ++i)
38                table[i].key = NULL;
39
40        size = 0;
41
42        return 0;
43}
44
45void OAHash::destroy(void)
46{
47        free(table);
48
49        return;
50}
51
52void *OAHash::insert(char *key, void *data)
53{
54        register unsigned int p, i;
55        void *d;
56 
57        // Do not exceed the number of positions in the table.
58        if (size == positions)
59                return NULL;
60
61        // Do nothing if the data is already in the table.
62        if ((d = lookup(key)))
63                /* return the position in case it can be used */
64                return d;
65
66        for (i = 0; i < positions; ++i)
67        {
68                p = OA_HASH(key);
69                if (table[p].key == NULL || table[p].key == &vacated)
70                {
71                        // Insert the data into the table.
72                        table[p].key = key;
73                        table[p].data = data;
74                        size++;
75                        return data;
76                }
77        }
78
79        return NULL;
80}
81
82int OAHash::remove(char *key)
83{
84        register unsigned int p, i;
85
86        for (i = 0; i < positions; ++i)
87        {
88                p = OA_HASH(key);
89                if (table[p].key == NULL)
90                {
91                        // Return that the data was not found.
92                        return -1;
93                }
94                else if (table[p].key == &vacated)
95                {
96                        // Search beyond vacated positions.
97                        continue;
98                }
99                else if (OACMP(table[p].key, key))
100                {
101                        table[p].key = &vacated;
102                        size--;
103                        return 0;
104                }
105        }
106        return -1;
107}
108
109void *OAHash::lookup(char *key)
110{
111        register unsigned int p, i;
112
113        for (i = 0; i < positions; ++i)
114        {
115                p = OA_HASH(key);
116                if (table[p].key == NULL)
117                {
118                        return NULL;
119                }
120
121                else if (table[p].key == &vacated)
122                {
123                        continue;
124                }
125
126                else if (OACMP(table[p].key, key))
127                        // return pointer to data
128                        return table[p].data;
129
130        }
131        return NULL;
132}
Note: See TracBrowser for help on using the browser.