Skip to content

Commit a2b0d26

Browse files
authored
Merge pull request scala#7264 from joshlemer/hashmap-preemptive-overrides
Add preemptive overrides for s.c.i.Hashmap
2 parents 8008069 + 8227da6 commit a2b0d26

File tree

2 files changed

+174
-0
lines changed

2 files changed

+174
-0
lines changed

src/library/scala/collection/immutable/ChampHashMap.scala

+102
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,108 @@ final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode:
153153
that.removeAll(thisKeys) ++ this.removeAll(thatKeys) ++ thisKeys.intersect(thatKeys).map { case k => mergef((k, this(k)), (k, that(k))) }
154154
}
155155
}
156+
157+
override def filterImpl(pred: ((K, V)) => Boolean, flipped: Boolean): HashMap[K, V] = {
158+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
159+
// in a minor release without breaking binary compatibility.
160+
//
161+
// In particular, `filterImpl` could be optimized to filter and reconstruct the trie node-by-node, without having to
162+
// perform any hashing or equality checks.
163+
super.filterImpl(pred, flipped)
164+
}
165+
166+
override def removeAll(keys: IterableOnce[K]): HashMap[K, V] = {
167+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
168+
// in a minor release without breaking binary compatibility.
169+
//
170+
// In particular, `removeAll` could be optimized to avoid reallocating the `HashMap` wrapper of the rootNode on each
171+
// element in `keys`, and potentially to take advantage of the structure of `keys`, if it happens to be a HashSet
172+
// which would allow us to skip hashing keys all together.
173+
super.removeAll(keys)
174+
}
175+
176+
override def transform[W](f: (K, V) => W): HashMap[K, W] = {
177+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
178+
// in a minor release without breaking binary compatibility.
179+
//
180+
// In particular, `transform` could be optimized to traverse the trie node-by-node, swapping out the values of each
181+
// key with the result of applying `f`.
182+
super.transform(f)
183+
}
184+
185+
override def partition(p: ((K, V)) => Boolean): (HashMap[K, V], HashMap[K, V]) = {
186+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
187+
// in a minor release without breaking binary compatibility.
188+
//
189+
// In particular, `partition` could be optimized to traverse the trie node-by-node, splitting each node into two,
190+
// based on the result of applying `p` to its elements and subnodes.
191+
super.partition(p)
192+
}
193+
194+
override def take(n: Int): HashMap[K, V] = {
195+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
196+
// in a minor release without breaking binary compatibility.
197+
//
198+
// In particular, `take` could be optimized to construct a new trie structure by visiting each node, and including
199+
// those nodes in the resulting trie, until `n` total elements have been included.
200+
super.take(n)
201+
}
202+
203+
override def takeRight(n: Int): HashMap[K, V] = {
204+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
205+
// in a minor release without breaking binary compatibility.
206+
//
207+
// In particular, `take` could be optimized to construct a new trie structure by visiting each node in reverse, and
208+
// and including those nodes in the resulting trie, until `n` total elements have been included.
209+
super.takeRight(n)
210+
}
211+
212+
override def takeWhile(p: ((K, V)) => Boolean): HashMap[K, V] = {
213+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
214+
// in a minor release without breaking binary compatibility.
215+
//
216+
// In particular, `takeWhile` could be optimized to construct a new trie structure by visiting each node, and
217+
// including those nodes in the resulting trie, until `p` returns `false`
218+
super.takeWhile(p)
219+
}
220+
221+
override def dropWhile(p: ((K, V)) => Boolean): HashMap[K, V] = {
222+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
223+
// in a minor release without breaking binary compatibility.
224+
//
225+
// In particular, `dropWhile` could be optimized to construct a new trie structure by visiting each node, and
226+
// dropping those nodes in the resulting trie, until `p` returns `true`
227+
super.dropWhile(p)
228+
}
229+
230+
override def dropRight(n: Int): HashMap[K, V] = {
231+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
232+
// in a minor release without breaking binary compatibility.
233+
//
234+
// In particular, `dropRight` could be optimized to construct a new trie structure by visiting each node, in reverse
235+
// order, and dropping all nodes until `n` elements have been dropped
236+
super.dropRight(n)
237+
}
238+
239+
override def drop(n: Int): HashMap[K, V] = {
240+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
241+
// in a minor release without breaking binary compatibility.
242+
//
243+
// In particular, `dropRight` could be optimized to construct a new trie structure by visiting each node, and
244+
// dropping all nodes until `n` elements have been dropped
245+
super.drop(n)
246+
}
247+
248+
override def span(p: ((K, V)) => Boolean): (HashMap[K, V], HashMap[K, V]) = {
249+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
250+
// in a minor release without breaking binary compatibility.
251+
//
252+
// In particular, `scan` could be optimized to construct a new trie structure by visiting each node, and
253+
// keeping each node and element until `p` returns false, then including the remaining nodes in the second result.
254+
// This would avoid having to rebuild most of the trie, and would eliminate the need to perform hashing and equality
255+
// checks.
256+
super.span(p)
257+
}
156258
}
157259

