Skip to content

Commit

Permalink
Merge pull request #54 from isaacl/fixLocalRandom2
Browse files Browse the repository at this point in the history
Fix ThreadLocalRandom, again
  • Loading branch information
ornicar authored Sep 14, 2024
2 parents aa2235c + a22ef54 commit 1b3a95d
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 26 deletions.
2 changes: 0 additions & 2 deletions lila/src/main/scala/Maths.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package scalalib

import scalalib.ThreadLocalRandom

import scala.Numeric.Implicits.*
import scala.reflect.ClassTag
import scala.util.Sorting
Expand Down
27 changes: 17 additions & 10 deletions lila/src/main/scala/Random.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@ package scalalib

import scala.collection.mutable.StringBuilder

private final val store =
java.lang.ThreadLocal.withInitial(() => RandomApi(java.util.concurrent.ThreadLocalRandom.current))
object ThreadLocalRandom extends RandomApi:
protected def impl = java.util.concurrent.ThreadLocalRandom.current()

def ThreadLocalRandom = store.get
object SecureRandom extends RandomApi:
protected val impl = java.security.SecureRandom.getInstanceStrong()

val SecureRandom = RandomApi(java.security.SecureRandom())
private abstract class RandomApi:
protected def impl: java.util.Random

final class RandomApi(impl: java.util.Random):

export impl.{ nextBoolean, nextDouble, nextFloat, nextGaussian, nextInt, nextLong }
def nextBoolean() = impl.nextBoolean
def nextDouble() = impl.nextDouble
def nextFloat() = impl.nextFloat
def nextGaussian() = impl.nextGaussian
def nextInt() = impl.nextInt
def nextInt(n: Int) = impl.nextInt(n)
def nextLong() = impl.nextLong
def nextLong(l: Long) = impl.nextLong(l)

def nextBytes(len: Int): Array[Byte] =
val bytes = new Array[Byte](len)
Expand All @@ -20,7 +27,7 @@ final class RandomApi(impl: java.util.Random):

private val chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
private inline def nextAlphanumeric(): Char =
chars.charAt(nextInt(chars.length)) // Constant time
chars.charAt(impl.nextInt(chars.length)) // Constant time

def nextString(len: Int): String =
val sb = StringBuilder(len)
Expand All @@ -31,9 +38,9 @@ final class RandomApi(impl: java.util.Random):
scala.util.Random(impl).shuffle(xs)

def oneOf[A](vec: Vector[A]): Option[A] =
if vec.nonEmpty then vec.lift(nextInt(vec.size)) else None
if vec.nonEmpty then vec.lift(impl.nextInt(vec.size)) else None

// odds(1) = 100% true
// odds(2) = 50% true
// odds(3) = 33% true
def odds(n: Int): Boolean = nextInt(n) == 0
def odds(n: Int): Boolean = impl.nextInt(n) == 0
2 changes: 0 additions & 2 deletions lila/src/main/scala/cuteName.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package scalalib
package cuteName

import scalalib.ThreadLocalRandom

// children friendly names only
// this is used by /class
object CuteNameGenerator:
Expand Down
12 changes: 0 additions & 12 deletions lila/src/test/scala/RandomTest.scala

This file was deleted.

0 comments on commit 1b3a95d

Please sign in to comment.