PR opt/14472
[official-gcc.git] / libbanshee / engine / hashset.c
blob27195e767bdca66d44712060f51e792ce0d8d5e4
1 /*
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
7 * are met:
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
27 * SUCH DAMAGE.
31 #include <stdlib.h>
32 #include <assert.h>
33 #include <math.h>
35 #include "hashset.h"
36 #include "util.h"
37 #define INIT_TABLE_SIZE 2
38 #define EMPTY_KEY 0
39 #define UB(n) ((1<<n)-1) /* 2^n-1 */
40 #define CAP(n) (1<<n) /* 2^n */
42 struct hash_set
44 int *traditional table;
45 unsigned int ub;
46 unsigned int capacity;
47 unsigned int inserts;
48 unsigned int size;
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));
65 hs->inserts = 0;
66 return hs;
69 int hs_num_items(hash_set hs)
71 return hs->inserts;
74 int *hs_list_items(hash_set hs)
76 return hs->table;
79 static bool member(int *table, int ub, int i, int value)
81 while (table[i] != empty_key)
83 if (table[i] == value)
84 return TRUE;
86 else
87 i = ub & (i + prime_2);
89 return FALSE;
92 static inline void reinsert(int *table, int ub, int value)
94 int i;
96 i = ub & (prime_1 * value);
98 while (table[i] != empty_key)
100 /* possibly the value is already present */
101 if (table[i] == value)
102 return;
104 else
105 i = ub & (i + prime_2);
108 table[i] = value;
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)
116 return TRUE;
118 else
119 i = ub & (i + prime_2);
121 table[i] = value;
122 return FALSE;
125 static void rehash(hash_set hs)
127 int *old_table;
128 int old_capacity, i;
130 old_table = hs->table;
131 old_capacity = hs->capacity;
132 hs->capacity *= 2;
133 hs->ub = UB(++hs->size);
134 hs->table = (int *)calloc(hs->capacity, sizeof(int));
135 assert(hs->table);
138 for (i = 0; i < old_capacity; i++)
140 reinsert(hs->table, hs->ub, old_table[i]);
143 free(old_table);
146 static void post_insert(hash_set hs)
148 float percent_full;
150 int capacity = hs->capacity;
151 int inserts = ++hs->inserts;
153 printf("%d,%d->%f\n",inserts,capacity,percent_full);
154 assert(capacity);
155 percent_full = (float) inserts / capacity;
158 if (percent_full != percent_full)
160 assert (0);
163 if (percent_full >= .85)
164 rehash(hs);
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)
181 rehash(hs);
187 bool hs_query(hash_set hs, int entry)
189 int hash;
190 int ub = hs->ub;
192 hash = ub & (prime_1 * abs(entry));
193 return member(hs->table, ub, hash, entry);
196 bool hs_member(hash_set hs, int entry)
198 int hash;
199 int ub = hs->ub;
201 hash = ub & (prime_1 * abs(entry));
202 if (member_or_insert(hs->table, ub, hash, entry))
203 return TRUE;
205 else
207 post_insert(hs);
208 return FALSE;
212 void hs_delete(hash_set hs)
214 free(hs->table);