2 * Copyright (c) 2000-2001
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #define INIT_TABLE_SIZE 2
39 #define UB(n) ((1<<n)-1) /* 2^n-1 */
40 #define CAP(n) (1<<n) /* 2^n */
44 int *traditional table
;
46 unsigned int capacity
;
51 static const int prime_1
= 83;
52 static const int prime_2
= 5189;
53 static const int init_table_size
= INIT_TABLE_SIZE
;
54 static const int empty_key
= EMPTY_KEY
;
56 hash_set
hs_create(region r
)
59 hash_set hs
= ralloc(r
, struct hash_set
);
61 hs
->ub
= UB(init_table_size
);
62 hs
->size
= init_table_size
;
63 hs
->capacity
= CAP(init_table_size
);
64 hs
->table
= (int *)calloc(hs
->capacity
, sizeof(int));
69 int hs_num_items(hash_set hs
)
74 int *hs_list_items(hash_set hs
)
79 static bool member(int *table
, int ub
, int i
, int value
)
81 while (table
[i
] != empty_key
)
83 if (table
[i
] == value
)
87 i
= ub
& (i
+ prime_2
);
92 static inline void reinsert(int *table
, int ub
, int value
)
96 i
= ub
& (prime_1
* value
);
98 while (table
[i
] != empty_key
)
100 /* possibly the value is already present */
101 if (table
[i
] == value
)
105 i
= ub
& (i
+ prime_2
);
111 static bool member_or_insert(int *table
, int ub
, int i
, int value
)
113 while (table
[i
] != empty_key
)
115 if (table
[i
] == value
)
119 i
= ub
& (i
+ prime_2
);
125 static void rehash(hash_set hs
)
130 old_table
= hs
->table
;
131 old_capacity
= hs
->capacity
;
133 hs
->ub
= UB(++hs
->size
);
134 hs
->table
= (int *)calloc(hs
->capacity
, sizeof(int));
138 for (i
= 0; i
< old_capacity
; i
++)
140 reinsert(hs
->table
, hs
->ub
, old_table
[i
]);
146 static void post_insert(hash_set hs)
150 int capacity = hs->capacity;
151 int inserts = ++hs->inserts;
153 printf("%d,%d->%f\n",inserts,capacity,percent_full);
155 percent_full = (float) inserts / capacity;
158 if (percent_full != percent_full)
163 if (percent_full >= .85)
168 static void post_insert(hash_set hs
)
170 int capacity
= hs
->capacity
;
171 int inserts
= ++hs
->inserts
;
173 float percent_capacity
= capacity
* .85;
176 printf("%d,%d->%f\n",inserts,capacity,percent_capacity);
179 if ( (float) inserts
>= percent_capacity
)
187 bool hs_query(hash_set hs
, int entry
)
192 hash
= ub
& (prime_1
* abs(entry
));
193 return member(hs
->table
, ub
, hash
, entry
);
196 bool hs_member(hash_set hs
, int entry
)
201 hash
= ub
& (prime_1
* abs(entry
));
202 if (member_or_insert(hs
->table
, ub
, hash
, entry
))
212 void hs_delete(hash_set hs
)