Skip to content

Commit 2fa1738

Browse files
committed
More SimpleMap -> SimpleEqMap
1 parent d7ecb21 commit 2fa1738

File tree

7 files changed

+234
-11
lines changed

7 files changed

+234
-11
lines changed

compiler/src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import Comments._
1717
import util.Positions._
1818
import ast.Trees._
1919
import ast.untpd
20-
import util.{FreshNameCreator, SimpleMap, SourceFile, NoSource}
20+
import util.{FreshNameCreator, SimpleEqMap, SourceFile, NoSource}
2121
import typer.{Implicits, ImplicitRunInfo, ImportInfo, Inliner, NamerContextOps, SearchHistory, TypeAssigner, Typer}
2222
import Implicits.ContextualImplicits
2323
import config.Settings._
@@ -694,14 +694,14 @@ object Contexts {
694694
implicit val ctx: Context = initctx
695695
}
696696

697-
class GADTMap(initBounds: SimpleMap[Symbol, TypeBounds]) extends util.DotClass {
697+
class GADTMap(initBounds: SimpleEqMap[Symbol, TypeBounds]) extends util.DotClass {
698698
private var myBounds = initBounds
699699
def setBounds(sym: Symbol, b: TypeBounds): Unit =
700700
myBounds = myBounds.updated(sym, b)
701701
def bounds = myBounds
702702
}
703703

704-
@sharable object EmptyGADTMap extends GADTMap(SimpleMap.Empty) {
704+
@sharable object EmptyGADTMap extends GADTMap(SimpleEqMap.Empty) {
705705
override def setBounds(sym: Symbol, b: TypeBounds) = unsupported("EmptyGADTMap.setBounds")
706706
}
707707
}

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import Decorators.SymbolIteratorDecorator
1313
import ast._
1414
import annotation.tailrec
1515
import CheckRealizable._
16-
import util.SimpleMap
16+
import util.SimpleEqMap
1717
import util.Stats
1818
import java.util.WeakHashMap
1919
import config.Config
@@ -1254,7 +1254,7 @@ object SymDenotations {
12541254
// ----- caches -------------------------------------------------------
12551255

12561256
private[this] var myTypeParams: List[TypeSymbol] = null
1257-
private[this] var fullNameCache: SimpleMap[QualifiedNameKind, Name] = SimpleMap.Empty
1257+
private[this] var fullNameCache: SimpleEqMap[QualifiedNameKind, Name] = SimpleEqMap.Empty
12581258

12591259
private[this] var myMemberCache: LRUCache[Name, PreDenotation] = null
12601260
private[this] var myMemberCachePeriod: Period = Nowhere
@@ -2041,7 +2041,7 @@ object SymDenotations {
20412041
}
20422042

20432043
private class MemberNamesImpl(createdAt: Period) extends InheritedCacheImpl(createdAt) with MemberNames {
2044-
private[this] var cache: SimpleMap[NameFilter, Set[Name]] = SimpleMap.Empty
2044+
private[this] var cache: SimpleEqMap[NameFilter, Set[Name]] = SimpleEqMap.Empty
20452045

20462046
final def isValid(implicit ctx: Context): Boolean =
20472047
cache != null && isValidAt(ctx.phase)
@@ -2054,7 +2054,7 @@ object SymDenotations {
20542054
*/
20552055
def invalidate(): Unit =
20562056
if (cache != null)
2057-
if (locked) cache = SimpleMap.Empty
2057+
if (locked) cache = SimpleEqMap.Empty
20582058
else {
20592059
cache = null
20602060
invalidateDependents()

compiler/src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import Types._, Contexts._, Symbols._, Flags._, Names._, NameOps._, Denotations.
66
import Decorators._
77
import StdNames.{nme, tpnme}
88
import collection.mutable
9-
import util.{Stats, DotClass, SimpleMap}
9+
import util.{Stats, DotClass}
1010
import config.Config
1111
import config.Printers.{typr, constr, subtyping, noPrinter}
1212
import TypeErasure.{erasedLub, erasedGlb}

compiler/src/dotty/tools/dotc/core/TypeOps.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import StdNames._
1313
import Annotations._
1414
import annotation.tailrec
1515
import config.Config
16-
import util.{SimpleMap, Property}
16+
import util.Property
1717
import collection.mutable
1818
import ast.tpd._
1919

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import Periods._
1919
import Designators._
2020
import util.Positions.{Position, NoPosition}
2121
import util.Stats._
22-
import util.{DotClass, SimpleMap}
22+
import util.DotClass
2323
import reporting.diagnostic.Message
2424
import reporting.diagnostic.messages.CyclicReferenceInvolving
2525
import ast.tpd._

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import ErrorReporting.errorTree
2121

2222
import annotation.unchecked
2323
import util.Positions._
24-
import util.{SimpleMap, Stats}
24+
import util.Stats
2525
import util.common._
2626
import transform.SymUtils._
2727
import Decorators._
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
package dotty.tools.dotc.util
2+
3+
import collection.mutable.ListBuffer
4+
5+
abstract class SimpleEqMap[K <: AnyRef, +V >: Null <: AnyRef] extends (K => V) {
6+
def size: Int
7+
def apply(k: K): V
8+
def remove(k: K): SimpleEqMap[K, V]
9+
def updated[V1 >: V <: AnyRef](k: K, v: V1): SimpleEqMap[K, V1]
10+
def contains(k: K): Boolean = apply(k) != null
11+
def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1): SimpleEqMap[K, V1]
12+
def foreachBinding(f: (K, V) => Unit): Unit
13+
def map2[T](f: (K, V) => T): List[T] = {
14+
val buf = new ListBuffer[T]
15+
foreachBinding((k, v) => buf += f(k, v))
16+
buf.toList
17+
}
18+
def keys: List[K] = map2((k, v) => k)
19+
def toList: List[(K, V)] = map2((k, v) => (k, v))
20+
override def toString = {
21+
def assocToString(key: K, value: V) = s"$key -> $value"
22+
map2(assocToString) mkString ("(", ", ", ")")
23+
}
24+
}
25+
26+
object SimpleEqMap {
27+
28+
private val CompactifyThreshold = 4
29+
30+
private object myEmpty extends SimpleEqMap[AnyRef, Null] {
31+
def size = 0
32+
def apply(k: AnyRef) = null
33+
def remove(k: AnyRef) = this
34+
def updated[V1 >: Null <: AnyRef](k: AnyRef, v: V1) = new Map1(k, v)
35+
def mapValuesNow[V1 >: Null <: AnyRef](f: (AnyRef, V1) => V1) = this
36+
def foreachBinding(f: (AnyRef, Null) => Unit) = ()
37+
}
38+
39+
def Empty[K <: AnyRef] = myEmpty.asInstanceOf[SimpleEqMap[K, Null]]
40+
41+
class Map1[K <: AnyRef, +V >: Null <: AnyRef] (k1: K, v1: V) extends SimpleEqMap[K, V] {
42+
def size = 1
43+
def apply(k: K) =
44+
if (k eq k1) v1
45+
else null
46+
def remove(k: K) =
47+
if (k eq k1) Empty.asInstanceOf[SimpleEqMap[K, V]]
48+
else this
49+
def updated[V1 >: V <: AnyRef](k: K, v: V1) =
50+
if (k eq k1) new Map1(k, v)
51+
else new Map2(k1, v1, k, v)
52+
def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
53+
val w1 = f(k1, v1)
54+
if (v1 eq w1) this else new Map1(k1, w1)
55+
}
56+
def foreachBinding(f: (K, V) => Unit) = f(k1, v1)
57+
}
58+
59+
class Map2[K <: AnyRef, +V >: Null <: AnyRef] (k1: K, v1: V, k2: K, v2: V) extends SimpleEqMap[K, V] {
60+
def size = 2
61+
def apply(k: K) =
62+
if (k eq k1) v1
63+
else if (k eq k2) v2
64+
else null
65+
def remove(k: K) =
66+
if (k eq k1) new Map1(k2, v2)
67+
else if (k eq k2) new Map1(k1, v1)
68+
else this
69+
def updated[V1 >: V <: AnyRef](k: K, v: V1) =
70+
if (k eq k1) new Map2(k, v, k2, v2)
71+
else if (k eq k2) new Map2(k1, v1, k, v)
72+
else new Map3(k1, v1, k2, v2, k, v)
73+
def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
74+
val w1 = f(k1, v1); val w2 = f(k2, v2)
75+
if ((v1 eq w1) && (v2 eq w2)) this
76+
else new Map2(k1, w1, k2, w2)
77+
}
78+
def foreachBinding(f: (K, V) => Unit) = { f(k1, v1); f(k2, v2) }
79+
}
80+
81+
class Map3[K <: AnyRef, +V >: Null <: AnyRef] (k1: K, v1: V, k2: K, v2: V, k3: K, v3: V) extends SimpleEqMap[K, V] {
82+
def size = 3
83+
def apply(k: K) =
84+
if (k eq k1) v1
85+
else if (k eq k2) v2
86+
else if (k eq k3) v3
87+
else null
88+
def remove(k: K) =
89+
if (k eq k1) new Map2(k2, v2, k3, v3)
90+
else if (k eq k2) new Map2(k1, v1, k3, v3)
91+
else if (k eq k3) new Map2(k1, v1, k2, v2)
92+
else this
93+
def updated[V1 >: V <: AnyRef](k: K, v: V1) =
94+
if (k eq k1) new Map3(k, v, k2, v2, k3, v3)
95+
else if (k eq k2) new Map3(k1, v1, k, v, k3, v3)
96+
else if (k eq k3) new Map3(k1, v1, k2, v2, k, v)
97+
else new Map4(k1, v1, k2, v2, k3, v3, k, v)
98+
def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
99+
val w1 = f(k1, v1); val w2 = f(k2, v2); val w3 = f(k3, v3)
100+
if ((v1 eq w1) && (v2 eq w2) && (v3 eq w3)) this
101+
else new Map3(k1, w1, k2, w2, k3, w3)
102+
}
103+
def foreachBinding(f: (K, V) => Unit) = { f(k1, v1); f(k2, v2); f(k3, v3) }
104+
}
105+
106+
class Map4[K <: AnyRef, +V >: Null <: AnyRef] (k1: K, v1: V, k2: K, v2: V, k3: K, v3: V, k4: K, v4: V) extends SimpleEqMap[K, V] {
107+
def size = 4
108+
def apply(k: K) =
109+
if (k eq k1) v1
110+
else if (k eq k2) v2
111+
else if (k eq k3) v3
112+
else if (k eq k4) v4
113+
else null
114+
def remove(k: K) =
115+
if (k eq k1) new Map3(k2, v2, k3, v3, k4, v4)
116+
else if (k eq k2) new Map3(k1, v1, k3, v3, k4, v4)
117+
else if (k eq k3) new Map3(k1, v1, k2, v2, k4, v4)
118+
else if (k eq k4) new Map3(k1, v1, k2, v2, k3, v3)
119+
else this
120+
def updated[V1 >: V <: AnyRef](k: K, v: V1) =
121+
if (k eq k1) new Map4(k, v, k2, v2, k3, v3, k4, v4)
122+
else if (k eq k2) new Map4(k1, v1, k, v, k3, v3, k4, v4)
123+
else if (k eq k3) new Map4(k1, v1, k2, v2, k, v, k4, v4)
124+
else if (k eq k4) new Map4(k1, v1, k2, v2, k3, v3, k, v)
125+
else new MapMore(Array[AnyRef](k1, v1, k2, v2, k3, v3, k4, v4, k, v))
126+
def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
127+
val w1 = f(k1, v1); val w2 = f(k2, v2); val w3 = f(k3, v3); val w4 = f(k4, v4)
128+
if ((v1 eq w1) && (v2 eq w2) && (v3 eq w3) && (v4 eq w4)) this
129+
else new Map4(k1, w1, k2, w2, k3, w3, k4, w4)
130+
}
131+
def foreachBinding(f: (K, V) => Unit) = { f(k1, v1); f(k2, v2); f(k3, v3); f(k4, v4) }
132+
}
133+
134+
class MapMore[K <: AnyRef, +V >: Null <: AnyRef](bindings: Array[AnyRef]) extends SimpleEqMap[K, V] {
135+
private def key(i: Int): K = bindings(i).asInstanceOf[K]
136+
private def value(i: Int): V = bindings(i + 1).asInstanceOf[V]
137+
138+
def size = bindings.length / 2
139+
140+
def apply(k: K): V = {
141+
var i = 0
142+
while (i < bindings.length) {
143+
if (bindings(i) eq k) return value(i)
144+
i += 2
145+
}
146+
null
147+
}
148+
149+
def remove(k: K): SimpleEqMap[K, V] = {
150+
var i = 0
151+
while (i < bindings.length) {
152+
if (bindings(i) eq k) return {
153+
if (size == CompactifyThreshold) {
154+
var m: SimpleEqMap[K, V] = Empty[K]
155+
for (j <- 0 until bindings.length by 2)
156+
if (j != i) m = m.updated(key(j), value(j))
157+
m
158+
} else {
159+
val bindings1 = new Array[AnyRef](bindings.length - 2)
160+
Array.copy(bindings, 0, bindings1, 0, i)
161+
Array.copy(bindings, i + 2, bindings1, i, bindings1.length - i)
162+
new MapMore(bindings1)
163+
}
164+
}
165+
i += 2
166+
}
167+
this
168+
}
169+
170+
def updated[V1 >: V <: AnyRef](k: K, v: V1): SimpleEqMap[K, V] = {
171+
var i = 0
172+
while (i < bindings.length) {
173+
if (bindings(i) eq k)
174+
return {
175+
if (v eq bindings(i + 1)) this
176+
else {
177+
val bindings1 = bindings.clone
178+
bindings1(i + 1) = v
179+
new MapMore(bindings1)
180+
}
181+
}
182+
i += 2
183+
}
184+
val bindings2 = new Array[AnyRef](bindings.length + 2)
185+
Array.copy(bindings, 0, bindings2, 0, bindings.length)
186+
bindings2(bindings.length) = k
187+
bindings2(bindings.length + 1) = v
188+
new MapMore(bindings2)
189+
}
190+
191+
override def contains(k: K): Boolean = {
192+
var i = 0
193+
while (i < bindings.length) {
194+
if (bindings(i) eq k) return true
195+
i += 2
196+
}
197+
false
198+
}
199+
200+
def mapValuesNow[V1 >: V <: AnyRef](f: (K, V1) => V1) = {
201+
var bindings1: Array[AnyRef] = bindings
202+
var i = 0
203+
while (i < bindings.length) {
204+
val v = value(i)
205+
val v1 = f(key(i), v)
206+
if ((v1 ne v) && (bindings1 eq bindings))
207+
bindings1 = bindings.clone
208+
bindings1(i) = bindings(i)
209+
bindings1(i + 1) = v1
210+
i += 2
211+
}
212+
if (bindings1 eq bindings) this else new MapMore(bindings1)
213+
}
214+
215+
def foreachBinding(f: (K, V) => Unit) = {
216+
var i = 0
217+
while (i < bindings.length) {
218+
f(key(i), value(i))
219+
i += 2
220+
}
221+
}
222+
}
223+
}

0 commit comments

Comments
 (0)