1 /*
2 * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
268 // This is a regular bucket, which has more than one
269 // entries. Each entry is a pair of entry (hash, offset).
270 // Seek until the end of the bucket.
271 u4* entry_max = _entries + BUCKET_OFFSET(_buckets[index + 1]);
272 while (entry < entry_max) {
273 unsigned int h = (unsigned int)(entry[0]);
274 if (h == hash) {
275 V value = decode(entry[1]);
276 if (EQUALS(value, key, len)) {
277 return value;
278 }
279 }
280 entry += 2;
281 }
282 }
283 }
284 return nullptr;
285 }
286
287 template <class ITER>
288 inline void iterate(ITER* iter) const {
289 for (u4 i = 0; i < _bucket_count; i++) {
290 u4 bucket_info = _buckets[i];
291 u4 bucket_offset = BUCKET_OFFSET(bucket_info);
292 int bucket_type = BUCKET_TYPE(bucket_info);
293 u4* entry = _entries + bucket_offset;
294
295 if (bucket_type == VALUE_ONLY_BUCKET_TYPE) {
296 iter->do_value(decode(entry[0]));
297 } else {
298 u4*entry_max = _entries + BUCKET_OFFSET(_buckets[i + 1]);
299 while (entry < entry_max) {
300 iter->do_value(decode(entry[1]));
301 entry += 2;
302 }
303 }
304 }
305 }
306
307 void print_table_statistics(outputStream* st, const char* name) {
308 st->print_cr("%s statistics:", name);
309 int total_entries = 0;
310 int max_bucket = 0;
311 for (u4 i = 0; i < _bucket_count; i++) {
312 u4 bucket_info = _buckets[i];
313 int bucket_type = BUCKET_TYPE(bucket_info);
314 int bucket_size;
315
316 if (bucket_type == VALUE_ONLY_BUCKET_TYPE) {
317 bucket_size = 1;
318 } else {
319 bucket_size = (BUCKET_OFFSET(_buckets[i + 1]) - BUCKET_OFFSET(bucket_info)) / 2;
320 }
|
1 /*
2 * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
268 // This is a regular bucket, which has more than one
269 // entries. Each entry is a pair of entry (hash, offset).
270 // Seek until the end of the bucket.
271 u4* entry_max = _entries + BUCKET_OFFSET(_buckets[index + 1]);
272 while (entry < entry_max) {
273 unsigned int h = (unsigned int)(entry[0]);
274 if (h == hash) {
275 V value = decode(entry[1]);
276 if (EQUALS(value, key, len)) {
277 return value;
278 }
279 }
280 entry += 2;
281 }
282 }
283 }
284 return nullptr;
285 }
286
287 template <class ITER>
288 inline void iterate(ITER* iter) const { iterate([&](V v) { iter->do_value(v); }); }
289
290 template<typename Function>
291 inline void iterate(const Function& function) const { // lambda enabled API
292 iterate(const_cast<Function&>(function));
293 }
294
295 template<typename Function>
296 inline void iterate(Function& function) const { // lambda enabled API
297 for (u4 i = 0; i < _bucket_count; i++) {
298 u4 bucket_info = _buckets[i];
299 u4 bucket_offset = BUCKET_OFFSET(bucket_info);
300 int bucket_type = BUCKET_TYPE(bucket_info);
301 u4* entry = _entries + bucket_offset;
302
303 if (bucket_type == VALUE_ONLY_BUCKET_TYPE) {
304 function(decode(entry[0]));
305 } else {
306 u4* entry_max = _entries + BUCKET_OFFSET(_buckets[i + 1]);
307 while (entry < entry_max) {
308 function(decode(entry[1]));
309 entry += 2;
310 }
311 }
312 }
313 }
314
315 void print_table_statistics(outputStream* st, const char* name) {
316 st->print_cr("%s statistics:", name);
317 int total_entries = 0;
318 int max_bucket = 0;
319 for (u4 i = 0; i < _bucket_count; i++) {
320 u4 bucket_info = _buckets[i];
321 int bucket_type = BUCKET_TYPE(bucket_info);
322 int bucket_size;
323
324 if (bucket_type == VALUE_ONLY_BUCKET_TYPE) {
325 bucket_size = 1;
326 } else {
327 bucket_size = (BUCKET_OFFSET(_buckets[i + 1]) - BUCKET_OFFSET(bucket_info)) / 2;
328 }
|