summaryrefslogtreecommitdiff
path: root/src/library/scala/collection/IndexedSeqLike.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-03-11 12:13:58 +0000
committerPaul Phillips <paulp@improving.org>2011-03-11 12:13:58 +0000
commitbe49752855a1a6997d4112eeff351e1c119a8a93 (patch)
treeee2cef3642b675420d47ff30bda9ddb2b74f1c30 /src/library/scala/collection/IndexedSeqLike.scala
parent67c461b2d9c19d51e40e1f3ff23455cead1413b5 (diff)
downloadscala-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.scala65
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)
-*/
}