158260
private[immutable] object MapNode {

src/library/scala/collection/immutable/ChampHashSet.scala

+72
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,78 @@ final class HashSet[A] private[immutable] (val rootNode: SetNode[A], val cachedJ
101101
//assert(hash == super.hashCode())
102102
hash
103103
}
104+
105+
override def diff(that: collection.Set[A]): HashSet[A] = {
106+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
107+
// in a minor release without breaking binary compatibility.
108+
super.diff(that)
109+
}
110+
111+
override def removeAll(that: IterableOnce[A]): HashSet[A] = {
112+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
113+
// in a minor release without breaking binary compatibility.
114+
super.removeAll(that)
115+
}
116+
117+
override def partition(p: A => Boolean): (HashSet[A], HashSet[A]) = {
118+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
119+
// in a minor release without breaking binary compatibility.
120+
super.partition(p)
121+
}
122+
123+
override def span(p: A => Boolean): (HashSet[A], HashSet[A]) = {
124+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
125+
// in a minor release without breaking binary compatibility.
126+
super.span(p)
127+
}
128+
129+
override protected[collection] def filterImpl(pred: A => Boolean, isFlipped: Boolean): HashSet[A] = {
130+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
131+
// in a minor release without breaking binary compatibility.
132+
super.filterImpl(pred, isFlipped)
133+
}
134+
135+
override def intersect(that: collection.Set[A]): HashSet[A] = {
136+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
137+
// in a minor release without breaking binary compatibility.
138+
super.intersect(that)
139+
}
140+
141+
override def take(n: Int): HashSet[A] = {
142+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
143+
// in a minor release without breaking binary compatibility.
144+
super.take(n)
145+
}
146+
147+
override def takeRight(n: Int): HashSet[A] = {
148+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
149+
// in a minor release without breaking binary compatibility.
150+
super.takeRight(n)
151+
}
152+
153+
override def takeWhile(p: A => Boolean): HashSet[A] = {
154+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
155+
// in a minor release without breaking binary compatibility.
156+
super.takeWhile(p)
157+
}
158+
159+
override def drop(n: Int): HashSet[A] = {
160+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
161+
// in a minor release without breaking binary compatibility.
162+
super.drop(n)
163+
}
164+
165+
override def dropRight(n: Int): HashSet[A] = {
166+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
167+
// in a minor release without breaking binary compatibility.
168+
super.dropRight(n)
169+
}
170+
171+
override def dropWhile(p: A => Boolean): HashSet[A] = {
172+
// This method has been preemptively overridden in order to ensure that an optimizing implementation may be included
173+
// in a minor release without breaking binary compatibility.
174+
super.dropWhile(p)
175+
}
104176
}
105177

106178
private[immutable] final object SetNode {

0 commit comments

Comments
 (0)