2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * $XConsortium: bucket.cc /main/3 1996/06/11 17:18:55 cde-hal $
26 * Copyright (c) 1992 HaL Computer Systems, Inc. All rights reserved.
27 * UNPUBLISHED -- rights reserved under the Copyright Laws of the United
28 * States. Use of a copyright notice is precautionary only and does not
29 * imply publication or disclosure.
31 * This software contains confidential information and trade secrets of HaL
32 * Computer Systems, Inc. Use, disclosure, or reproduction is prohibited
33 * without the prior express written permission of HaL Computer Systems, Inc.
35 * RESTRICTED RIGHTS LEGEND
36 * Use, duplication, or disclosure by the Government is subject to
37 * restrictions as set forth in subparagraph (c)(l)(ii) of the Rights in
38 * Technical Data and Computer Software clause at DFARS 252.227-7013.
39 * HaL Computer Systems, Inc.
40 * 1315 Dell Avenue, Campbell, CA 95008
45 #include "dynhash/bucket.h"
47 int bucket::upper_limit;
49 bucket::bucket(int new_Mj, int owj) : wj(0), Mj(new_Mj), old_wj(owj)
52 data_array = new data_t[2*Mj*Mj];
57 delete [2 * Mj * Mj] data_array;
60 /***********************************************/
61 // rehash the existing keys and the new key
63 /***********************************************/
64 void bucket::rehash_all(data_t& data, shared_t& sh)
69 sh.internal_L[j++] = (*this)(ind);
70 data_array[ind].marked = false;
73 sh.internal_L[j] = data;
77 for ( ind = 0; ind <= j; ind++ ) {
78 int hash = h(sh.internal_L[ind].key, sh);
79 data_array[hash] = sh.internal_L[ind];
80 data_array[hash].marked = true;
84 /****************************************/
85 // select a proper value for parameter k
86 // sh contains useful variables from the
87 // first level hash table.
88 /****************************************/
89 void bucket::select_h_params(shared_t& sh)
91 Boolean injective = false;
94 /******************************************/
95 // loop until an injective mapping is found
96 /******************************************/
98 while ( injective == false ) {
99 k = sh.rand_generator.rand() % (sh.p - 1) + 1;
101 for ( int i=0; i<wj; i++ ) {
102 int hash = h( sh.internal_L[i].key, sh );
103 if ( data_array[hash].marked == false ) {
104 data_array[hash].marked = true ;
106 for ( int j = 0; j<2*Mj*Mj; j++ )
107 data_array[j].marked = false;
113 if ( loops >= 20 ) { // supposedly loop twice
118 for ( int i=0; i<wj; i++ ) {
119 int hash = h( sh.internal_L[i].key, sh );
120 debug(cerr, sh.internal_L[i]);
123 throw(boundaryException(1, 20, loops));
128 /************************************************/
130 /************************************************/
131 Boolean bucket::insert(data_t& data, shared_t& sh)
134 int j = h(data.key, sh);
138 /**********************/
140 /**********************/
142 if ( data_array[j].marked == false ) {
143 data_array[j] = data;
144 data_array[j].marked = true;
146 if ( data_array[j].key == data.key) {
147 debug(cerr, data_array[j]);
149 MESSAGE(cerr, "key is in the set");
152 rehash_all(data, sh);
157 /***************************/
158 // need to double the space
159 // debug(cerr, "rehash bucket");
160 // debug(cerr, data.key);
161 /***************************/
163 int old_contribute = 2 * old_wj * old_wj;
164 int new_contribute = 2 * wj * wj;
165 if ( sh.sum - old_contribute + new_contribute < sh.limit ) {
167 /**************************************/
168 // if condition 4 holds, we just rehash
169 // keys in this table
170 /**************************************/
171 sh.sum -= old_contribute;
172 sh.sum += new_contribute;
175 data_t *x = new data_t[8*Mj*Mj];
179 /********************/
181 /********************/
182 while ( ind != -1 ) {
183 x[ind] = (*this)(ind);
187 /*****************************/
188 // allocate new space
189 /*****************************/
190 delete [2*Mj*Mj] data_array;
195 /*****************************/
196 // re-hash keys in this bucket
197 /*****************************/
198 rehash_all(data, sh);
203 /*******************************/
204 // Condition 4 does not hold.
205 // Return false to signal a
206 // entire set re-hash.
207 /*******************************/
213 /*******************************/
214 // compute the hash value
215 /*******************************/
216 int bucket::h(int key, shared_t& sh)
218 return ( (abs( k * key )) % (sh.p) ) % (2 * Mj * Mj);
221 /*******************************/
223 /*******************************/
224 Boolean bucket::member(data_t& data, shared_t& sh)
226 int pos = h( data.key, sh );
227 if ( data_array[pos].marked == true ) {
228 data.dt = data_array[pos].dt;
230 if ( data_array[pos].key == data.key )
241 /*******************************/
243 /*******************************/
244 Boolean bucket::remove(data_t& data, shared_t& sh)
246 int pos = h( data.key, sh );
248 if ( data_array[pos].marked == true &&
249 data_array[pos].key == data.key) {
251 data_array[pos].marked = false;
256 MESSAGE(cerr, "+++++++++++++++");
260 debug(cerr, data_array[pos]);
261 MESSAGE(cerr, "data is not in the key set");
262 MESSAGE(cerr, "+++++++++++++++");
267 /***********************************************/
268 // iteration operations
269 /***********************************************/
272 upper_limit = 2 * Mj * Mj;
277 while ( data_array[i].marked == false ) {
278 if ( i >= upper_limit ) {
280 debug(cerr, upper_limit);
281 throw(stringException("hash table is in inconsistent status"));
289 data_t& bucket::operator()(int ind)
291 return data_array[ind];
294 void bucket::next(int& ind)
296 for ( int j = ind+1; j < upper_limit; j ++ )
297 if ( data_array[j].marked == true ) {
305 /***********************************************/
307 /***********************************************/
308 ostream& operator<<(ostream& out, bucket& bt)
310 int ind = bt.first();
311 while ( ind != -1 ) {