| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|\ |
|
| |
| |
| |
| | |
When dealing with mutable collections, it is not safe to assume iterators will remain consistent when the collection is modified mid-traversal. The bug reported in SI-9497 is very similar to SI-7269, "ConcurrentModificationException when filtering converted Java HashMap". Then, only the `retain` method was fixed. This commit fixes `clear`, which had the same problem.
|
|\|
| |
| |
| |
| |
| |
| |
| | |
Conflicts:
build.number
src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
src/library/scala/collection/Iterator.scala
versions.properties
|
| |
| |
| |
| |
| | |
- there is no need for explicit links with [[ and ]]
- there is no need for explicit backquoting
|
|/
|
|
|
|
|
|
|
|
| |
Switched to `Vector` for the default `MapLike`/`SetLike`, then back again in `mutable.MapLike`/`mutable.SetLike`.
Preliminary performance testing indicates an across-the-board improvement due to cutting out a great deal of indirection. In the case of empty immutable maps or sets, the improvement is enormous: it quickly returns Vector.empty instead of jumping through all sorts of hoops to eventually create an empty `ArrayBuffer`.
One possible downside is that `Vector` is pretty memory-hungry for small collections. Need to evalute this; rather than abandoning this change, it's probably better to make `Vector` smarter about small collections.
Also fixed test with literal "ArrayBuffer" in output (`s/ArrayBuffer/Vector/g`).
|
|
|
|
| |
Fixed advice; it was already there in mutable.SetLike but a case sensitivity error kept it from appearing.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Collections library tidying, part one: scripting.
Everything in scala.collection.scripting is deprecated now, along with the
<< method that is implemented in a few other classes. Scripting does not
seem used at all, and anyone who did can easily write a wrapper that does
the same thing.
Deprecated *Proxy collections.
The only place proxies were used in the library was in swing.ListView, and
that was easy to change to a lazy val.
Proxy itself is used in ScalaNumberProxy and such, so it was left
undeprecated.
Deprecated Synchronized* traits from collections.
Synchronizability does not compose well, and it requires careful examination
of every method (which has not actually been done).
Places where the Scala codebase needs to be fixed (eventually) include:
scala.reflect.internal.util.Statistics$QuantMap
scala.tools.nsc.interactive.Global (several places)
Deprecated LinkedList (including Double- and -Like variants).
Interface is idiosyncratic and dangerously low-level. Although some
low-level functionality of this sort would be useful, this doesn't seem
to be the ideal implementation.
Also deprecated the extractFirst method in Queue as it exposes LinkedList.
Cannot shift internal representations away from LinkedList at this time
because of that method.
Deprecated non-finality of several toX collection methods.
Improved documentation of most toX collection methods to describe what the
expectation is for their behavior. Additionally deprecated overriding of
- toIterator in IterableLike (should always forward to iterator)
- toTraversable in TraversableLike (should always return self)
- toIndexedSeq in immutable.IndexedSeq (should always return self)
- toMap in immutable.Map (should always return self)
- toSet in immutable.Set (should always return self)
Did not do anything with IterableLike.toIterable or Seq/SeqLike.toSeq since
for some odd reason immutable.Range overrides those.
Deprecated Forwarders from collections.
Forwarding, without an automatic mechanism to keep up to date with changes
in the forwarded class, is inherently unreliable. Absent a mechanism to
keep current, they're deprecated. ListBuffer is the only class in the
collections library that uses forwarders, and that functionality can be
rolled into ListBuffer itself.
Deprecating immutable set/map adaptors.
They're a bad idea (barring compiler support) for the same reason that all
the other adaptors are a bad idea: they get out of date and probably have a
variety of performance bugs.
Deprecated inheritance from leaf classes in immutable collections.
Inheriting from leaf-classes in immutable collections is rarely a good idea
since whenever you use any interesting collections method you'll revert to
the original class. Also, the methods are often designed to work with only
particular behavior, and an override would be difficult (at best) to make
work. Fortunately, people seem to have realized this and there are few to
no cases of people extending PagedSeq and TreeSet and the like.
Note that in many cases the classes will become sealed not final.
Deprecated overriding of methods and inheritance from various mutable
collections.
Some mutable collections seem unsuited for overriding since to override
anything interesting you would need vast knowledge of internal data
structures and/or access to private methods. These include
- ArrayBuilder.ofX classes.
- ArrayOps
- Some methods of BitSet (moved others from private to protected final)
- Some methods of HashTable and FlatHashTable
- Some methods of HashMap and HashSet (esp += and -= which just forward)
- Some methods of other maps and sets (LinkedHashX, ListMap, TreeSet)
- PriorityQueue
- UnrolledBuffer
This is a somewhat aggressive deprecation, the theory being better to try it
out now and back off if it's too much than not attempt the change and be
stuck with collections that can neither be safely inherited nor have
implementation details changed.
Note that I have made no changes--in this commit--which would cause
deprecation warnings in any of the Scala projects available on Maven (at
least as gathered by Adriaan). There are deprecation warnings induced
within the library (esp. for classes/traits that should become static) and
the compiler. I have not attempted to fix all the deprecations in the
compiler as some of them touch the IDE API (but these mostly involved
Synchronized which is inherently unsafe, so this should be fixed
eventually in coordination with the IDE code base(s)).
Updated test checks to include new deprecations.
Used a higher level implementation for messages in JavapClass.
|
|\
| |
| |
| |
| | |
Conflicts:
src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
`MapLike#retains` contains a for-comprehension that relied on the strict
`filter` by its generator. You can't, in general, iterate a mutable map
and remove items in the same pass.
Here's the history of the desugaring of:
def retain[A, B](thiz: mutable.Map[A, B])(p: (A, B) => Boolean): thiz.type = {
thiz.foreach {
case (k, v) =>
if (p(k, v)) thiz -= k
}
Before regression (c82ecabad6~1):
thiz.filter(((check$ifrefutable$1) => check$ifrefutable$1: @scala.unchecked match {
case scala.Tuple2((k @ _), (v @ _)) => true
case _ => false
})).withFilter(((x$1) => x$1: @scala.unchecked match {
case scala.Tuple2((k @ _), (v @ _)) => p(k, v).unary_$bang
})).foreach(((x$2) => x$2: @scala.unchecked match {
case scala.Tuple2((k @ _), (v @ _)) => thiz.$minus$eq(k)
}));
After regression (c82ecabad6, which incorrectly assumed in the parser that
no filter is required for isInstanceOf[Tuple2])
thiz.withFilter(((x$1) => x$1: @scala.unchecked match {
case scala.Tuple2((k @ _), (v @ _)) => p(k, v).unary_$bang
})).foreach(((x$2) => x$2: @scala.unchecked match {
case scala.Tuple2((k @ _), (v @ _)) => thiz.$minus$eq(k)
}));
After the reversion of c82ecabad6, v2.10.2
This is also after 365bb2b4e, which uses `withFilter` rather than `filter`.
thiz.withFilter(((check$q$1) => check$ifrefutable$1: @scala.unchecked match {
case scala.Tuple2((k @ _), (v @ _)) => true
case _ => false
})).withFilter(((x$1) => x$1: @scala.unchecked match {
case scala.Tuple2((k @ _), (v @ _)) => p(k, v).unary_$bang
})).foreach(((x$2) => x$2: @scala.unchecked match {
case scala.Tuple2((k @ _), (v @ _)) => thiz.$minus$eq(k)
}));
This commit does the same as `SetLike#retains`, and converts the map to
an immutable list before the rest of the operation.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Confusing, now-it-happens now-it-doesn't mysteries lurk
in the darkness. When scala packages are declared like this:
package scala.collection.mutable
Then paths relative to scala can easily be broken via the unlucky
presence of an empty (or nonempty) directory. Example:
// a.scala
package scala.foo
class Bar { new util.Random }
% scalac ./a.scala
% mkdir util
% scalac ./a.scala
./a.scala:4: error: type Random is not a member of package util
new util.Random
^
one error found
There are two ways to play defense against this:
- don't use relative paths; okay sometimes, less so others
- don't "opt out" of the scala package
This commit mostly pursues the latter, with occasional doses
of the former.
I created a scratch directory containing these empty directories:
actors annotation ant api asm beans cmd collection compat
concurrent control convert docutil dtd duration event factory
forkjoin generic hashing immutable impl include internal io
logging macros man1 matching math meta model mutable nsc parallel
parsing partest persistent process pull ref reflect reify remote
runtime scalap scheduler script swing sys text threadpool tools
transform unchecked util xml
I stopped when I could compile the main src directories
even with all those empties on my classpath.
|
| | |
|
|/ |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
These things are killing me. Constructions like
package scala.foo.bar.baz
import foo.Other
DO NOT WORK in general. Such files are not really in the
"scala" package, because it is not declared
package scala
package foo.bar.baz
And there is a second problem: using a relative path name means
compilation will fail in the presence of a directory of the same
name, e.g.
% mkdir reflect
% scalac src/reflect/scala/reflect/internal/util/Position.scala
src/reflect/scala/reflect/internal/util/Position.scala:9: error:
object ClassTag is not a member of package reflect
import reflect.ClassTag
^
src/reflect/scala/reflect/internal/util/Position.scala:10: error:
object base is not a member of package reflect
import reflect.base.Attachments
^
As a rule, do not use relative package paths unless you have
explicitly imported the path to which you think you are relative.
Better yet, don't use them at all. Unfortunately they mostly work
because scala variously thinks everything scala.* is in the scala
package and/or because you usually aren't bootstrapping and it
falls through to an existing version of the class already on the
classpath.
Making the paths explicit is not a complete solution -
in particular, we remain enormously vulnerable to any directory
or package called "scala" which isn't ours - but it greatly
limts the severity of the problem.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The @migration annotation can now be used like @deprecation.
Old syntax is still supported, but deprecated.
Improve wording and consistency of migration messages, migration
warnings also print the version in which the change occurred now.
Partially fixes SI-4990.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Adding some Sets/Maps to perRunCaches, and eliminating ambiguously named
imports.
Did a tour of the compiler adding a few longer-lived mutable structures
to the per-run cache clearing mechanism. Some of these were not a big
threat, but there is (almost) literally no cost to tracking them and the
fewer mutable structures which are created "lone wolf style" the easier
it is to spot the one playing by his own rules.
While I was at it I followed through on long held ambition to eliminate
the importing of highly ambiguous names like "Map" and "HashSet" from
the mutable and immutable packages. I didn't quite manage elimination
but it's pretty close. Something potentially as pernicious which I
didn't do much about is this import:
import scala.collection._
Imagine coming across that one on lines 407 and 474 of a 1271 file.
That's not cool. Some poor future programmer will be on line 1100 and
use "Map[A, B]" in some function and only after the product has shipped
will it be discovered that the signature is wrong and the rocket will
now be crashing into the mountainside straightaway. No review.
|
|
|
|
|
|
|
| |
After having to update the code for someone else, ran damarau
levenshtein on trunk again. Patchwise, I guess correcting spelling
errors in comments is about as safe as it gets. No review.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Refactoring the collections api to support differentiation between
referring to a sequential collection and a parallel collection, and to
support referring to both types of collections.
New set of traits Gen* are now superclasses of both their * and Par* subclasses. For example, GenIterable is a superclass of both Iterable and ParIterable. Iterable and ParIterable are not in a subclassing relation. The new class hierarchy is illustrated below (simplified, not all relations and classes are shown):
TraversableOnce --> GenTraversableOnce
^ ^
| |
Traversable --> GenTraversable
^ ^
| |
Iterable --> GenIterable <-- ParIterable
^ ^ ^
| | |
Seq --> GenSeq <-- ParSeq
(the *Like, *View and *ViewLike traits have a similar hierarchy)
General views extract common view functionality from parallel and
sequential collections.
This design also allows for more flexible extensions to the collections
framework. It also allows slowly factoring out common functionality up
into Gen* traits.
From now on, it is possible to write this:
import collection._
val p = parallel.ParSeq(1, 2, 3)
val g: GenSeq[Int] = p // meaning a General Sequence
val s = g.seq // type of s is Seq[Int]
for (elem <- g) {
// do something without guarantees on sequentiality of foreach
// this foreach may be executed in parallel
}
for (elem <- s) {
// do something with a guarantee that foreach is executed in order, sequentially
}
for (elem <- p) {
// do something concurrently, in parallel
}
This also means that some signatures had to be changed. For example,
method `flatMap` now takes `A => GenTraversableOnce[B]`, and `zip` takes
a `GenIterable[B]`.
Also, there are mutable & immutable Gen* trait variants. They have
generic companion functionality.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Removing toPar* methods, since we've agreed they're difficult to: -
underestand - maintain
Also, changed the docs and some tests appropriately.
Description:
1) Every collection is now parallelizable - switch to the parallel version of the collection is done via `par`.
- Traversable collections and iterators have `par` return a parallel
- collection of type `ParIterable[A]` with the implementation being the
- representative of `ParIterable`s (currently, `ParArray`). Iterable
- collections do the same thing. Sequences refine `par`'s returns type
- to `ParSeq[A]`. Maps and sets do a similar thing.
The above means that the contract for `par` changed - it is no longer guaranteed to be O(1), nor reflect the same underlying data, as was the case for mutable collections before. Method `par` is now at worst linear.
Furthermore, specific collection implementations override `par` to a more efficient alternative - instead of copying the dataset, the dataset is shared between the old and the new version. Implementation complexity may be sublinear or constant in these cases, and the underlying data structure may be shared. Currently, these data structures include parallel arrays, maps and sets, vectors, hash trie maps and sets, and ranges.
Finally, parallel collections implement `par` trivially.
2) Methods `toMap`, `toSet`, `toSeq` and `toIterable` have been refined
for parallel collections to switch between collection types, however,
they never switch an implementation from parallel to sequential. They
may or may not copy the elements, as is the case with sequential
variants of these methods.
3) The preferred way to switch between different collection types,
whether maps, sets and seqs, or parallel and sequential, is now via use
of methods `toIterable`, `toSeq`, `toSet` and `toMap` in combination
with `par` and `seq`.
Review by odersky.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
While investigating the cause of #3984, discovered that set hashcodes
were being calculated like:
elems map (_.hashCode) sum
This looks totally correct, except that because of set+map semantics it
drops all the duplicate hashcodes and therefore calculates the wrong
sum anytime there are unequal elements with equal hashcodes. If we're
married to the set+map semantics (and I don't know what could be done
about it) I had better get a proper -Xlint going because this is one of
those traps which shoots bees out of its mouth. No review.
|
| |
|
| |
|
| |
|
|
|
|
|
| |
Removed more than 3400 svn '$Id' keywords and related junk.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
to BufferLike (++ and similar now create a new collection.)
Removed MapLikeBase. Annotated all the methods in mutable.{ Map, Set }
which mutated in-place in 2.7 to note that they create new
collections, and implemented same.
At this point the only +/- like method which mutates in place which I am
aware of is BufferLike.+ (see source comment for my observations.)
Also tweaked some collections return types as necessitated by these
changes, such as mutable.Set.clone() now returning "This" rather than
mutable.Set[A].
References #3089, closes #3179. Review by odersky.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Added -Xmigration option and @migration annotation. At present it will
warn about the following changes from 2.7 to 2.8:
Stack iterator order reversed
mutable.Set.map returns a Set and thus discards duplicates
A case 'x @ Pattern' matches differently than 'Pattern'
Review by odersky.
|
|
|
|
|
| |
lost of documentation and some small adjustments to collection classes.
|
| |
|
| |
|
|
|