summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build/maven/scala-library-pom.xml29
-rw-r--r--src/library/scala/collection/mutable/HashTable.scala2
-rw-r--r--src/library/scala/concurrent/ConcurrentPackageObject.scala30
-rw-r--r--src/library/scala/concurrent/ExecutionContext.scala6
-rw-r--r--src/library/scala/concurrent/Future.scala33
-rw-r--r--src/library/scala/concurrent/impl/ExecutionContextImpl.scala42
-rw-r--r--src/library/scala/concurrent/impl/Future.scala30
-rw-r--r--src/library/scala/concurrent/impl/Promise.scala2
-rw-r--r--src/library/scala/math/BigDecimal.scala15
-rw-r--r--src/library/scala/math/BigInt.scala38
10 files changed, 157 insertions, 70 deletions
diff --git a/src/build/maven/scala-library-pom.xml b/src/build/maven/scala-library-pom.xml
index 673c3dfada..c3f8a4531c 100644
--- a/src/build/maven/scala-library-pom.xml
+++ b/src/build/maven/scala-library-pom.xml
@@ -30,17 +30,24 @@
<system>JIRA</system>
<url>https://issues.scala-lang.org/</url>
</issueManagement>
- <distributionManagement>
- <repository>
- <id>scala-tools.org</id>
- <url>@RELEASE_REPOSITORY@</url>
- </repository>
- <snapshotRepository>
- <id>scala-tools.org</id>
- <url>@SNAPSHOT_REPOSITORY@</url>
- <uniqueVersion>false</uniqueVersion>
- </snapshotRepository>
- </distributionManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.skife.com.typesafe.config</groupId>
+ <artifactId>typesafe-config</artifactId>
+ <version>0.3.0</version>
+ </dependency>
+ </dependencies>
+ <distributionManagement>
+ <repository>
+ <id>scala-tools.org</id>
+ <url>@RELEASE_REPOSITORY@</url>
+ </repository>
+ <snapshotRepository>
+ <id>scala-tools.org</id>
+ <url>@SNAPSHOT_REPOSITORY@</url>
+ <uniqueVersion>false</uniqueVersion>
+ </snapshotRepository>
+ </distributionManagement>
<developers>
<developer>
<id>lamp</id>
diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala
index cc0aed6963..06b7d40bfc 100644
--- a/src/library/scala/collection/mutable/HashTable.scala
+++ b/src/library/scala/collection/mutable/HashTable.scala
@@ -366,7 +366,7 @@ private[collection] object HashTable {
private[collection] final def newThreshold(_loadFactor: Int, size: Int) = ((size.toLong * _loadFactor) / loadFactorDenum).toInt
- private[collection] final def sizeForThreshold(_loadFactor: Int, thr: Int) = thr * loadFactorDenum / _loadFactor
+ private[collection] final def sizeForThreshold(_loadFactor: Int, thr: Int) = ((thr.toLong * loadFactorDenum) / _loadFactor).toInt
private[collection] final def capacity(expectedSize: Int) = if (expectedSize == 0) 1 else powerOfTwo(expectedSize)
diff --git a/src/library/scala/concurrent/ConcurrentPackageObject.scala b/src/library/scala/concurrent/ConcurrentPackageObject.scala
index ba98757906..f4744a8757 100644
--- a/src/library/scala/concurrent/ConcurrentPackageObject.scala
+++ b/src/library/scala/concurrent/ConcurrentPackageObject.scala
@@ -10,8 +10,8 @@ package scala.concurrent
-import java.util.concurrent.{ Executors, ExecutorService }
-import scala.concurrent.forkjoin.ForkJoinPool
+import java.util.concurrent.{ Executors, ExecutorService, ThreadFactory }
+import scala.concurrent.forkjoin.{ ForkJoinPool, ForkJoinWorkerThread }
import scala.util.{ Try, Success, Failure }
import scala.concurrent.util.Duration
import ConcurrentPackageObject._
@@ -24,14 +24,9 @@ abstract class ConcurrentPackageObject {
/** A global execution environment for executing lightweight tasks.
*/
lazy val executionContext =
- new impl.ExecutionContextImpl(getExecutorService)
-
- private[concurrent] def getExecutorService: AnyRef =
- if (scala.util.Properties.isJavaAtLeast("1.6")) {
- val vendor = scala.util.Properties.javaVmVendor
- if ((vendor contains "Oracle") || (vendor contains "Sun") || (vendor contains "Apple")) new ForkJoinPool
- else Executors.newCachedThreadPool()
- } else Executors.newCachedThreadPool()
+ new impl.ExecutionContextImpl()
+
+ private val currentExecutionContext = new ThreadLocal[ExecutionContext]
val handledFutureException: PartialFunction[Throwable, Throwable] = {
case t: Throwable if isFutureThrowable(t) => t
@@ -58,10 +53,10 @@ abstract class ConcurrentPackageObject {
/* concurrency constructs */
- def future[T](body: =>T)(implicit execCtx: ExecutionContext = executionContext): Future[T] =
+ def future[T](body: =>T)(implicit execctx: ExecutionContext = executionContext): Future[T] =
Future[T](body)
- def promise[T]()(implicit execCtx: ExecutionContext = executionContext): Promise[T] =
+ def promise[T]()(implicit execctx: ExecutionContext = executionContext): Promise[T] =
Promise[T]()
/** Wraps a block of code into an awaitable object. */
@@ -82,8 +77,8 @@ abstract class ConcurrentPackageObject {
* - InterruptedException - in the case that a wait within the blockable object was interrupted
* - TimeoutException - in the case that the blockable object timed out
*/
- def blocking[T](body: =>T)(implicit execCtx: ExecutionContext): T =
- executionContext.blocking(body)
+ def blocking[T](body: =>T): T =
+ blocking(body2awaitable(body), Duration.fromNanos(0))
/** Blocks on an awaitable object.
*
@@ -94,8 +89,11 @@ abstract class ConcurrentPackageObject {
* - InterruptedException - in the case that a wait within the blockable object was interrupted
* - TimeoutException - in the case that the blockable object timed out
*/
- def blocking[T](awaitable: Awaitable[T], atMost: Duration)(implicit execCtx: ExecutionContext = executionContext): T =
- executionContext.blocking(awaitable, atMost)
+ def blocking[T](awaitable: Awaitable[T], atMost: Duration): T =
+ currentExecutionContext.get match {
+ case null => Await.result(awaitable, atMost)
+ case ec => ec.internalBlockingCall(awaitable, atMost)
+ }
@inline implicit final def int2durationops(x: Int): DurationOps = new DurationOps(x)
}
diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala
index a206a2d4ea..f639f76dc9 100644
--- a/src/library/scala/concurrent/ExecutionContext.scala
+++ b/src/library/scala/concurrent/ExecutionContext.scala
@@ -26,10 +26,8 @@ trait ExecutionContext {
def execute[U](body: () => U): Unit
- def blocking[T](body: =>T): T
-
- def blocking[T](awaitable: Awaitable[T], atMost: Duration): T
-
+ def internalBlockingCall[T](awaitable: Awaitable[T], atMost: Duration): T
+
def reportFailure(t: Throwable): Unit
/* implementations follow */
diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala
index d73801aa90..8cecadc605 100644
--- a/src/library/scala/concurrent/Future.scala
+++ b/src/library/scala/concurrent/Future.scala
@@ -274,6 +274,18 @@ self =>
p.future
}
+ /** Used by for-comprehensions.
+ */
+ final def withFilter(p: T => Boolean): Future[T] = filter(p)
+ // final def withFilter(p: T => Boolean) = new FutureWithFilter[T](this, p)
+
+ // final class FutureWithFilter[+S](self: Future[S], p: S => Boolean) {
+ // def foreach(f: S => Unit): Unit = self filter p foreach f
+ // def map[R](f: S => R) = self filter p map f
+ // def flatMap[R](f: S => Future[R]) = self filter p flatMap f
+ // def withFilter(q: S => Boolean): FutureWithFilter[S] = new FutureWithFilter[S](self, x => p(x) && q(x))
+ // }
+
/** Creates a new future by mapping the value of the current future if the given partial function is defined at that value.
*
* If the current future contains a value for which the partial function is defined, the new future will also hold that value.
@@ -417,7 +429,26 @@ self =>
p.future
}
-
+
+ /** Creates a new `Future[S]` which is completed with this `Future`'s result if
+ * that conforms to `S`'s erased type or a `ClassCastException` otherwise.
+ */
+ def mapTo[S](implicit m: Manifest[S]): Future[S] = {
+ val p = newPromise[S]
+
+ onComplete {
+ case l: Failure[_] => p complete l.asInstanceOf[Try[S]]
+ case Success(t) =>
+ p complete (try {
+ Success(impl.Future.boxedType(m.erasure).cast(t).asInstanceOf[S])
+ } catch {
+ case e: ClassCastException => Failure(e)
+ })
+ }
+
+ p.future
+ }
+
/** Applies the side-effecting function to the result of this future, and returns
* a new future with the result of this future.
*
diff --git a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
index 5dc440f42b..2cfd6f22cd 100644
--- a/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
+++ b/src/library/scala/concurrent/impl/ExecutionContextImpl.scala
@@ -10,7 +10,7 @@ package scala.concurrent.impl
-import java.util.concurrent.{Callable, ExecutorService}
+import java.util.concurrent.{Callable, ExecutorService, Executors, ThreadFactory}
import scala.concurrent.forkjoin._
import scala.concurrent.{ExecutionContext, resolver, Awaitable, body2awaitable}
import scala.util.{ Try, Success, Failure }
@@ -18,8 +18,42 @@ import scala.concurrent.util.{ Duration }
-private[scala] class ExecutionContextImpl(val executorService: AnyRef) extends ExecutionContext {
+private[scala] class ExecutionContextImpl() extends ExecutionContext {
import ExecutionContextImpl._
+
+ val executorService: AnyRef = getExecutorService
+
+ // to ensure that the current execution context thread local is properly set
+ private def executorsThreadFactory = new ThreadFactory {
+ def newThread(r: Runnable) = new Thread(new Runnable {
+ override def run() {
+ currentExecutionContext.set(ExecutionContextImpl.this)
+ r.run()
+ }
+ })
+ }
+
+ // to ensure that the current execution context thread local is properly set
+ private def forkJoinPoolThreadFactory = new ForkJoinPool.ForkJoinWorkerThreadFactory {
+ def newThread(fjp: ForkJoinPool) = new ForkJoinWorkerThread(fjp) {
+ override def onStart() {
+ currentExecutionContext.set(ExecutionContextImpl.this)
+ }
+ }
+ }
+
+ private def getExecutorService: AnyRef =
+ if (scala.util.Properties.isJavaAtLeast("1.6")) {
+ val vendor = scala.util.Properties.javaVmVendor
+ if ((vendor contains "Oracle") || (vendor contains "Sun") || (vendor contains "Apple"))
+ new ForkJoinPool(
+ Runtime.getRuntime.availableProcessors(),
+ forkJoinPoolThreadFactory,
+ null,
+ false)
+ else
+ Executors.newCachedThreadPool(executorsThreadFactory)
+ } else Executors.newCachedThreadPool(executorsThreadFactory)
def execute(runnable: Runnable): Unit = executorService match {
case fj: ForkJoinPool =>
@@ -37,9 +71,7 @@ private[scala] class ExecutionContextImpl(val executorService: AnyRef) extends E
def run() = body()
})
- def blocking[T](body: =>T): T = blocking(body2awaitable(body), Duration.fromNanos(0))
-
- def blocking[T](awaitable: Awaitable[T], atMost: Duration): T = {
+ def internalBlockingCall[T](awaitable: Awaitable[T], atMost: Duration): T = {
Future.releaseStack(this)
awaitable.result(atMost)(scala.concurrent.Await.canAwaitEvidence)
diff --git a/src/library/scala/concurrent/impl/Future.scala b/src/library/scala/concurrent/impl/Future.scala
index 6833b2467f..1111aa4753 100644
--- a/src/library/scala/concurrent/impl/Future.scala
+++ b/src/library/scala/concurrent/impl/Future.scala
@@ -40,36 +40,6 @@ private[concurrent] trait Future[+T] extends scala.concurrent.Future[T] with Awa
def onComplete[U](func: Try[T] => U): this.type
- /** Creates a new Future[A] which is completed with this Future's result if
- * that conforms to A's erased type or a ClassCastException otherwise.
- */
- final def mapTo[T](implicit m: Manifest[T]) = {
- val p = new Promise.DefaultPromise[T]
-
- onComplete {
- case f @ Failure(t) => p complete f.asInstanceOf[Try[T]]
- case Success(v) =>
- p complete (try {
- Success(Future.boxedType(m.erasure).cast(v).asInstanceOf[T])
- } catch {
- case e: ClassCastException => Failure(e)
- })
- }
-
- p.future
- }
-
- /** Used by for-comprehensions.
- */
- final def withFilter(p: T => Boolean) = new FutureWithFilter[T](this, p)
-
- final class FutureWithFilter[+A](self: Future[A], p: A => Boolean) {
- def foreach(f: A => Unit): Unit = self filter p foreach f
- def map[B](f: A => B) = self filter p map f
- def flatMap[B](f: A => Future[B]) = self filter p flatMap f
- def withFilter(q: A => Boolean): FutureWithFilter[A] = new FutureWithFilter[A](self, x ⇒ p(x) && q(x))
- }
-
}
object Future {
diff --git a/src/library/scala/concurrent/impl/Promise.scala b/src/library/scala/concurrent/impl/Promise.scala
index c79b0d02cc..f05e306088 100644
--- a/src/library/scala/concurrent/impl/Promise.scala
+++ b/src/library/scala/concurrent/impl/Promise.scala
@@ -127,7 +127,7 @@ object Promise {
value.isDefined
}
- executor.blocking(concurrent.body2awaitable(awaitUnsafe(dur2long(atMost))), atMost)
+ blocking(concurrent.body2awaitable(awaitUnsafe(dur2long(atMost))), atMost)
}
def ready(atMost: Duration)(implicit permit: CanAwait): this.type =
diff --git a/src/library/scala/math/BigDecimal.scala b/src/library/scala/math/BigDecimal.scala
index c1f45eccfb..cb42b76b51 100644
--- a/src/library/scala/math/BigDecimal.scala
+++ b/src/library/scala/math/BigDecimal.scala
@@ -183,7 +183,8 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
override def equals (that: Any): Boolean = that match {
case that: BigDecimal => this equals that
case that: BigInt => this.toBigIntExact exists (that equals _)
- case _: Float | _: Double => unifiedPrimitiveEquals(that)
+ case that: Double => isValidDouble && toDouble == that
+ case that: Float => isValidFloat && toFloat == that
case _ => isValidLong && unifiedPrimitiveEquals(that)
}
override def isValidByte = noArithmeticException(toByteExact)
@@ -191,6 +192,18 @@ extends ScalaNumber with ScalaNumericConversions with Serializable {
override def isValidChar = isValidInt && toIntExact >= Char.MinValue && toIntExact <= Char.MaxValue
override def isValidInt = noArithmeticException(toIntExact)
def isValidLong = noArithmeticException(toLongExact)
+ /** Returns `true` iff this can be represented exactly by [[scala.Float]]; otherwise returns `false`.
+ */
+ def isValidFloat = {
+ val f = toFloat
+ !f.isInfinity && bigDecimal.compareTo(new java.math.BigDecimal(f)) == 0
+ }
+ /** Returns `true` iff this can be represented exactly by [[scala.Double]]; otherwise returns `false`.
+ */
+ def isValidDouble = {
+ val d = toDouble
+ !d.isInfinity && bigDecimal.compareTo(new java.math.BigDecimal(d)) == 0
+ }
private def noArithmeticException(body: => Unit): Boolean = {
try { body ; true }
diff --git a/src/library/scala/math/BigInt.scala b/src/library/scala/math/BigInt.scala
index 8a53afaa62..dbec30b2fe 100644
--- a/src/library/scala/math/BigInt.scala
+++ b/src/library/scala/math/BigInt.scala
@@ -20,6 +20,7 @@ object BigInt {
private val minCached = -1024
private val maxCached = 1024
private val cache = new Array[BigInt](maxCached - minCached + 1)
+ private val minusOne = BigInteger.valueOf(-1)
@deprecated("Use Long.MinValue", "2.9.0")
val MinLong = BigInt(Long.MinValue)
@@ -122,6 +123,8 @@ class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericCo
override def equals(that: Any): Boolean = that match {
case that: BigInt => this equals that
case that: BigDecimal => that.toBigIntExact exists (this equals _)
+ case that: Double => isValidDouble && toDouble == that
+ case that: Float => isValidFloat && toFloat == that
case x => isValidLong && unifiedPrimitiveEquals(x)
}
override def isValidByte = this >= Byte.MinValue && this <= Byte.MaxValue
@@ -129,6 +132,41 @@ class BigInt(val bigInteger: BigInteger) extends ScalaNumber with ScalaNumericCo
override def isValidChar = this >= Char.MinValue && this <= Char.MaxValue
override def isValidInt = this >= Int.MinValue && this <= Int.MaxValue
def isValidLong = this >= Long.MinValue && this <= Long.MaxValue
+ /** Returns `true` iff this can be represented exactly by [[scala.Float]]; otherwise returns `false`.
+ */
+ def isValidFloat = {
+ val bitLen = bitLength
+ (bitLen <= 24 ||
+ {
+ val lowest = lowestSetBit
+ bitLen <= java.lang.Float.MAX_EXPONENT + 1 && // exclude this < -2^128 && this >= 2^128
+ lowest >= bitLen - 24 &&
+ lowest < java.lang.Float.MAX_EXPONENT + 1 // exclude this == -2^128
+ }
+ ) && !bitLengthOverflow
+ }
+ /** Returns `true` iff this can be represented exactly by [[scala.Double]]; otherwise returns `false`.
+ */
+ def isValidDouble = {
+ val bitLen = bitLength
+ (bitLen <= 53 ||
+ {
+ val lowest = lowestSetBit
+ bitLen <= java.lang.Double.MAX_EXPONENT + 1 && // exclude this < -2^1024 && this >= 2^1024
+ lowest >= bitLen - 53 &&
+ lowest < java.lang.Double.MAX_EXPONENT + 1 // exclude this == -2^1024
+ }
+ ) && !bitLengthOverflow
+ }
+ /** Some implementations of java.math.BigInteger allow huge values with bit length greater than Int.MaxValue .
+ * The BigInteger.bitLength method returns truncated bit length in this case .
+ * This method tests if result of bitLength is valid.
+ * This method will become unnecessary if BigInt constructors reject huge BigIntegers.
+ */
+ private def bitLengthOverflow = {
+ val shifted = bigInteger.shiftRight(Int.MaxValue)
+ (shifted.signum != 0) && !(shifted equals BigInt.minusOne)
+ }
protected[math] def isWhole = true
def underlying = bigInteger