All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.compat.java8.converterImpl.StepsWithTail.scala Maven / Gradle / Ivy

The newest version!
package scala.compat.java8.converterImpl

import java.util.Spliterator
import scala.compat.java8.collectionImpl._
import Stepper._

/** Abstracts all the generic operations of stepping over a collection with a fast tail operation.
  * Because of how Java 8 streams subdivide their spliterators, we do this by chunking a bit at
  * a time, generating a long chain of chunks.  These won't necessarily all be the same size,
  * but if there are enough hopefully it won't matter.
  *
  * Subclasses MUST decrement `maxN` when consuming elements, or this will not work!
  */
private[java8] abstract class AbstractStepsWithTail[CC >: Null, Sub >: Null, Semi <: Sub](final protected var underlying: CC, final protected var maxN: Long) {
  private var nextChunkSize: Int = 0
  protected def myIsEmpty(cc: CC): Boolean
  protected def myTailOf(cc: CC): CC
  def prepareParallelOperation(): this.type = {
    if (maxN >= Int.MaxValue && nextChunkSize == 0) {
      // Need parallel context to know whether to run this or not!
      var u = underlying
      var i = 0
      while (i < 1024 && !myIsEmpty(u)) { u = myTailOf(u); i += 1 }
      if (i < 1024) maxN = i
      else nextChunkSize = 64   // Guaranteed at least 16 chunks
    }
    this
  }
  def semiclone(chunk: Int): Semi
  def characteristics(): Int = if (maxN < Int.MaxValue) Ordered | Sized | SubSized else Ordered
  def estimateSize(): Long = if (maxN < Int.MaxValue) maxN else Long.MaxValue
  def hasNext(): Boolean = if (maxN < Int.MaxValue) maxN > 0 else if (myIsEmpty(underlying)) { maxN = 0; false } else true
  def substep(): Sub = {
    prepareParallelOperation()
    maxN match {
      case x if x < 2 => null
      case x if x >= Int.MaxValue =>
        var u = underlying
        var i = 0
        val n = (nextChunkSize & 0xFFFFFFFC)  // Use bottom two bits to count up
        while (i < n && !myIsEmpty(u)) {
          u = myTailOf(u)
          i += 1
        }
        if (myIsEmpty(u)) {
          maxN = i
          substep()  // Different branch now, recursion is an easy way to get it
        }
        else {
          val sub = semiclone(n)
          underlying = u
          if ((nextChunkSize & 3) == 3) nextChunkSize = if (n < 0x40000000) 2*n else n else nextChunkSize += 1
          sub
        }
      case x =>
        var half = x.toInt >>> 1
        val sub = semiclone(half)
        maxN -= half
        while (half > 0) { underlying = myTailOf(underlying); half -= 1 }
        sub
    }
  }
}

/** Abstracts the operation of stepping over a generic indexable collection */
private[java8] abstract class StepsWithTail[A, CC >: Null, STA >: Null <: StepsWithTail[A, CC, _]](_underlying: CC, _maxN: Long)
  extends AbstractStepsWithTail[CC, AnyStepper[A], STA](_underlying, _maxN)
  with AnyStepper[A]
{}

/** Abstracts the operation of stepping over an indexable collection of Doubles */
private[java8] abstract class StepsDoubleWithTail[CC >: Null, STD >: Null <: StepsDoubleWithTail[CC, _]](_underlying: CC, _maxN: Long)
  extends AbstractStepsWithTail[CC, DoubleStepper, STD](_underlying, _maxN)
  with DoubleStepper
{}

/** Abstracts the operation of stepping over an indexable collection of Ints */
private[java8] abstract class StepsIntWithTail[CC >: Null, STI >: Null <: StepsIntWithTail[CC, _]](_underlying: CC, _maxN: Long)
  extends AbstractStepsWithTail[CC, IntStepper, STI](_underlying, _maxN)
  with IntStepper
{}

/** Abstracts the operation of stepping over an indexable collection of Longs */
private[java8] abstract class StepsLongWithTail[CC >: Null, STL >: Null <: StepsLongWithTail[CC, _]](_underlying: CC, _maxN: Long)
  extends AbstractStepsWithTail[CC, LongStepper, STL](_underlying, _maxN)
  with LongStepper
{}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy