@@ -47,7 +47,7 @@ final static class Small extends CompactStringObjectMap
47
47
protected final String key1 , key2 ;
48
48
protected final Object value1 , value2 ;
49
49
50
- private Small (Map .Entry <String ,?> e1 , Map .Entry <String ,?> e2 )
50
+ public Small (Map .Entry <String ,?> e1 , Map .Entry <String ,?> e2 )
51
51
{
52
52
if (e1 == null ) {
53
53
key1 = null ;
@@ -99,15 +99,13 @@ final static class Big extends CompactStringObjectMap
99
99
{
100
100
private final int _hashMask , _spillCount ;
101
101
102
- private final String [] _keys ;
103
- private final Object [] _values ;
102
+ private final Object [] _hashArea ;
104
103
105
- private Big (int hashMask , int spillCount , String [] keys , Object [] fields )
104
+ private Big (int hashMask , int spillCount , Object [] hashArea )
106
105
{
107
106
_hashMask = hashMask ;
108
107
_spillCount = spillCount ;
109
- _keys = keys ;
110
- _values = fields ;
108
+ _hashArea = hashArea ;
111
109
}
112
110
113
111
public static <T > Big construct (Map <String ,T > all )
@@ -116,34 +114,33 @@ public static <T> Big construct(Map<String,T> all)
116
114
final int size = findSize (all .size ());
117
115
final int mask = size -1 ;
118
116
// and allocate enough to contain primary/secondary, expand for spillovers as need be
119
- int alloc = size + (size >>1 );
120
- String [] keys = new String [alloc ];
121
- Object [] fieldHash = new Object [alloc ];
122
- int spills = 0 ;
117
+ int alloc = (size + (size >>1 )) * 2 ;
118
+ Object [] hashArea = new Object [alloc ];
119
+ int spillCount = 0 ;
123
120
124
121
for (Map .Entry <String ,T > entry : all .entrySet ()) {
125
122
String key = entry .getKey ();
126
123
127
124
int slot = key .hashCode () & mask ;
125
+ int ix = slot +slot ;
128
126
129
127
// primary slot not free?
130
- if (keys [ slot ] != null ) {
128
+ if (hashArea [ ix ] != null ) {
131
129
// secondary?
132
- slot = size + (slot >> 1 );
133
- if (keys [ slot ] != null ) {
130
+ ix = ( size + (slot >> 1 )) << 1 ;
131
+ if (hashArea [ ix ] != null ) {
134
132
// ok, spill over.
135
- slot = size + (size >> 1 ) + spills ;
136
- ++spills ;
137
- if (slot >= keys .length ) {
138
- keys = Arrays .copyOf (keys , keys .length + 4 );
139
- fieldHash = Arrays .copyOf (fieldHash , fieldHash .length + 4 );
133
+ ix = ((size + (size >> 1 ) ) << 1 ) + spillCount ;
134
+ spillCount += 2 ;
135
+ if (ix >= hashArea .length ) {
136
+ hashArea = Arrays .copyOf (hashArea , hashArea .length + 4 );
140
137
}
141
138
}
142
139
}
143
- keys [ slot ] = key ;
144
- fieldHash [ slot ] = entry .getValue ();
140
+ hashArea [ ix ] = key ;
141
+ hashArea [ ix + 1 ] = entry .getValue ();
145
142
}
146
- return new Big (mask , spills , keys , fieldHash );
143
+ return new Big (mask , spillCount , hashArea );
147
144
}
148
145
149
146
private final static int findSize (int size )
@@ -161,47 +158,52 @@ private final static int findSize(int size)
161
158
}
162
159
return result ;
163
160
}
164
-
161
+
165
162
@ Override
166
163
public Object find (String key ) {
167
164
int slot = key .hashCode () & _hashMask ;
168
- String match = _keys [slot ];
165
+ int ix = (slot <<1 );
166
+ Object match = _hashArea [ix ];
169
167
if ((match == key ) || key .equals (match )) {
170
- return _values [ slot ];
168
+ return _hashArea [ ix + 1 ];
171
169
}
170
+ return _find2 (key , slot , match );
171
+ }
172
+
173
+ private final Object _find2 (String key , int slot , Object match )
174
+ {
172
175
if (match == null ) {
173
176
return null ;
174
177
}
175
- // no? secondary?
176
- slot = ( _hashMask + 1 ) + (slot >>1 );
177
- match = _keys [ slot ];
178
+ int hashSize = _hashMask + 1 ;
179
+ int ix = hashSize + (slot >>1 ) << 1 ;
180
+ match = _hashArea [ ix ];
178
181
if (key .equals (match )) {
179
- return _values [ slot ];
182
+ return _hashArea [ ix + 1 ];
180
183
}
181
- // or spill?
182
- return _findFromSpill (key );
183
- }
184
-
185
- private Object _findFromSpill (String key ) {
186
- int hashSize = _hashMask +1 ;
187
- int i = hashSize + (hashSize >>1 );
188
- for (int end = i + _spillCount ; i < end ; ++i ) {
189
- if (key .equals (_keys [i ])) {
190
- return _values [i ];
184
+ if (match != null ) { // _findFromSpill(...)
185
+ int i = (hashSize + (hashSize >>1 )) << 1 ;
186
+ for (int end = i + _spillCount ; i < end ; i += 2 ) {
187
+ match = _hashArea [i ];
188
+ if ((match == key ) || key .equals (match )) {
189
+ return _hashArea [i +1 ];
190
+ }
191
191
}
192
192
}
193
193
return null ;
194
194
}
195
195
196
196
@ Override
197
197
public List <String > keys () {
198
- List <String > keys = new ArrayList <String >(_keys .length >> 1 );
199
- for (String key : _keys ) {
198
+ final int end = _hashArea .length ;
199
+ List <String > keys = new ArrayList <String >(end >> 2 );
200
+ for (int i = 0 ; i < end ; i += 2 ) {
201
+ Object key = _hashArea [i ];
200
202
if (key != null ) {
201
- keys .add (key );
203
+ keys .add (( String ) key );
202
204
}
203
205
}
204
206
return keys ;
205
207
}
206
- }
208
+ }
207
209
}
0 commit comments