Skip to content

Commit 08bfa48

Browse files
authored
Merge pull request scala/scala#10235 from liang3zy22/2ndoptimizationlhslhm
continuous optimization for LinkedHashMap/LinkedHashSet related codes
2 parents e205912 + 2b2806a commit 08bfa48

File tree

6 files changed

+263
-66
lines changed

6 files changed

+263
-66
lines changed

library/src/scala/collection/immutable/HashMap.scala

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,27 @@ final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode:
190190
}
191191
}
192192
this
193+
case lhm: mutable.LinkedHashMap[K @unchecked, V @unchecked] =>
194+
val iter = lhm.entryIterator
195+
var current = rootNode
196+
while (iter.hasNext) {
197+
val next = iter.next()
198+
val originalHash = lhm.unimproveHash(next.hash)
199+
val improved = improve(originalHash)
200+
current = current.updated(next.key, next.value, originalHash, improved, 0, replaceValue = true)
201+
202+
if (current ne rootNode) {
203+
var shallowlyMutableNodeMap = Node.bitposFrom(Node.maskFrom(improved, 0))
204+
205+
while (iter.hasNext) {
206+
val next = iter.next()
207+
val originalHash = lhm.unimproveHash(next.hash)
208+
shallowlyMutableNodeMap = current.updateWithShallowMutations(next.key, next.value, originalHash, improve(originalHash), 0, shallowlyMutableNodeMap)
209+
}
210+
return new HashMap(current)
211+
}
212+
}
213+
this
193214
case _ =>
194215
class accum extends AbstractFunction2[K, V1, Unit] with Function1[(K, V1), Unit] {
195216
var changed = false
@@ -397,6 +418,24 @@ final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode:
397418
}
398419
newHashMapOrThis(curr)
399420
}
421+
case lhashSet: collection.mutable.LinkedHashSet[K] =>
422+
if (lhashSet.isEmpty) {
423+
this
424+
} else {
425+
val iter = lhashSet.entryIterator
426+
var curr = rootNode
427+
428+
while (iter.hasNext) {
429+
val next = iter.next()
430+
val originalHash = lhashSet.unimproveHash(next.hash)
431+
val improved = improve(originalHash)
432+
curr = curr.removed(next.key, originalHash, improved, 0)
433+
if (curr.size == 0) {
434+
return HashMap.empty
435+
}
436+
}
437+
newHashMapOrThis(curr)
438+
}
400439
case _ =>
401440
val iter = keys.iterator
402441
var curr = rootNode
@@ -2353,6 +2392,14 @@ private[immutable] final class HashMapBuilder[K, V] extends ReusableBuilder[(K,
23532392
val hash = improve(originalHash)
23542393
update(rootNode, next.key, next.value, originalHash, hash, 0)
23552394
}
2395+
case lhm: collection.mutable.LinkedHashMap[K, V] =>
2396+
val iter = lhm.entryIterator
2397+
while (iter.hasNext) {
2398+
val next = iter.next()
2399+
val originalHash = lhm.unimproveHash(next.hash)
2400+
val hash = improve(originalHash)
2401+
update(rootNode, next.key, next.value, originalHash, hash, 0)
2402+
}
23562403
case thatMap: Map[K, V] =>
23572404
thatMap.foreachEntry((key, value) => addOne(key, value))
23582405
case other =>

library/src/scala/collection/immutable/HashSet.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,27 @@ final class HashSet[A] private[immutable](private[immutable] val rootNode: Bitma
121121
}
122122
}
123123
this
124+
case lhs: collection.mutable.LinkedHashSet[A] =>
125+
val iter = lhs.entryIterator
126+
var current = rootNode
127+
while (iter.hasNext) {
128+
val next = iter.next()
129+
val originalHash = lhs.unimproveHash(next.hash)
130+
val improved = improve(originalHash)
131+
current = current.updated(next.key, originalHash, improved, 0)
132+
133+
if (current ne rootNode) {
134+
var shallowlyMutableNodeMap = Node.bitposFrom(Node.maskFrom(improved, 0))
135+
while (iter.hasNext) {
136+
val next = iter.next()
137+
val originalHash = lhs.unimproveHash(next.hash)
138+
val improved = improve(originalHash)
139+
shallowlyMutableNodeMap = current.updateWithShallowMutations(next.key, originalHash, improved, 0, shallowlyMutableNodeMap)
140+
}
141+
return new HashSet(current)
142+
}
143+
}
144+
this
124145
case _ =>
125146
val iter = that.iterator
126147
var current = rootNode

library/src/scala/collection/mutable/HashMap.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double)
108108
put0(next.key, next.value, next.hash, getOld = false)
109109
}
110110
this
111+
case lhm: mutable.LinkedHashMap[K, V] =>
112+
val iter = lhm.entryIterator
113+
while (iter.hasNext) {
114+
val entry = iter.next()
115+
put0(entry.key, entry.value, entry.hash, getOld = false)
116+
}
117+
this
111118
case thatMap: Map[K, V] =>
112119
thatMap.foreachEntry { (key: K, value: V) =>
113120
put0(key, value, improveHash(key.##), getOld = false)
@@ -195,6 +202,14 @@ class HashMap[K, V](initialCapacity: Int, loadFactor: Double)
195202
if (size == 0) return this
196203
}
197204
this
205+
case lhs: mutable.LinkedHashSet[K] =>
206+
val iter = lhs.entryIterator
207+
while (iter.hasNext) {
208+
val next = iter.next()
209+
remove0(next.key, next.hash)
210+
if (size == 0) return this
211+
}
212+
this
198213
case _ => super.subtractAll(xs)
199214
}
200215
}

library/src/scala/collection/mutable/HashSet.scala

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,18 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double)
9393
override def addAll(xs: IterableOnce[A]): this.type = {
9494
sizeHint(xs.knownSize)
9595
xs match {
96-
case hm: immutable.HashSet[A] =>
97-
hm.foreachWithHash((k, h) => addElem(k, improveHash(h)))
96+
case hs: immutable.HashSet[A] =>
97+
hs.foreachWithHash((k, h) => addElem(k, improveHash(h)))
98+
this
99+
case hs: mutable.HashSet[A] =>
100+
val iter = hs.nodeIterator
101+
while (iter.hasNext) {
102+
val next = iter.next()
103+
addElem(next.key, next.hash)
104+
}
98105
this
99-
case hm: mutable.HashSet[A] =>
100-
val iter = hm.nodeIterator
106+
case lhs: mutable.LinkedHashSet[A] =>
107+
val iter = lhs.entryIterator
101108
while (iter.hasNext) {
102109
val next = iter.next()
103110
addElem(next.key, next.hash)
@@ -127,6 +134,14 @@ final class HashSet[A](initialCapacity: Int, loadFactor: Double)
127134
if (size == 0) return this
128135
}
129136
this
137+
case lhs: mutable.LinkedHashSet[A] =>
138+
val iter = lhs.entryIterator
139+
while (iter.hasNext) {
140+
val next = iter.next()
141+
remove(next.key, next.hash)
142+
if (size == 0) return this
143+
}
144+
this
130145
case _ => super.subtractAll(xs)
131146
}
132147
}

0 commit comments

Comments
 (0)