@@ -47,7 +47,7 @@ final static class Small extends CompactStringObjectMap
4747 protected final String key1 , key2 ;
4848 protected final Object value1 , value2 ;
4949
50- private Small (Map .Entry <String ,?> e1 , Map .Entry <String ,?> e2 )
50+ public Small (Map .Entry <String ,?> e1 , Map .Entry <String ,?> e2 )
5151 {
5252 if (e1 == null ) {
5353 key1 = null ;
@@ -99,15 +99,13 @@ final static class Big extends CompactStringObjectMap
9999 {
100100 private final int _hashMask , _spillCount ;
101101
102- private final String [] _keys ;
103- private final Object [] _values ;
102+ private final Object [] _hashArea ;
104103
105- private Big (int hashMask , int spillCount , String [] keys , Object [] fields )
104+ private Big (int hashMask , int spillCount , Object [] hashArea )
106105 {
107106 _hashMask = hashMask ;
108107 _spillCount = spillCount ;
109- _keys = keys ;
110- _values = fields ;
108+ _hashArea = hashArea ;
111109 }
112110
113111 public static <T > Big construct (Map <String ,T > all )
@@ -116,34 +114,33 @@ public static <T> Big construct(Map<String,T> all)
116114 final int size = findSize (all .size ());
117115 final int mask = size -1 ;
118116 // 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 ;
123120
124121 for (Map .Entry <String ,T > entry : all .entrySet ()) {
125122 String key = entry .getKey ();
126123
127124 int slot = key .hashCode () & mask ;
125+ int ix = slot +slot ;
128126
129127 // primary slot not free?
130- if (keys [ slot ] != null ) {
128+ if (hashArea [ ix ] != null ) {
131129 // secondary?
132- slot = size + (slot >> 1 );
133- if (keys [ slot ] != null ) {
130+ ix = ( size + (slot >> 1 )) << 1 ;
131+ if (hashArea [ ix ] != null ) {
134132 // 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 );
140137 }
141138 }
142139 }
143- keys [ slot ] = key ;
144- fieldHash [ slot ] = entry .getValue ();
140+ hashArea [ ix ] = key ;
141+ hashArea [ ix + 1 ] = entry .getValue ();
145142 }
146- return new Big (mask , spills , keys , fieldHash );
143+ return new Big (mask , spillCount , hashArea );
147144 }
148145
149146 private final static int findSize (int size )
@@ -161,47 +158,52 @@ private final static int findSize(int size)
161158 }
162159 return result ;
163160 }
164-
161+
165162 @ Override
166163 public Object find (String key ) {
167164 int slot = key .hashCode () & _hashMask ;
168- String match = _keys [slot ];
165+ int ix = (slot <<1 );
166+ Object match = _hashArea [ix ];
169167 if ((match == key ) || key .equals (match )) {
170- return _values [ slot ];
168+ return _hashArea [ ix + 1 ];
171169 }
170+ return _find2 (key , slot , match );
171+ }
172+
173+ private final Object _find2 (String key , int slot , Object match )
174+ {
172175 if (match == null ) {
173176 return null ;
174177 }
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 ];
178181 if (key .equals (match )) {
179- return _values [ slot ];
182+ return _hashArea [ ix + 1 ];
180183 }
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+ }
191191 }
192192 }
193193 return null ;
194194 }
195195
196196 @ Override
197197 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 ];
200202 if (key != null ) {
201- keys .add (key );
203+ keys .add (( String ) key );
202204 }
203205 }
204206 return keys ;
205207 }
206- }
208+ }
207209}
0 commit comments