1+ package dotty .tools .dotc .util
2+
3+ /** A table with an immutable API that must be used linearly since it uses
4+ * mutation internally. A packed array representation is used for sizes
5+ * up to 8, and a hash table is used for larger sizes.
6+ */
7+ abstract class LinearTable [Key >: Null <: AnyRef , Value >: Null <: AnyRef ]:
8+ def lookup (key : Key ): Value
9+ def enter (key : Key , value : Value ): LinearTable [Key , Value ]
10+ def invalidate (key : Key ): Unit
11+ def size : Int
12+
13+ object LinearTable :
14+ def empty [Key >: Null <: AnyRef , Value >: Null <: AnyRef ]: LinearTable [Key , Value ] =
15+ ArrayTable [Key , Value ](8 )
16+
17+ class ArrayTable [Key >: Null <: AnyRef , Value >: Null <: AnyRef ](capacity : Int ) extends LinearTable [Key , Value ]:
18+
19+ val elems = new Array [AnyRef ](capacity * 2 )
20+ var size = 0
21+
22+ def lookup (key : Key ): Value =
23+ var i = 0
24+ while i < elems.length do
25+ if elems(i) eq key then
26+ return elems(i + 1 ).asInstanceOf [Value ]
27+ if elems(i) == null then
28+ return null
29+ i += 2
30+ null
31+
32+ def enter (key : Key , value : Value ): LinearTable [Key , Value ] =
33+ var i = 0
34+ while i < elems.length do
35+ if elems(i) eq key then
36+ elems(i + 1 ) = value
37+ return this
38+ if elems(i) == null then
39+ elems(i) = key
40+ elems(i + 1 ) = value
41+ size += 1
42+ return this
43+ i += 2
44+ val ht = HashTable [Key , Value ](initialCapacity = 16 )
45+ i = 0
46+ while i < elems.length do
47+ ht.enter(elems(i).asInstanceOf [Key ], elems(i + 1 ).asInstanceOf [Value ])
48+ i += 2
49+ ht.enter(key, value)
50+ ht
51+
52+ def invalidate (key : Key ): Unit =
53+ var i = 0
54+ while i < elems.length do
55+ if elems(i) eq key then
56+ size -= 1
57+ elems(i) = null
58+ return
59+ i += 2
60+
61+ override def toString : String =
62+ val buf = new StringBuilder
63+ var i = 0
64+ while i < elems.length do
65+ buf.append(if i == 0 then " ArrayTable(" else " , " )
66+ if elems(i) != null then
67+ buf.append(elems(i))
68+ buf.append(" -> " )
69+ buf.append(elems(i + 1 ))
70+ i += 2
71+ buf.append(" )" )
72+ buf.toString
73+ end ArrayTable
74+
75+ class HashTable [Key >: Null <: AnyRef , Value >: Null <: AnyRef ](initialCapacity : Int ) extends LinearTable [Key , Value ]:
76+ private val table = java.util.HashMap [Key , Value ](initialCapacity)
77+
78+ def lookup (key : Key ): Value =
79+ table.get(key)
80+ def enter (key : Key , value : Value ): LinearTable [Key , Value ] =
81+ table.put(key, value)
82+ this
83+ def invalidate (key : Key ): Unit =
84+ table.remove(key)
85+ def size : Int =
86+ table.size
87+
88+ override def toString : String = table.toString
89+ end HashTable
0 commit comments