diff options
author | Paul Phillips <paulp@improving.org> | 2011-03-11 12:13:58 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-03-11 12:13:58 +0000 |
commit | be49752855a1a6997d4112eeff351e1c119a8a93 (patch) | |
tree | ee2cef3642b675420d47ff30bda9ddb2b74f1c30 /src/library/scala/collection/IndexedSeqLike.scala | |
parent | 67c461b2d9c19d51e40e1f3ff23455cead1413b5 (diff) | |
download | scala-be49752855a1a6997d4112eeff351e1c119a8a93.tar.gz scala-be49752855a1a6997d4112eeff351e1c119a8a93.tar.bz2 scala-be49752855a1a6997d4112eeff351e1c119a8a93.zip |
A patch for views. Most relevant change:
Almost all view classes now list parents like
trait Appended[B >: A] extends super.Appended[B] with Transformed[B]
instead of the former
trait Appended[B >: A] extends Transformed[B] with super.Appended[B]
because as it was, the implementation of foreach in
TraversableViewLike#Transformed was repeatedly trumping overrides found
in e.g. IterableLike. This change was not without its own consequences,
and much of the rest of the patch is dealing with that. A more general
issue is clearly revealed here: there is no straightforward way to deal
with trait composition and overrides when some methods should prefer B
over A and some the reverse. (It's more like A through Z in this case.)
That closes #4279, with some views being five orders of magnitude slower
than necessary. There is a test that confirms they'll stay performance
neighbors.
In the view classes (Zipped, Mapped, etc.) I attended to them with
comb and brush until they were reasonably consistent. I only use
"override" where necessary and throw in some "final" in the interests
of trying to anchor the composition outcome. I also switched the
newSliced, newZipped, etc. methods to use early init syntax since a
number have abstract vals and I found at least one bug originating with
uninitialized access.
There was a piece of a parallel collections scalacheck test failing,
which
I disabled out of expedience - am emailing prokopec.
There is plenty of work left to do but paulp must get back to other 2.9
issues. This is the Zurich->SF airplane patch. No review.
Diffstat (limited to 'src/library/scala/collection/IndexedSeqLike.scala')
-rw-r--r-- | src/library/scala/collection/IndexedSeqLike.scala | 65 |
1 files changed, 29 insertions, 36 deletions
diff --git a/src/library/scala/collection/IndexedSeqLike.scala b/src/library/scala/collection/IndexedSeqLike.scala index 952721a73f..7e948208d2 100644 --- a/src/library/scala/collection/IndexedSeqLike.scala +++ b/src/library/scala/collection/IndexedSeqLike.scala @@ -39,7 +39,8 @@ import scala.annotation.tailrec * @define willNotTerminateInf * @define mayNotTerminateInf */ -trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => +trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { + self => override protected[this] def thisCollection: IndexedSeq[A] = this.asInstanceOf[IndexedSeq[A]] override protected[this] def toCollection(repr: Repr): IndexedSeq[A] = repr.asInstanceOf[IndexedSeq[A]] @@ -48,35 +49,41 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => * multiple `take`, `drop`, and `slice` operations on this iterator are bunched * together for better efficiency. */ + // pre: start >= 0, end <= self.length @SerialVersionUID(1756321872811029277L) protected class Elements(start: Int, end: Int) extends BufferedIterator[A] with Serializable { - private var i = start + private def initialSize = if (end <= start) 0 else end - start + private var index = start + private def available = (end - index) max 0 - def hasNext: Boolean = i < end + def hasNext: Boolean = index < end - def next: A = - if (i < end) { - val x = self(i) - i += 1 - x - } else Iterator.empty.next + def next: A = { + if (index >= end) + Iterator.empty.next - def head = - if (i < end) self(i) else Iterator.empty.next + val x = self(index) + index += 1 + x + } - /** $super - * '''Note:''' `drop` is overridden to enable fast searching in the middle of indexed sequences. - */ - override def drop(n: Int): Iterator[A] = - if (n > 0) new Elements(i + n, end) else this + def head = { + if (index >= end) + Iterator.empty.next + + self(index) + } - /** $super - * '''Note:''' `take` is overridden to be symmetric to `drop`. - */ + override def drop(n: Int): Iterator[A] = + if (n <= 0) new Elements(index, end) + else if (index + n >= end) new Elements(end, end) + else new Elements(index + n, end) override def take(n: Int): Iterator[A] = - if (n <= 0) Iterator.empty.buffered - else if (i + n < end) new Elements(i, i + n) - else this + if (n <= 0) Iterator.empty + else if (n <= available) new Elements(index, index + n) + else new Elements(index, end) + override def slice(from: Int, until: Int): Iterator[A] = + this take until drop from } override /*IterableLike*/ @@ -88,19 +95,5 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => copyToBuffer(result) result } - - -/* - override /*SeqLike*/ - def view = new IndexedSeqView[A, Repr] { - protected lazy val underlying = self.repr - override def iterator = self.iterator - override def length = self.length - override def apply(idx: Int) = self.apply(idx) - } - - override /*SeqLike*/ - def view(from: Int, until: Int) = view.slice(from, until) -*/ } |