@@ -93,7 +93,7 @@ class LinkedHashMap[K, V]
93
93
}
94
94
override def sizeHint (size : Int ): Unit = {
95
95
val target = tableSizeFor(((size + 1 ).toDouble / LinkedHashMap .defaultLoadFactor).toInt)
96
- if (target > table.length) growTable(target)
96
+ if (target > table.length) growTable(target)
97
97
}
98
98
99
99
override def contains (key : K ): Boolean = {
@@ -131,23 +131,23 @@ class LinkedHashMap[K, V]
131
131
// subclasses of LinkedHashMap might customise `get` ...
132
132
super .getOrElseUpdate(key, defaultValue)
133
133
} else {
134
- val hash = computeHash(key)
135
- val idx = index(hash)
136
- val nd = table(idx) match {
137
- case null => null
138
- case nd => nd.findEntry(key, hash)
139
- }
140
- if (nd != null ) nd.value
141
- else {
142
- val table0 = table
143
- val default = defaultValue
144
- if (contentSize + 1 >= threshold) growTable(table.length * 2 )
145
- // Avoid recomputing index if the `defaultValue()` or new element hasn't triggered a table resize.
146
- val newIdx = if (table0 eq table) idx else index(hash)
147
- put0(key, default, false , hash, newIdx)
148
- default
149
- }
150
- }
134
+ val hash = computeHash(key)
135
+ val idx = index(hash)
136
+ val nd = table(idx) match {
137
+ case null => null
138
+ case nd => nd.findEntry(key, hash)
139
+ }
140
+ if (nd != null ) nd.value
141
+ else {
142
+ val table0 = table
143
+ val default = defaultValue
144
+ if (contentSize + 1 >= threshold) growTable(table.length * 2 )
145
+ // Avoid recomputing index if the `defaultValue()` or new element hasn't triggered a table resize.
146
+ val newIdx = if (table0 eq table) idx else index(hash)
147
+ put0(key, default, false , hash, newIdx)
148
+ default
149
+ }
150
+ }
151
151
}
152
152
153
153
private [this ] def removeEntry0 (elem : K ): Entry = removeEntry0(elem, computeHash(elem))
@@ -215,104 +215,103 @@ class LinkedHashMap[K, V]
215
215
this
216
216
}
217
217
218
- def iterator : Iterator [( K , V )] = new AbstractIterator [( K , V ) ] {
218
+ private [ this ] abstract class LinkedHashMapIterator [ T ] extends AbstractIterator [T ] {
219
219
private [this ] var cur = firstEntry
220
- def hasNext = cur ne null
221
- def next () =
222
- if (hasNext) { val res = (cur.key, cur.value); cur = cur.later; res }
220
+ def extract (nd : Entry ): T
221
+ def hasNext : Boolean = cur ne null
222
+ def next (): T =
223
+ if (hasNext) { val r = extract(cur); cur = cur.later; r }
223
224
else Iterator .empty.next()
224
225
}
225
226
227
+ def iterator : Iterator [(K , V )] =
228
+ if (size == 0 ) Iterator .empty
229
+ else new LinkedHashMapIterator [(K , V )] {
230
+ def extract (nd : Entry ): (K , V ) = (nd.key, nd.value)
231
+ }
232
+
226
233
protected class LinkedKeySet extends KeySet {
227
234
override def iterableFactory : IterableFactory [collection.Set ] = LinkedHashSet
228
235
}
229
236
230
237
override def keySet : collection.Set [K ] = new LinkedKeySet
231
238
232
- override def keysIterator : Iterator [K ] = new AbstractIterator [K ] {
233
- private [this ] var cur = firstEntry
234
- def hasNext = cur ne null
235
- def next () =
236
- if (hasNext) { val res = cur.key; cur = cur.later; res }
237
- else Iterator .empty.next()
238
- }
239
+ override def keysIterator : Iterator [K ] =
240
+ if (size == 0 ) Iterator .empty
241
+ else new LinkedHashMapIterator [K ] {
242
+ def extract (nd : Entry ): K = nd.key
243
+ }
239
244
240
- private [collection] def entryIterator : Iterator [Entry ] = new AbstractIterator [Entry ] {
241
- private [this ] var cur = firstEntry
245
+ private [collection] def entryIterator : Iterator [Entry ] =
246
+ if (size == 0 ) Iterator .empty
247
+ else new LinkedHashMapIterator [Entry ] {
248
+ def extract (nd : Entry ): Entry = nd
249
+ }
242
250
243
- def hasNext = cur ne null
244
251
245
- def next () =
246
- if (hasNext) {
247
- val res = cur; cur = cur.later; res
248
- }
249
- else Iterator .empty.next()
250
- }
251
252
// Override updateWith for performance, so we can do the update while hashing
252
253
// the input key only once and performing one lookup into the hash table
253
254
override def updateWith (key : K )(remappingFunction : Option [V ] => Option [V ]): Option [V ] = {
254
255
if (getClass != classOf [LinkedHashMap [_, _]]) {
255
256
// subclasses of LinkedHashMap might customise `get` ...
256
257
super .updateWith(key)(remappingFunction)
257
258
} else {
258
- val hash = computeHash(key)
259
- val indexedHash = index(hash)
260
-
261
- var foundEntry : Entry = null
262
- var previousEntry : Entry = null
263
- table(indexedHash) match {
264
- case null =>
265
- case nd =>
266
- @ tailrec
267
- def findEntry (prev : Entry , nd : Entry , k : K , h : Int ): Unit = {
268
- if (h == nd.hash && k == nd.key) {
269
- previousEntry = prev
270
- foundEntry = nd
271
- }
272
- else if ((nd.next eq null ) || (nd.hash > h)) ()
273
- else findEntry(nd, nd.next, k, h)
274
- }
275
-
276
- findEntry(null , nd, key, hash)
259
+ val hash = computeHash(key)
260
+ val indexedHash = index(hash)
261
+
262
+ var foundEntry : Entry = null
263
+ var previousEntry : Entry = null
264
+ table(indexedHash) match {
265
+ case null =>
266
+ case nd =>
267
+ @ tailrec
268
+ def findEntry (prev : Entry , nd : Entry , k : K , h : Int ): Unit = {
269
+ if (h == nd.hash && k == nd.key) {
270
+ previousEntry = prev
271
+ foundEntry = nd
272
+ }
273
+ else if ((nd.next eq null ) || (nd.hash > h)) ()
274
+ else findEntry(nd, nd.next, k, h)
277
275
}
278
276
279
- val previousValue = foundEntry match {
280
- case null => None
281
- case nd => Some (nd.value)
282
- }
277
+ findEntry(null , nd, key, hash)
278
+ }
279
+
280
+ val previousValue = foundEntry match {
281
+ case null => None
282
+ case nd => Some (nd.value)
283
+ }
283
284
284
- val nextValue = remappingFunction(previousValue)
285
+ val nextValue = remappingFunction(previousValue)
285
286
286
- (previousValue, nextValue) match {
287
- case (None , None ) => // do nothing
287
+ (previousValue, nextValue) match {
288
+ case (None , None ) => // do nothing
288
289
289
- case (Some (_), None ) =>
290
- if (previousEntry != null ) previousEntry.next = foundEntry.next
291
- else table(indexedHash) = foundEntry.next
292
- deleteEntry(foundEntry)
293
- contentSize -= 1
290
+ case (Some (_), None ) =>
291
+ if (previousEntry != null ) previousEntry.next = foundEntry.next
292
+ else table(indexedHash) = foundEntry.next
293
+ deleteEntry(foundEntry)
294
+ contentSize -= 1
294
295
295
- case (None , Some (value)) =>
296
- val newIndexedHash =
297
- if (contentSize + 1 >= threshold) {
298
- growTable(table.length * 2 )
299
- index(hash)
300
- } else indexedHash
301
- put0(key, value, false , hash, newIndexedHash)
296
+ case (None , Some (value)) =>
297
+ val newIndexedHash =
298
+ if (contentSize + 1 >= threshold) {
299
+ growTable(table.length * 2 )
300
+ index(hash)
301
+ } else indexedHash
302
+ put0(key, value, false , hash, newIndexedHash)
302
303
303
- case (Some (_), Some (newValue)) => foundEntry.value = newValue
304
- }
305
- nextValue
304
+ case (Some (_), Some (newValue)) => foundEntry.value = newValue
305
+ }
306
+ nextValue
306
307
}
307
308
}
308
309
309
- override def valuesIterator : Iterator [V ] = new AbstractIterator [V ] {
310
- private [this ] var cur = firstEntry
311
- def hasNext = cur ne null
312
- def next () =
313
- if (hasNext) { val res = cur.value; cur = cur.later; res }
314
- else Iterator .empty.next()
315
- }
310
+ override def valuesIterator : Iterator [V ] =
311
+ if (size == 0 ) Iterator .empty
312
+ else new LinkedHashMapIterator [V ] {
313
+ def extract (nd : Entry ): V = nd.value
314
+ }
316
315
317
316
318
317
override def foreach [U ](f : ((K , V )) => U ): Unit = {
@@ -452,31 +451,18 @@ class LinkedHashMap[K, V]
452
451
}
453
452
}
454
453
455
- override def hashCode (): Int = {
456
- abstract class LinkedHashMapIterator [A ](val firstentry : Entry ) extends AbstractIterator [A ] {
457
- var cur = firstentry
458
- def extract (nd : Entry ): A
459
- def hasNext : Boolean = cur ne null
460
- def next (): A =
461
- if (hasNext) {
462
- val r = extract(cur)
463
- cur = cur.later
464
- r
465
- } else Iterator .empty.next()
466
- }
467
-
454
+ override def hashCode : Int = {
468
455
if (isEmpty) MurmurHash3 .emptyMapHash
469
456
else {
470
- val tupleHashIterator = new LinkedHashMapIterator [Any ](firstEntry) {
457
+ val tupleHashIterator = new LinkedHashMapIterator [Any ] {
471
458
var hash : Int = 0
472
459
override def hashCode : Int = hash
473
- override def extract (nd : Entry ): Any = {
460
+ override def extract (nd : Entry ): Any = {
474
461
hash = MurmurHash3 .tuple2Hash(unimproveHash(nd.hash), nd.value.## )
475
462
this
476
463
}
477
464
}
478
-
479
- MurmurHash3 .orderedHash(tupleHashIterator, MurmurHash3 .mapSeed)
465
+ MurmurHash3 .unorderedHash(tupleHashIterator, MurmurHash3 .mapSeed)
480
466
}
481
467
}
482
468
@ nowarn(""" cat=deprecation&origin=scala\.collection\.Iterable\.stringPrefix""" )
0 commit comments