1 /*******************************************************************************
2 * Copyright (c) 2000, 2009 IBM Corporation and others.
3 *
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
8 *
9 * SPDX-License-Identifier: EPL-2.0
10 *
11 * Contributors:
12 * IBM Corporation - initial API and implementation
13 *******************************************************************************/
14 package org.eclipse.jdt.internal.compiler.util;
15
16 /**
17 * Hashtable for non-zero long keys.
18 */
19
20 public final class HashtableOfLong {
21 // to avoid using Enumerations, walk the individual tables skipping nulls
22 public long[] keyTable;
23 public Object[] valueTable;
24
25 public int elementSize; // number of elements in the table
26 int threshold;
HashtableOfLong()27 public HashtableOfLong() {
28 this(13);
29 }
HashtableOfLong(int size)30 public HashtableOfLong(int size) {
31 this.elementSize = 0;
32 this.threshold = size; // size represents the expected number of elements
33 int extraRoom = (int) (size * 1.75f);
34 if (this.threshold == extraRoom)
35 extraRoom++;
36 this.keyTable = new long[extraRoom];
37 this.valueTable = new Object[extraRoom];
38 }
containsKey(long key)39 public boolean containsKey(long key) {
40 int length = this.keyTable.length,
41 index = ((int)(key >>> 32)) % length;
42 long currentKey;
43 while ((currentKey = this.keyTable[index]) != 0) {
44 if (currentKey == key)
45 return true;
46 if (++index == length) {
47 index = 0;
48 }
49 }
50 return false;
51 }
get(long key)52 public Object get(long key) {
53 int length = this.keyTable.length,
54 index = ((int)(key >>> 32)) % length;
55 long currentKey;
56 while ((currentKey = this.keyTable[index]) != 0) {
57 if (currentKey == key) return this.valueTable[index];
58 if (++index == length) {
59 index = 0;
60 }
61 }
62 return null;
63 }
put(long key, Object value)64 public Object put(long key, Object value) {
65 int length = this.keyTable.length,
66 index = ((int)(key >>> 32)) % length;
67 long currentKey;
68 while ((currentKey = this.keyTable[index]) != 0) {
69 if (currentKey == key) return this.valueTable[index] = value;
70 if (++index == length) {
71 index = 0;
72 }
73 }
74 this.keyTable[index] = key;
75 this.valueTable[index] = value;
76
77 // assumes the threshold is never equal to the size of the table
78 if (++this.elementSize > this.threshold)
79 rehash();
80 return value;
81 }
rehash()82 private void rehash() {
83 HashtableOfLong newHashtable = new HashtableOfLong(this.elementSize * 2); // double the number of expected elements
84 long currentKey;
85 for (int i = this.keyTable.length; --i >= 0;)
86 if ((currentKey = this.keyTable[i]) != 0)
87 newHashtable.put(currentKey, this.valueTable[i]);
88
89 this.keyTable = newHashtable.keyTable;
90 this.valueTable = newHashtable.valueTable;
91 this.threshold = newHashtable.threshold;
92 }
size()93 public int size() {
94 return this.elementSize;
95 }
96 @Override
toString()97 public String toString() {
98 String s = ""; //$NON-NLS-1$
99 Object object;
100 for (int i = 0, length = this.valueTable.length; i < length; i++)
101 if ((object = this.valueTable[i]) != null)
102 s += this.keyTable[i] + " -> " + object.toString() + "\n"; //$NON-NLS-2$ //$NON-NLS-1$
103 return s;
104 }
105 }
106