@@ -14,8 +14,7 @@ package scala
14
14
package collection
15
15
package immutable
16
16
17
- import scala .collection .mutable .{Builder , ImmutableBuilder }
18
- import scala .annotation .unchecked .{uncheckedVariance => uV }
17
+ import scala .annotation .tailrec
19
18
20
19
/** This class implements immutable maps using a vector/map-based data structure, which preserves insertion order.
21
20
*
@@ -26,140 +25,194 @@ import scala.annotation.unchecked.{uncheckedVariance => uV}
26
25
* @tparam V the type of the values associated with the keys in this vector map.
27
26
*
28
27
* @author Matthew de Detrich
28
+ * @author Odd Möller
29
29
* @version 2.13
30
30
* @since 2.13
31
31
* @define coll immutable vector map
32
32
* @define Coll `immutable.VectorMap`
33
33
*/
34
- final class VectorMap [K , + V ] private [immutable] (
35
- private [immutable] val fields : Vector [K ],
36
- private [immutable] val underlying : Map [K , (Int , V )])
37
- extends AbstractMap [K , V ]
34
+ final class VectorMap [K , + V ] private (
35
+ private [immutable] val fields : Vector [Any ],
36
+ private [immutable] val underlying : Map [K , (Int , V )], dummy : Boolean )
37
+ extends AbstractMap [K , V ]
38
38
with SeqMap [K , V ]
39
39
with MapOps [K , V , VectorMap , VectorMap [K , V ]]
40
40
with StrictOptimizedIterableOps [(K , V ), Iterable , VectorMap [K , V ]] {
41
+
42
+ import VectorMap ._
43
+
41
44
override protected [this ] def className : String = " VectorMap"
42
45
46
+ private [immutable] def this (fields : Vector [K ], underlying : Map [K , (Int , V )]) = {
47
+ this (fields, underlying, false )
48
+ }
49
+
50
+ override val size = underlying.size
51
+
52
+ override def knownSize : Int = size
53
+
54
+ override def isEmpty : Boolean = size == 0
55
+
43
56
def updated [V1 >: V ](key : K , value : V1 ): VectorMap [K , V1 ] = {
44
57
underlying.get(key) match {
45
- case Some (oldIndexWithValue) =>
46
- new VectorMap (fields,
47
- underlying.updated(key, (oldIndexWithValue._1, value)))
58
+ case Some ((slot, _)) =>
59
+ new VectorMap (fields, underlying.updated[(Int , V1 )](key, (slot, value)), false )
48
60
case None =>
49
- new VectorMap (
50
- fields :+ key,
51
- underlying.updated(key, (fields.length, value)))
61
+ new VectorMap (fields :+ key, underlying.updated[(Int , V1 )](key, (fields.length, value)), false )
52
62
}
53
63
}
54
64
55
65
override def withDefault [V1 >: V ](d : K => V1 ): Map .WithDefault [K , V1 ] =
56
66
new Map .WithDefault (this , d)
57
67
58
- override def withDefaultValue [V1 >: V ](d : V1 ): Map .WithDefault [K , V1 ] = new Map .WithDefault [K , V1 ](this , _ => d)
68
+ override def withDefaultValue [V1 >: V ](d : V1 ): Map .WithDefault [K , V1 ] =
69
+ new Map .WithDefault [K , V1 ](this , _ => d)
70
+
71
+ def get (key : K ): Option [V ] = underlying.get(key) match {
72
+ case Some (v) => Some (v._2)
73
+ case None => None
74
+ }
75
+
76
+ @ tailrec
77
+ private def field (slot : Int ): (Int , K ) = {
78
+ fields(slot) match {
79
+ case Tombstone .Kinless =>
80
+ (- 1 , null .asInstanceOf [K ])
81
+ case Tombstone .NextOfKin (distance) =>
82
+ field(slot + distance)
83
+ case k : K =>
84
+ (slot, k)
85
+ }
86
+ }
59
87
60
88
def iterator : Iterator [(K , V )] = new AbstractIterator [(K , V )] {
61
- private val fieldsIterator = fields.iterator
89
+ private [this ] val fieldsLength = fields.length
90
+ private [this ] var slot = - 1
91
+ private [this ] var key : K = null .asInstanceOf [K ]
92
+
93
+ private [this ] def advance (): Unit = {
94
+ val nextSlot = slot + 1
95
+ if (nextSlot >= fieldsLength) {
96
+ slot = fieldsLength
97
+ key = null .asInstanceOf [K ]
98
+ } else {
99
+ field(nextSlot) match {
100
+ case (- 1 , _) ⇒
101
+ slot = fieldsLength
102
+ key = null .asInstanceOf [K ]
103
+ case (s, k) ⇒
104
+ slot = s
105
+ key = k
106
+ }
107
+ }
108
+ }
109
+
110
+ advance()
62
111
63
- override def hasNext : Boolean = fieldsIterator.hasNext
112
+ override def hasNext : Boolean = slot < fieldsLength
64
113
65
114
override def next (): (K , V ) = {
66
- val field = fieldsIterator.next()
67
- (field, underlying(field)._2)
115
+ if (! hasNext) throw new NoSuchElementException (" next called on depleted iterator" )
116
+ val result = (key, underlying(key)._2)
117
+ advance()
118
+ result
68
119
}
69
120
}
70
121
71
- def get (key : K ): Option [V ] = underlying.get(key) match {
72
- case Some (v) => Some (v._2)
73
- case None => None
74
- }
75
-
76
122
def remove (key : K ): VectorMap [K , V ] = {
77
- underlying.get(key) match {
78
- case Some ((index, _)) =>
79
- val finalUnderlying = (underlying - key).map{ case (k, (currentIndex,v)) =>
80
- if (currentIndex > index)
81
- (k, (currentIndex - 1 , v))
82
- else
83
- (k, (currentIndex, v))
84
- }
85
- new VectorMap (fields.patch(index, Nil , 1 ), finalUnderlying)
86
- case _ =>
87
- this
123
+ if (isEmpty) empty
124
+ else {
125
+ var fs = fields
126
+ val sz = fs.size
127
+ underlying.get(key) match {
128
+ case Some ((slot, _)) =>
129
+ val s = field(slot)._1
130
+ // Calculate distance to next of kin
131
+ val d =
132
+ if (s < sz - 1 ) fs(s + 1 ) match {
133
+ case Tombstone .Kinless => 0
134
+ case Tombstone .NextOfKin (d) => d + 1
135
+ case _ => 1
136
+ } else 0
137
+ fs = fs.updated(s, Tombstone (d))
138
+ if (s > 0 ) {
139
+ // Adjust distance to next of kin for all preceding tombstones
140
+ var t = s - 1
141
+ var prev = fs(t)
142
+ while (t >= 0 && prev.isInstanceOf [Tombstone ]) {
143
+ fs = prev match {
144
+ case Tombstone .Kinless => throw new IllegalStateException (" kinless tombstone found in prefix: " + key)
145
+ case Tombstone .NextOfKin (_) if d == 0 => fs.updated(t, Tombstone .Kinless )
146
+ case Tombstone .NextOfKin (d) => fs.updated(t, Tombstone (d + 1 ))
147
+ case _ => fs
148
+ }
149
+ t -= 1
150
+ if (t >= 0 ) prev = fs(t)
151
+ }
152
+ }
153
+ new VectorMap (fs, underlying - key, false )
154
+ case _ =>
155
+ this
156
+ }
88
157
}
89
158
}
90
159
91
160
override def mapFactory : MapFactory [VectorMap ] = VectorMap
92
161
93
- override def size : Int = fields.size
94
-
95
- override def knownSize : Int = fields.size
96
-
97
- override def isEmpty : Boolean = fields.isEmpty
98
-
99
- override final def contains (key : K ): Boolean = underlying.contains(key)
162
+ override def contains (key : K ): Boolean = underlying.contains(key)
100
163
101
164
override def head : (K , V ) = iterator.next()
102
165
103
166
override def last : (K , V ) = {
104
- val last = fields.last
167
+ val last = fields
168
+ .reverseIterator
169
+ .find(! _.isInstanceOf [Tombstone ])
170
+ .get
171
+ .asInstanceOf [K ]
105
172
(last, underlying(last)._2)
106
173
}
107
174
108
175
override def lastOption : Option [(K , V )] = {
109
- fields.lastOption match {
110
- case Some (last) => Some ((last, underlying(last)._2))
111
- case None => None
112
- }
176
+ fields
177
+ .reverseIterator
178
+ .find(! _.isInstanceOf [Tombstone ])
179
+ .map { f ⇒
180
+ val last = f.asInstanceOf [K ]
181
+ (last, underlying(last)._2)
182
+ }
113
183
}
114
184
115
185
override def tail : VectorMap [K , V ] = {
116
- new VectorMap (fields.tail, underlying.remove(fields.head))
186
+ val (slot, key) = field(0 )
187
+ new VectorMap (fields.drop(slot + 1 ), underlying - key, false )
117
188
}
118
189
119
190
override def init : VectorMap [K , V ] = {
120
- new VectorMap (fields.init, underlying.remove(fields.last))
191
+ val (slot, key) = field(size - 1 )
192
+ new VectorMap (fields.dropRight(size - 1 - slot + 1 ), underlying - key, false )
121
193
}
122
194
123
- // Only care about content, not ordering for equality
124
- override def equals (that : Any ): Boolean =
125
- that match {
126
- case map : Map [K , V ] =>
127
- (this eq map) ||
128
- (this .size == map.size) && {
129
- try {
130
- var i = 0
131
- val _size = size
132
- while (i < _size) {
133
- val k = fields(i)
134
-
135
- map.get(k) match {
136
- case Some (value) =>
137
- if (! (value == underlying(k)._2)) {
138
- return false
139
- }
140
- case None =>
141
- return false
142
- }
143
- i += 1
144
- }
145
- true
146
- } catch {
147
- case _ : ClassCastException => false
148
- }
149
- }
150
- case _ => super .equals(that)
151
- }
152
-
153
- override def foreach [U ](f : ((K , V )) => U ): Unit = iterator.foreach(f)
154
-
155
- override def keys : Iterable [K ] = fields
195
+ def keyIterator : Iterator [K ] = iterator.map(_._1)
196
+ override def keys : Vector [K ] = keyIterator.toVector
156
197
157
198
override def values : Iterable [V ] = new Iterable [V ] {
158
- override def iterator : Iterator [V ] = fields.iterator .map(underlying(_)._2)
199
+ override def iterator : Iterator [V ] = keyIterator .map(underlying(_)._2)
159
200
}
160
201
}
161
202
162
203
object VectorMap extends MapFactory [VectorMap ] {
204
+ private [VectorMap ] sealed trait Tombstone
205
+ private [VectorMap ] object Tombstone {
206
+ final case object Kinless extends Tombstone {
207
+ override def toString = " ⤞"
208
+ }
209
+ final case class NextOfKin private (distance : Int ) extends Tombstone {
210
+ override def toString = " ⥅" + distance
211
+ }
212
+ def apply (distance : Int ): Tombstone =
213
+ if (distance <= 0 ) Kinless
214
+ else NextOfKin (distance)
215
+ }
163
216
164
217
def empty [K , V ]: VectorMap [K , V ] =
165
218
new VectorMap [K , V ](
@@ -172,8 +225,8 @@ object VectorMap extends MapFactory[VectorMap] {
172
225
case _ => (newBuilder[K , V ] ++= it).result()
173
226
}
174
227
175
- def newBuilder [K , V ]: Builder [(K , V ), VectorMap [K , V ]] =
176
- new ImmutableBuilder [(K , V ), VectorMap [K , V ]](empty) {
228
+ def newBuilder [K , V ]: mutable. Builder [(K , V ), VectorMap [K , V ]] =
229
+ new mutable. ImmutableBuilder [(K , V ), VectorMap [K , V ]](empty) {
177
230
def addOne (elem : (K , V )): this .type = { elems = elems + elem; this }
178
231
}
179
232
0 commit comments