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