1
1
/*
2
- * Copyright (c) 1997, 2018 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 1997, 2020 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,7 @@ static const short xsum[MAXID] = {3,8,17,34,67,132,261,264,269,278,295,328,393,5
47
47
class bucket : public ResourceObj {
48
48
public:
49
49
uint _cnt, _max; // Size of bucket
50
- void ** _keyvals; // Array of keys and values
50
+ void ** _keyvals; // Array of keys and values
51
51
};
52
52
53
53
// ------------------------------Dict-----------------------------------------
@@ -64,75 +64,70 @@ Dict::Dict(CmpKey initcmp, Hash inithash) : _arena(Thread::current()->resource_a
64
64
65
65
_size = 16 ; // Size is a power of 2
66
66
_cnt = 0 ; // Dictionary is empty
67
- _bin = (bucket*)_arena->Amalloc_4 (sizeof (bucket)* _size);
68
- memset ((void *)_bin,0 , sizeof (bucket)* _size);
67
+ _bin = (bucket*)_arena->Amalloc_4 (sizeof (bucket) * _size);
68
+ memset ((void *)_bin, 0 , sizeof (bucket) * _size);
69
69
}
70
70
71
- Dict::Dict (CmpKey initcmp, Hash inithash, Arena * arena, int size)
71
+ Dict::Dict (CmpKey initcmp, Hash inithash, Arena* arena, int size)
72
72
: _arena(arena), _hash(inithash), _cmp(initcmp) {
73
73
// Size is a power of 2
74
74
_size = MAX2 (16 , round_up_power_of_2 (size));
75
75
76
76
_cnt = 0 ; // Dictionary is empty
77
- _bin = (bucket*)_arena->Amalloc_4 (sizeof (bucket)* _size);
78
- memset ((void *)_bin,0 , sizeof (bucket)* _size);
77
+ _bin = (bucket*)_arena->Amalloc_4 (sizeof (bucket) * _size);
78
+ memset ((void *)_bin, 0 , sizeof (bucket) * _size);
79
79
}
80
80
81
- // ------------------------------~Dict------------------------------------------
82
- // Delete an existing dictionary.
83
- Dict::~Dict () {
84
- /*
85
- tty->print("~Dict %d/%d: ",_cnt,_size);
86
- for( uint i=0; i < _size; i++) // For complete new table do
87
- tty->print("%d ",_bin[i]._cnt);
88
- tty->print("\n");*/
89
- /* for( uint i=0; i<_size; i++ ) {
90
- FREE_FAST( _bin[i]._keyvals );
91
- } */
81
+ // Deep copy into arena of choice
82
+ Dict::Dict (const Dict &d, Arena* arena)
83
+ : _arena(arena), _size(d._size), _cnt(d._cnt), _hash(d._hash), _cmp(d._cmp) {
84
+ _bin = (bucket*)_arena->Amalloc_4 (sizeof (bucket) * _size);
85
+ memcpy ((void *)_bin, (void *)d._bin , sizeof (bucket) * _size);
86
+ for (uint i = 0 ; i < _size; i++) {
87
+ if (!_bin[i]._keyvals ) {
88
+ continue ;
89
+ }
90
+ _bin[i]._keyvals = (void **)_arena->Amalloc_4 (sizeof (void *) * _bin[i]._max * 2 );
91
+ memcpy (_bin[i]._keyvals , d._bin [i]._keyvals , _bin[i]._cnt * 2 * sizeof (void *));
92
+ }
92
93
}
93
94
94
- // ------------------------------Clear----------------------------------------
95
- // Zap to empty; ready for re-use
96
- void Dict::Clear () {
97
- _cnt = 0 ; // Empty contents
98
- for ( uint i=0 ; i<_size; i++ )
99
- _bin[i]._cnt = 0 ; // Empty buckets, but leave allocated
100
- // Leave _size & _bin alone, under the assumption that dictionary will
101
- // grow to this size again.
102
- }
95
+ // ------------------------------~Dict------------------------------------------
96
+ // Delete an existing dictionary.
97
+ Dict::~Dict () { }
103
98
104
99
// ------------------------------doubhash---------------------------------------
105
100
// Double hash table size. If can't do so, just suffer. If can, then run
106
101
// thru old hash table, moving things to new table. Note that since hash
107
102
// table doubled, exactly 1 new bit is exposed in the mask - so everything
108
103
// in the old table ends up on 1 of two lists in the new table; a hi and a
109
104
// lo list depending on the value of the bit.
110
- void Dict::doubhash (void ) {
105
+ void Dict::doubhash () {
111
106
uint oldsize = _size;
112
107
_size <<= 1 ; // Double in size
113
108
_bin = (bucket*)_arena->Arealloc (_bin, sizeof (bucket) * oldsize, sizeof (bucket) * _size);
114
109
memset ((void *)(&_bin[oldsize]), 0 , oldsize * sizeof (bucket));
115
110
// Rehash things to spread into new table
116
111
for (uint i = 0 ; i < oldsize; i++) { // For complete OLD table do
117
- bucket * b = &_bin[i]; // Handy shortcut for _bin[i]
112
+ bucket* b = &_bin[i]; // Handy shortcut for _bin[i]
118
113
if (!b->_keyvals ) continue ; // Skip empties fast
119
114
120
- bucket * nb = &_bin[i+oldsize]; // New bucket shortcut
115
+ bucket* nb = &_bin[i+oldsize]; // New bucket shortcut
121
116
uint j = b->_max ; // Trim new bucket to nearest power of 2
122
117
while (j > b->_cnt ) { j >>= 1 ; } // above old bucket _cnt
123
118
if (!j) { j = 1 ; } // Handle zero-sized buckets
124
119
nb->_max = j << 1 ;
125
120
// Allocate worst case space for key-value pairs
126
- nb->_keyvals = (void **)_arena->Amalloc_4 (sizeof (void * ) * nb->_max * 2 );
121
+ nb->_keyvals = (void **)_arena->Amalloc_4 (sizeof (void * ) * nb->_max * 2 );
127
122
uint nbcnt = 0 ;
128
123
129
- for (j = 0 ; j < b->_cnt ; ) { // Rehash all keys in this bucket
130
- void * key = b->_keyvals [j + j];
124
+ for (j = 0 ; j < b->_cnt ;) { // Rehash all keys in this bucket
125
+ void * key = b->_keyvals [j + j];
131
126
if ((_hash (key) & (_size-1 )) != i) { // Moving to hi bucket?
132
127
nb->_keyvals [nbcnt + nbcnt] = key;
133
128
nb->_keyvals [nbcnt + nbcnt + 1 ] = b->_keyvals [j + j + 1 ];
134
129
nb->_cnt = nbcnt = nbcnt + 1 ;
135
- b->_cnt --; // Remove key/value from lo bucket
130
+ b->_cnt --; // Remove key/value from lo bucket
136
131
b->_keyvals [j + j] = b->_keyvals [b->_cnt + b->_cnt ];
137
132
b->_keyvals [j + j + 1 ] = b->_keyvals [b->_cnt + b->_cnt + 1 ];
138
133
// Don't increment j, hash compacted element also.
@@ -143,135 +138,86 @@ void Dict::doubhash(void) {
143
138
} // End of for all buckets
144
139
}
145
140
146
- // ------------------------------Dict-----------------------------------------
147
- // Deep copy a dictionary.
148
- Dict::Dict ( const Dict &d ) : ResourceObj(d), _arena(d._arena), _size(d._size), _cnt(d._cnt), _hash(d._hash), _cmp(d._cmp) {
149
- _bin = (bucket*)_arena->Amalloc_4 (sizeof (bucket)*_size);
150
- memcpy ( (void *)_bin, (void *)d._bin , sizeof (bucket)*_size );
151
- for ( uint i=0 ; i<_size; i++ ) {
152
- if ( !_bin[i]._keyvals ) continue ;
153
- _bin[i]._keyvals =(void **)_arena->Amalloc_4 ( sizeof (void *)*_bin[i]._max *2 );
154
- memcpy ( _bin[i]._keyvals , d._bin [i]._keyvals ,_bin[i]._cnt *2 *sizeof (void *));
155
- }
156
- }
157
-
158
- // ------------------------------Dict-----------------------------------------
159
- // Deep copy a dictionary.
160
- Dict &Dict::operator =( const Dict &d ) {
161
- if ( _size < d._size ) { // If must have more buckets
162
- _arena = d._arena ;
163
- _bin = (bucket*)_arena->Arealloc ( _bin, sizeof (bucket)*_size, sizeof (bucket)*d._size );
164
- memset ( (void *)(&_bin[_size]), 0 , (d._size -_size)*sizeof (bucket) );
165
- _size = d._size ;
166
- }
167
- uint i;
168
- for ( i=0 ; i<_size; i++ ) // All buckets are empty
169
- _bin[i]._cnt = 0 ; // But leave bucket allocations alone
170
- _cnt = d._cnt ;
171
- *(Hash*)(&_hash) = d._hash ;
172
- *(CmpKey*)(&_cmp) = d._cmp ;
173
- for ( i=0 ; i<_size; i++ ) {
174
- bucket *b = &d._bin [i]; // Shortcut to source bucket
175
- for ( uint j=0 ; j<b->_cnt ; j++ )
176
- Insert ( b->_keyvals [j+j], b->_keyvals [j+j+1 ] );
177
- }
178
- return *this ;
179
- }
180
-
181
141
// ------------------------------Insert----------------------------------------
182
142
// Insert or replace a key/value pair in the given dictionary. If the
183
143
// dictionary is too full, it's size is doubled. The prior value being
184
144
// replaced is returned (NULL if this is a 1st insertion of that key). If
185
145
// an old value is found, it's swapped with the prior key-value pair on the
186
146
// list. This moves a commonly searched-for value towards the list head.
187
- void *Dict::Insert (void * key, void * val, bool replace) {
188
- uint hash = _hash ( key ); // Get hash key
189
- uint i = hash & (_size- 1 ); // Get hash key, corrected for size
190
- bucket * b = &_bin[i]; // Handy shortcut
191
- for ( uint j= 0 ; j< b->_cnt ; j++ ) {
192
- if ( !_cmp (key,b->_keyvals [j+ j]) ) {
147
+ void *Dict::Insert (void * key, void * val, bool replace) {
148
+ uint hash = _hash (key); // Get hash key
149
+ uint i = hash & (_size - 1 ); // Get hash key, corrected for size
150
+ bucket* b = &_bin[i];
151
+ for ( uint j = 0 ; j < b->_cnt ; j++) {
152
+ if ( !_cmp (key, b->_keyvals [j + j])) {
193
153
if (!replace) {
194
- return b->_keyvals [j+j+ 1 ];
154
+ return b->_keyvals [j + j + 1 ];
195
155
} else {
196
- void * prior = b->_keyvals [j+j+ 1 ];
197
- b->_keyvals [j+ j ] = key; // Insert current key-value
198
- b->_keyvals [j+j+ 1 ] = val;
199
- return prior; // Return prior
156
+ void * prior = b->_keyvals [j + j + 1 ];
157
+ b->_keyvals [j + j ] = key;
158
+ b->_keyvals [j + j + 1 ] = val;
159
+ return prior;
200
160
}
201
161
}
202
162
}
203
- if ( ++_cnt > _size ) { // Hash table is full
163
+ if ( ++_cnt > _size) { // Hash table is full
204
164
doubhash (); // Grow whole table if too full
205
- i = hash & (_size- 1 ); // Rehash
206
- b = &_bin[i]; // Handy shortcut
165
+ i = hash & (_size - 1 ); // Rehash
166
+ b = &_bin[i];
207
167
}
208
- if ( b->_cnt == b->_max ) { // Must grow bucket?
209
- if ( !b->_keyvals ) {
168
+ if ( b->_cnt == b->_max ) { // Must grow bucket?
169
+ if ( !b->_keyvals ) {
210
170
b->_max = 2 ; // Initial bucket size
211
171
b->_keyvals = (void **)_arena->Amalloc_4 (sizeof (void *) * b->_max * 2 );
212
172
} else {
213
173
b->_keyvals = (void **)_arena->Arealloc (b->_keyvals , sizeof (void *) * b->_max * 2 , sizeof (void *) * b->_max * 4 );
214
174
b->_max <<= 1 ; // Double bucket
215
175
}
216
176
}
217
- b->_keyvals [b->_cnt + b->_cnt ] = key;
218
- b->_keyvals [b->_cnt + b->_cnt + 1 ] = val;
177
+ b->_keyvals [b->_cnt + b->_cnt ] = key;
178
+ b->_keyvals [b->_cnt + b->_cnt + 1 ] = val;
219
179
b->_cnt ++;
220
180
return NULL ; // Nothing found prior
221
181
}
222
182
223
183
// ------------------------------Delete---------------------------------------
224
184
// Find & remove a value from dictionary. Return old value.
225
- void * Dict::Delete (void * key) {
226
- uint i = _hash ( key ) & (_size- 1 ); // Get hash key, corrected for size
227
- bucket * b = &_bin[i]; // Handy shortcut
228
- for ( uint j= 0 ; j< b->_cnt ; j++ )
229
- if ( !_cmp (key,b->_keyvals [j+ j]) ) {
230
- void * prior = b->_keyvals [j+j+ 1 ];
185
+ void * Dict::Delete (void * key) {
186
+ uint i = _hash (key) & (_size - 1 ); // Get hash key, corrected for size
187
+ bucket* b = &_bin[i]; // Handy shortcut
188
+ for ( uint j = 0 ; j < b->_cnt ; j++) {
189
+ if ( !_cmp (key, b->_keyvals [j + j])) {
190
+ void * prior = b->_keyvals [j + j + 1 ];
231
191
b->_cnt --; // Remove key/value from lo bucket
232
- b->_keyvals [j+j ] = b->_keyvals [b->_cnt + b->_cnt ];
233
- b->_keyvals [j+j+1 ] = b->_keyvals [b->_cnt + b->_cnt + 1 ];
192
+ b->_keyvals [j+j ] = b->_keyvals [b->_cnt + b->_cnt ];
193
+ b->_keyvals [j+j+1 ] = b->_keyvals [b->_cnt + b->_cnt + 1 ];
234
194
_cnt--; // One less thing in table
235
195
return prior;
236
196
}
197
+ }
237
198
return NULL ;
238
199
}
239
200
240
201
// ------------------------------FindDict-------------------------------------
241
202
// Find a key-value pair in the given dictionary. If not found, return NULL.
242
203
// If found, move key-value pair towards head of list.
243
- void *Dict::operator [](const void *key) const {
244
- uint i = _hash ( key ) & (_size-1 ); // Get hash key, corrected for size
245
- bucket *b = &_bin[i]; // Handy shortcut
246
- for ( uint j=0 ; j<b->_cnt ; j++ )
247
- if ( !_cmp (key,b->_keyvals [j+j]) )
248
- return b->_keyvals [j+j+1 ];
249
- return NULL ;
250
- }
251
-
252
- // ------------------------------CmpDict--------------------------------------
253
- // CmpDict compares two dictionaries; they must have the same keys (their
254
- // keys must match using CmpKey) and they must have the same values (pointer
255
- // comparison). If so 1 is returned, if not 0 is returned.
256
- int32_t Dict::operator ==(const Dict &d2) const {
257
- if ( _cnt != d2._cnt ) return 0 ;
258
- if ( _hash != d2._hash ) return 0 ;
259
- if ( _cmp != d2._cmp ) return 0 ;
260
- for ( uint i=0 ; i < _size; i++) { // For complete hash table do
261
- bucket *b = &_bin[i]; // Handy shortcut
262
- if ( b->_cnt != d2._bin [i]._cnt ) return 0 ;
263
- if ( memcmp (b->_keyvals , d2._bin [i]._keyvals , b->_cnt *2 *sizeof (void *) ) )
264
- return 0 ; // Key-value pairs must match
204
+ void * Dict::operator [](const void * key) const {
205
+ uint i = _hash (key) & (_size - 1 ); // Get hash key, corrected for size
206
+ bucket* b = &_bin[i]; // Handy shortcut
207
+ for (uint j = 0 ; j < b->_cnt ; j++) {
208
+ if (!_cmp (key, b->_keyvals [j + j])) {
209
+ return b->_keyvals [j + j + 1 ];
210
+ }
265
211
}
266
- return 1 ; // All match, is OK
212
+ return NULL ;
267
213
}
268
214
269
215
// ------------------------------print------------------------------------------
270
216
// Handier print routine
271
217
void Dict::print () {
272
218
DictI i (this ); // Moved definition in iterator here because of g++.
273
219
tty->print (" Dict@" INTPTR_FORMAT " [%d] = {" , p2i (this ), _cnt);
274
- for ( ; i.test (); ++i ) {
220
+ for ( ; i.test (); ++i) {
275
221
tty->print (" (" INTPTR_FORMAT " ," INTPTR_FORMAT " )," , p2i (i._key ), p2i (i._value ));
276
222
}
277
223
tty->print_cr (" }" );
@@ -288,12 +234,12 @@ void Dict::print() {
288
234
// be in the range 0-127 (I double & add 1 to force oddness). Keys are
289
235
// limited to MAXID characters in length. Experimental evidence on 150K of
290
236
// C text shows excellent spreading of values for any size hash table.
291
- int hashstr (const void * t) {
237
+ int hashstr (const void * t) {
292
238
char c, k = 0 ;
293
239
int32_t sum = 0 ;
294
- const char * s = (const char *)t;
240
+ const char * s = (const char *)t;
295
241
296
- while ( ((c = *s++) != ' \0 ' ) && (k < MAXID-1 ) ) { // Get characters till null or MAXID-1
242
+ while ((( c = *s++) != ' \0 ' ) && (k < MAXID-1 )) { // Get characters till null or MAXID-1
297
243
c = (c << 1 ) + 1 ; // Characters are always odd!
298
244
sum += c + (c << shft[k++]); // Universal hash function
299
245
}
@@ -303,33 +249,37 @@ int hashstr(const void *t) {
303
249
// ------------------------------hashptr--------------------------------------
304
250
// Slimey cheap hash function; no guaranteed performance. Better than the
305
251
// default for pointers, especially on MS-DOS machines.
306
- int hashptr (const void * key) {
252
+ int hashptr (const void * key) {
307
253
return ((intptr_t )key >> 2 );
308
254
}
309
255
310
256
// Slimey cheap hash function; no guaranteed performance.
311
- int hashkey (const void * key) {
257
+ int hashkey (const void * key) {
312
258
return (intptr_t )key;
313
259
}
314
260
315
261
// ------------------------------Key Comparator Functions---------------------
316
- int32_t cmpstr (const void * k1, const void * k2) {
317
- return strcmp ((const char *)k1,(const char *)k2);
262
+ int32_t cmpstr (const void * k1, const void * k2) {
263
+ return strcmp ((const char *)k1, (const char *)k2);
318
264
}
319
265
320
266
// Cheap key comparator.
321
- int32_t cmpkey (const void *key1, const void *key2) {
322
- if (key1 == key2) return 0 ;
267
+ int32_t cmpkey (const void * key1, const void * key2) {
268
+ if (key1 == key2) {
269
+ return 0 ;
270
+ }
323
271
intptr_t delta = (intptr_t )key1 - (intptr_t )key2;
324
- if (delta > 0 ) return 1 ;
272
+ if (delta > 0 ) {
273
+ return 1 ;
274
+ }
325
275
return -1 ;
326
276
}
327
277
328
278
// =============================================================================
329
279
// ------------------------------reset------------------------------------------
330
280
// Create an iterator and initialize the first variables.
331
- void DictI::reset ( const Dict *dict ) {
332
- _d = dict; // The dictionary
281
+ void DictI::reset (const Dict* dict ) {
282
+ _d = dict;
333
283
_i = (uint)-1 ; // Before the first bin
334
284
_j = 0 ; // Nothing left in the current bin
335
285
++(*this ); // Step to first real value
@@ -339,15 +289,17 @@ void DictI::reset( const Dict *dict ) {
339
289
// Find the next key-value pair in the dictionary, or return a NULL key and
340
290
// value.
341
291
void DictI::operator ++(void ) {
342
- if ( _j-- ) { // Still working in current bin?
343
- _key = _d->_bin [_i]._keyvals [_j+ _j];
344
- _value = _d->_bin [_i]._keyvals [_j+_j+ 1 ];
292
+ if ( _j--) { // Still working in current bin?
293
+ _key = _d->_bin [_i]._keyvals [_j + _j];
294
+ _value = _d->_bin [_i]._keyvals [_j + _j + 1 ];
345
295
return ;
346
296
}
347
297
348
- while ( ++_i < _d->_size ) { // Else scan for non-zero bucket
298
+ while ( ++_i < _d->_size ) { // Else scan for non-zero bucket
349
299
_j = _d->_bin [_i]._cnt ;
350
- if ( !_j ) continue ;
300
+ if (!_j) {
301
+ continue ;
302
+ }
351
303
_j--;
352
304
_key = _d->_bin [_i]._keyvals [_j+_j];
353
305
_value = _d->_bin [_i]._keyvals [_j+_j+1 ];
0 commit comments