Skip to content

Commit 11fd2d0

Browse files
committed
Add lazy versions of sorted and immutable keysets, and deprecate the old versions
1 parent 0725809 commit 11fd2d0

File tree

6 files changed

+41
-5
lines changed

6 files changed

+41
-5
lines changed

library/src/scala/collection/SortedMap.scala

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,22 @@ transparent trait SortedMapOps[K, +V, +CC[X, Y] <: Map[X, Y] & SortedMapOps[X, Y
132132
rangeUntil(next)
133133
}
134134

135-
override def keySet: SortedSet[K] = new KeySortedSet
135+
override def keySet: SortedSet[K] = new LazyKeySortedSet
136136

137137
/** The implementation class of the set returned by `keySet` */
138+
private[collection] class LazyKeySortedSet extends MapOps.LazyKeySet(this) with SortedSet[K] {
139+
implicit def ordering: Ordering[K] = SortedMapOps.this.ordering
140+
def iteratorFrom(start: K): Iterator[K] = SortedMapOps.this.keysIteratorFrom(start)
141+
142+
override def diff(that: Set[K]): SortedSet[K] = fromSpecific(view.filterNot(that))
143+
override def rangeImpl(from: Option[K], until: Option[K]): SortedSet[K] = {
144+
val map = SortedMapOps.this.rangeImpl(from, until)
145+
new map.LazyKeySortedSet
146+
}
147+
}
148+
149+
/** The old implementation class of the set returned by `keySet` */
150+
@deprecated("KeySortedSet is no longer used in the .keySet implementation", since = "3.8.0")
138151
protected class KeySortedSet extends SortedSet[K] with GenKeySet with GenKeySortedSet {
139152
def diff(that: Set[K]): SortedSet[K] = fromSpecific(view.filterNot(that))
140153
def rangeImpl(from: Option[K], until: Option[K]): SortedSet[K] = {
@@ -144,6 +157,7 @@ transparent trait SortedMapOps[K, +V, +CC[X, Y] <: Map[X, Y] & SortedMapOps[X, Y
144157
}
145158

146159
/** A generic trait that is reused by sorted keyset implementations */
160+
@deprecated("GenKeySortedSet is no longer used in .keySet implementations", since = "3.8.0")
147161
protected trait GenKeySortedSet extends GenKeySet { this: SortedSet[K] =>
148162
implicit def ordering: Ordering[K] = SortedMapOps.this.ordering
149163
def iteratorFrom(start: K): Iterator[K] = SortedMapOps.this.keysIteratorFrom(start)

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode:
6060

6161
override def keySet: Set[K] = if (size == 0) Set.empty else new HashKeySet
6262

63-
private[immutable] final class HashKeySet extends ImmutableKeySet {
63+
64+
private[immutable] final class HashKeySet extends LazyImmutableKeySet {
6465

6566
private def newKeySetOrThis(newHashMap: HashMap[K, ?]): Set[K] =
6667
if (newHashMap eq HashMap.this) this else newHashMap.keySet

library/src/scala/collection/immutable/Map.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,17 @@ transparent trait MapOps[K, +V, +CC[X, +Y] <: MapOps[X, Y, CC, ?], +C <: MapOps[
143143
*/
144144
def transform[W](f: (K, V) => W): CC[K, W] = map { case (k, v) => (k, f(k, v)) }
145145

146-
override def keySet: Set[K] = new ImmutableKeySet
146+
override def keySet: Set[K] = new LazyImmutableKeySet
147147

148148
/** The implementation class of the set returned by `keySet` */
149+
private[immutable] class LazyImmutableKeySet extends MapOps.LazyKeySet(this) with Set[K] {
150+
override def diff(that: collection.Set[K]): Set[K] = super.diff(that)
151+
override def incl(elem: K): Set[K] = if (this(elem)) this else MapOps.this.updated(elem, ()).keySet
152+
override def excl(elem: K): Set[K] = if (this(elem)) MapOps.this.removed(elem).keySet else this
153+
}
154+
155+
/** The implementation class of the set returned by `keySet` */
156+
@deprecated("ImmutableKeySet is no longer used in .keySet implementations", since = "3.8.0")
149157
protected[immutable] class ImmutableKeySet extends AbstractSet[K] with GenKeySet with DefaultSerializable {
150158
def incl(elem: K): Set[K] = if (this(elem)) this else empty ++ this + elem
151159
def excl(elem: K): Set[K] = if (this(elem)) empty ++ this - elem else this

library/src/scala/collection/immutable/Set.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ object Set extends IterableFactory[Set] {
110110
case s: Set3[E] => s
111111
case s: Set4[E] => s
112112
case s: HashMap[E @unchecked, _]#HashKeySet => s
113-
case s: MapOps[E, Any, Map, Map[E, Any]]#ImmutableKeySet @unchecked => s
113+
case s: MapOps[E, Any, Map, Map[E, Any]]#LazyImmutableKeySet @unchecked => s
114114
// We also want `SortedSet` (and subclasses, such as `BitSet`)
115115
// to rebuild themselves, to avoid element type widening issues.
116116
case _ => newBuilder[E].addAll(it).result()

library/src/scala/collection/immutable/SortedMap.scala

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,21 @@ transparent trait SortedMapOps[K, +V, +CC[X, +Y] <: Map[X, Y] & SortedMapOps[X,
9393

9494
def unsorted: Map[K, V]
9595

96-
override def keySet: SortedSet[K] = new ImmutableKeySortedSet
96+
override def keySet: SortedSet[K] = new LazyImmutableKeySortedSet
9797

9898
/** The implementation class of the set returned by `keySet` */
99+
private class LazyImmutableKeySortedSet extends LazyKeySortedSet with SortedSet[K] {
100+
override def diff(that: scala.collection.Set[K]): SortedSet[K] = super.diff(that)
101+
override def rangeImpl(from: Option[K], until: Option[K]): SortedSet[K] = {
102+
val map = self.rangeImpl(from, until)
103+
new map.LazyImmutableKeySortedSet
104+
}
105+
def incl(elem: K): SortedSet[K] = fromSpecific(this).incl(elem)
106+
def excl(elem: K): SortedSet[K] = fromSpecific(this).excl(elem)
107+
}
108+
109+
/** The implementation class of the set returned by `keySet` */
110+
@deprecated("ImmutableKeySortedSet is no longer used by the .keySet implementation", since = "3.8.0")
99111
protected class ImmutableKeySortedSet extends AbstractSet[K] with SortedSet[K] with GenKeySet with GenKeySortedSet {
100112
def rangeImpl(from: Option[K], until: Option[K]): SortedSet[K] = {
101113
val map = self.rangeImpl(from, until)

library/src/scala/collection/mutable/LinkedHashMap.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ class LinkedHashMap[K, V]
234234
def extract(nd: Entry): (K, V) = (nd.key, nd.value)
235235
}
236236

237+
@deprecated("LinkedKeySet is now strict and no longer used in the implementation of .keySet", "3.8.0")
237238
/** Note that a LinkedKeySet could be strict. */
238239
protected class LinkedKeySet extends KeySet {
239240
override def iterableFactory: IterableFactory[collection.Set] = LinkedHashSet

0 commit comments

Comments
 (0)