scala.collection.immutable.TreeMap Scala Examples

The following examples show how to use scala.collection.immutable.TreeMap. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.
Example 1
Source File: OAuth.scala    From iot-demo   with Apache License 2.0 5 votes vote down vote up
package core

import java.net.URLEncoder
import java.nio.charset.Charset
import javax.crypto

import org.parboiled.common.Base64
import org.slf4j.LoggerFactory
import spray.http.HttpHeaders.RawHeader
import spray.http.{ContentType, HttpEntity, HttpRequest, MediaTypes}

import scala.collection.immutable.TreeMap

object OAuth {
  private[this] val log = LoggerFactory.getLogger(getClass)

  def oAuthAuthorizer(consumer: Consumer, token: Token): HttpRequest => HttpRequest = {
    // construct the key and cryptographic entity
    val SHA1 = "HmacSHA1"
    val keyString = percentEncode(consumer.secret :: token.secret :: Nil)
    val key = new crypto.spec.SecretKeySpec(bytes(keyString), SHA1)
    val mac = crypto.Mac.getInstance(SHA1)

    { httpRequest: HttpRequest =>
      val timestamp = (System.currentTimeMillis / 1000).toString
      // nonce is unique enough for our purposes here
      val nonce = System.nanoTime.toString

      // pick out x-www-form-urlencoded body
      val (requestParams, newEntity) = httpRequest.entity match {
        case [email protected](ContentType(MediaTypes.`application/x-www-form-urlencoded`, _), data) =>
          log.info("request {}", request)
          val params = data.asString.split("&")
          val pairs = params.map { param =>
            val p = param.split("=")
            p(0) -> percentEncode(p(1))
          }
          (pairs.toMap, HttpEntity(ContentType(MediaTypes.`application/x-www-form-urlencoded`), "%s=%s" format(pairs(0)._1, pairs(0)._2)))
        case e => (Map(), e)
      }

      // prepare the OAuth parameters
      val oauthParams = Map(
        "oauth_consumer_key" -> consumer.key,
        "oauth_signature_method" -> "HMAC-SHA1",
        "oauth_timestamp" -> timestamp,
        "oauth_nonce" -> nonce,
        "oauth_token" -> token.value,
        "oauth_version" -> "1.0"
      )

      // construct parts of the signature base string
      val encodedOrderedParams = (TreeMap[String, String]() ++ oauthParams ++ requestParams) map { case (k, v) => k + "=" + v } mkString "&"
      val url = httpRequest.uri.toString()
      // construct the signature base string
      val signatureBaseString = percentEncode(httpRequest.method.toString() :: url :: encodedOrderedParams :: Nil)

      mac.init(key)
      val sig = Base64.rfc2045().encodeToString(mac.doFinal(bytes(signatureBaseString)), false)
      mac.reset()

      val oauth = TreeMap[String, String]() ++ (oauthParams + ("oauth_signature" -> percentEncode(sig))) map { case (k, v) => "%s=\"%s\"" format(k, v) } mkString ", "

      // return the signed request
      httpRequest.withHeaders(List(RawHeader("Authorization", "OAuth " + oauth))).withEntity(newEntity)
    }
  }

  private def percentEncode(str: String): String = URLEncoder.encode(str, "UTF-8") replace("+", "%20") replace("%7E", "~")

  private def percentEncode(s: Seq[String]): String = s map percentEncode mkString "&"

  private def bytes(str: String) = str.getBytes(Charset.forName("UTF-8"))

  case class Consumer(key: String, secret: String)

  case class Token(value: String, secret: String)

} 
Example 2
Source File: DistributedRandomGenerator.scala    From Waves   with MIT License 5 votes vote down vote up
package com.wavesplatform.generator

import scala.collection.immutable.TreeMap
import scala.util.Random

// https://en.wikipedia.org/wiki/Categorical_distribution
trait DistributedRandomGenerator[T] {
  def getRandom: T
}

object DistributedRandomGenerator {
  private class SingleOutcome[T](outcome: T) extends DistributedRandomGenerator[T] {
    override def getRandom: T = outcome
  }

  private class MultipleOutcomes[T](outcomes: TreeMap[Double, T], total: Double) extends DistributedRandomGenerator[T] {
    override def getRandom: T = outcomes.rangeFrom(Random.nextDouble() * total).head._2
  }

  def apply[T](probabilities: Map[T, Double]): DistributedRandomGenerator[T] = {
    val filteredProbabilities = probabilities.filter { case (_, p) => p > 0 }
    filteredProbabilities.size match {
      case 0 => throw new IllegalArgumentException("empty probability list")
      case 1 => new SingleOutcome[T](filteredProbabilities.head._1)
      case _ =>
        import Ordering.Double.TotalOrdering
        val (treeMap, total) = filteredProbabilities.foldLeft((TreeMap.empty[Double, T], 0d)) {
          case ((tm, acc), (v, p)) => (tm + ((acc + p) -> v), acc + p)
        }

        new MultipleOutcomes[T](treeMap, total)
    }
  }
} 
Example 3
Source File: ClassIndexer.scala    From polynote   with Apache License 2.0 5 votes vote down vote up
package polynote.kernel.interpreter.scal

import java.io.File
import java.net.URI
import java.util.concurrent.atomic.AtomicReference
import java.util.function.UnaryOperator

import io.github.classgraph.ClassGraph
import polynote.kernel.ScalaCompiler
import polynote.kernel.util.pathOf
import zio.blocking.{Blocking, effectBlocking}
import zio.{Fiber, RIO, UIO, ZIO}

import scala.collection.immutable.TreeMap

trait ClassIndexer {

  
  def findMatches(name: String): UIO[Map[String, List[(Int, String)]]]

  def await: UIO[Unit]
}

object ClassIndexer {
  def default: ZIO[Blocking with ScalaCompiler.Provider, Nothing, ClassIndexer] =
    SimpleClassIndexer()
}

class SimpleClassIndexer(ref: AtomicReference[TreeMap[String, List[(Int, String)]]], process: Fiber[Throwable, Any]) extends ClassIndexer {

  override def findMatches(name: String): UIO[Map[String, List[(Int, String)]]] =
    ZIO.effectTotal(ref.get).map(_.range(name, name + Char.MaxValue))

  override def await: UIO[Unit] = process.await.unit
}

object SimpleClassIndexer {
  def apply(): ZIO[Blocking with ScalaCompiler.Provider, Nothing, SimpleClassIndexer] = {
    def buildIndex(
      priorityDependencies: Array[File],
      classPath: Array[File],
      classes: AtomicReference[TreeMap[String, List[(Int, String)]]]
    ) = effectBlocking {
      import scala.collection.JavaConverters._

      val lastPriority = priorityDependencies.length + classPath.length
      val priorities = (priorityDependencies ++ classPath.diff(priorityDependencies)).distinct.zipWithIndex.toMap

      val classGraph = new ClassGraph().overrideClasspath(priorityDependencies ++ classPath: _*).enableClassInfo()
      val scanResult = classGraph.scan()
      scanResult.getAllClasses.iterator().asScala
        .filter(_.isPublic)
        .filterNot(_.isSynthetic)
        .filterNot(_.getSimpleName.contains("$"))
        .foreach {
          classInfo =>
            val priority = priorities.getOrElse(classInfo.getClasspathElementFile, lastPriority)
            classes.updateAndGet(new UnaryOperator[TreeMap[String, List[(Int, String)]]] {
              def apply(t: TreeMap[String, List[(Int, String)]]): TreeMap[String, List[(Int, String)]] =
                t + (classInfo.getSimpleName -> ((priority -> classInfo.getName) :: t.getOrElse(classInfo.getSimpleName, Nil)))
            })
        }
      classes.get()
    }

    def javaLibraryPath = Option(classOf[Object].getResource("Object.class")).flatMap {
      case url if url.getProtocol == "jar"  => try Some(new File(new URI(url.getPath.stripSuffix("!/java/lang/Object.class")))) catch { case err: Throwable => None }
      case url if url.getProtocol == "file" => try Some(new File(url.toURI)) catch { case err: Throwable => None }
      case _ => None
    }

    for {
      classPath <- ScalaCompiler.settings.map(_.classpath.value.split(File.pathSeparatorChar).map(new File(_)))
      deps      <- ScalaCompiler.dependencies
      priorities = new File(pathOf(classOf[List[_]]).toURI) :: javaLibraryPath.toList ::: deps
      indexRef   = new AtomicReference[TreeMap[String, List[(Int, String)]]](new TreeMap)
      process   <- buildIndex(priorities.toArray, classPath, indexRef).forkDaemon
    } yield new SimpleClassIndexer(indexRef, process)
  }
} 
Example 4
Source File: IdGenUtilImpl.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4actor

import java.nio.ByteBuffer
import java.nio.charset.StandardCharsets.UTF_8
import java.security.MessageDigest
import java.util.Base64

import ee.cone.c4actor.Types.SrcId
import ee.cone.c4di.c4
import okio.ByteString

import scala.collection.immutable.TreeMap

@c4("RichDataCompApp") final case class IdGenUtilImpl()(
  proto: MessageDigest = MessageDigest.getInstance("MD5")
) extends IdGenUtil {
  private def md5(data: Array[Byte]*): String = {
    val d = proto.clone().asInstanceOf[MessageDigest] // much faster than getInstance("MD5")
    data.foreach{ bytes =>
      val l = bytes.length
      d.update((l>>24).toByte)
      d.update((l>>16).toByte)
      d.update((l>> 8).toByte)
      d.update((l>> 0).toByte)
      d.update(bytes)
    }
    Base64.getUrlEncoder.encodeToString(d.digest)
  }
  private def toBytes(value: String): Array[Byte] = value.getBytes(UTF_8)
  private def toBytes(value: Long): Array[Byte] =
    ByteBuffer.allocate(java.lang.Long.BYTES).putLong(value).array()

  def srcIdFromSrcIds(srcIdList: SrcId*): SrcId = md5(srcIdList.map(toBytes):_*)
  def srcIdFromStrings(stringList: String*): SrcId = md5(stringList.map(toBytes):_*)
  def srcIdFromSerialized(adapterId: Long, bytes: ByteString): SrcId =
    md5(toBytes(adapterId),bytes.toByteArray)
} 
Example 5
Source File: NotEffectiveAssembleTest.scala    From c4proto   with Apache License 2.0 5 votes vote down vote up
package ee.cone.c4actor

import Function.chain
import LEvent._
import com.typesafe.scalalogging.LazyLogging
import ee.cone.c4actor.PCProtocol.{D_RawChildNode, D_RawParentNode}
import ee.cone.c4di.c4

object Measure {
  def apply(f: ()=>Unit): Option[Long] = {
    val start = System.currentTimeMillis
    f()
    Option(System.currentTimeMillis-start)
  }
}

@c4("NotEffectiveAssemblerTestApp") final class NotEffectiveAssemblerTest(
  contextFactory: ContextFactory,
  execution: Execution,
  txAdd: LTxAdd,
) extends Executable with LazyLogging {
  def run(): Unit = {
    val nodes = List(D_RawParentNode("0", "P-1")) ++
      (1 to 10000).map(_.toString)
        .map(srcId => D_RawChildNode(srcId, "0", s"C-$srcId"))
    val local = contextFactory.updated(Nil)

    Measure { () =>
      IgnoreTestContext(chain(nodes.map(update).map(txAdd.add(_)))(local))
    }.foreach(t => logger.info(s"bad join with many add-s takes $t ms"))

    Measure { () =>
      IgnoreTestContext(chain(List(txAdd.add(nodes.flatMap(update))))(local))
    }.foreach(t => logger.info(s"bad join with single add takes $t ms"))
    execution.complete()
  }
}

 
Example 6
Source File: ClosestPlusPlusClustererSpec.scala    From fotm-info   with MIT License 5 votes vote down vote up
import info.fotm.clustering._
import info.fotm.clustering.implementations.ClosestPlusPlusClusterer
import info.fotm.util.MathVector
import org.scalactic.Equality
import org.scalatest._

import scala.collection.immutable.{TreeMap, IndexedSeq}

class ClosestPlusPlusClustererSpec extends FlatSpec with Matchers with ClustererSpecBase {
  val clusterer = new ClosestPlusPlusClusterer

  val input = Seq(
    MathVector(10, 0, 0),   // 0
    MathVector(11, 0, 0),   // 1
    MathVector(12, 0, 0),   // 2

    MathVector(0, 10, 0),   // 3
    MathVector(0, 11, 0),   // 4
    MathVector(0, 12, 0),   // 5

    MathVector(0, 0, 10),   // 6
    MathVector(0, 0, 11),   // 7
    MathVector(0, 0, 12)    // 8
  )

  "init" should "correctly init clusters" in {
    val expected = Seq(
      Seq(input(0)),
      Seq(input(5)),
      Seq(input(8))
    )

    val (clusters, _) = clusterer.init(input, 3)

    clusters should contain theSameElementsAs expected
  }

  "init" should "correctly remove cluster points" in {
    val expected = input diff List(0, 5, 8).map(input)

    val (_, points) = clusterer.init(input, 3)

    points should contain theSameElementsAs expected
  }

  "clusterize" should "correctly group simple vectors" in {
    val expected = Set(
      Seq(0, 1, 2).map(input),
      Seq(3, 4, 5).map(input),
      Seq(6, 7, 8).map(input)
    )

    val clusters: Set[Seq[MathVector]] = clusterer.clusterize(input, 3)

    expected.foreach(clusters should contain (_))
  }

} 
Example 7
Source File: FotmStorage.scala    From fotm-info   with MIT License 5 votes vote down vote up
package info.fotm.aether

import com.github.nscala_time.time.Imports._
import info.fotm.domain.TeamSnapshot._
import info.fotm.domain._

import scala.collection.immutable.TreeMap
import scala.concurrent.Future

trait FotmStorage {
  import FotmStorage._
  def update(updates: Updates): Unit
  def queryTeamHistory(axis: Axis, team: Team): Future[QueryTeamHistoryResponse]
  def queryCharHistory(axis: Axis, id: CharacterId): Future[QueryCharHistoryResponse]
  def queryAll(axis: Axis, interval: Interval, filter: SetupFilter, showChars: Boolean): Future[QueryAllResponse]
}

object FotmStorage {
  final case class Updates(axis: Axis, teamUpdates: Seq[TeamUpdate], charUpdates: Set[CharacterDiff]) {
    override val toString = s"Updates($axis, teams: ${teamUpdates.size}, chars: ${charUpdates.size})"
  }

  final case class QueryAll(axis: Axis, interval: Interval, filter: SetupFilter)
  final case class QueryAllResponse(axis: Axis, setups: Seq[FotmSetup], teams: Seq[TeamSnapshot], chars: Seq[CharacterSnapshot])

  final case class QueryTeamHistory(axis: Axis, team: Team)
  final case class QueryTeamHistoryResponse(axis: Axis, team: Team, history: TreeMap[DateTime, TeamSnapshot])

  final case class QueryCharHistory(axis: Axis, id: CharacterId)
  final case class QueryCharHistoryResponse(axis: Axis, charId: CharacterId, lastSnapshot: Option[CharacterSnapshot], history: TreeMap[DateTime, TeamSnapshot])

  final case class QueryFotm(axis: Axis, interval: Interval)
  final case class QueryFotmResponse(axis: Axis, setups: Seq[FotmSetup])
} 
Example 8
Source File: MyCodecImplicits.scala    From fotm-info   with MIT License 5 votes vote down vote up
package info.fotm

import info.fotm.domain._
import scodec._
import scodec.bits._
import codecs._
import scodec.codecs.implicits._
import com.github.nscala_time.time.Imports._
import scala.collection.immutable.TreeMap

object MyCodecImplicits {

  implicit def seqCodec[A](implicit listCodec: Codec[List[A]]): Codec[Seq[A]] =
    listCodec.xmap(_.toSeq, _.toList)

  implicit def setCodec[A](implicit listCodec: Codec[List[A]]): Codec[Set[A]] =
    listCodec.xmap(_.toSet[A], _.toList)

  implicit def mapCodec[K, V](implicit listCodec: Codec[List[(K, V)]]): Codec[Map[K, V]] =
    listCodec.xmap(_.toMap[K, V], _.toList)

  implicit def treemapCodec[K, V](implicit listCodec: Codec[List[(K, V)]], ordering: Ordering[K]): Codec[TreeMap[K, V]] =
    listCodec.xmap(lst => TreeMap(lst: _*), _.toList)

  implicit def datetimeCodec(implicit longCodec: Codec[Long]): Codec[DateTime] =
    longCodec.xmap(new DateTime(_), _.toInstant.getMillis)

  implicit def axisCodec(implicit strCodec: Codec[String]): Codec[Axis] =
    strCodec.xmap(
      str => {
        val Array(region, bracket) = str.split(',')
        Axis.parse(region, bracket).get
      },
      axis => s"${axis.region.slug},${axis.bracket.slug}")
} 
Example 9
Source File: Multiplexer.scala    From fotm-info   with MIT License 5 votes vote down vote up
package info.fotm.clustering.enhancers

import info.fotm.clustering.{RealClusterer, Clusterer}
import info.fotm.clustering.Clusterer.Cluster
import info.fotm.util.MathVector

import scala.collection.immutable.{TreeMap, IndexedSeq}
import scala.util.Random

trait Multiplexer extends RealClusterer {
  protected lazy val multiplexRng = new Random
  protected lazy val multiplexTurns = 20
  protected lazy val multiplexThreshold = 3

  abstract override def clusterize[T](input: Map[T, MathVector], groupSize: Int): Set[Seq[T]] = {
    class RandomOrder extends Ordering[T] {
      lazy val shuffled: List[(T, MathVector)] = multiplexRng.shuffle(input.toList)
      lazy val lookup: Map[T, Int] = shuffled.zipWithIndex.map { kvi =>
        val ((k, v), i) = kvi
        (k, i)
      }.toMap

      def compare(t1: T, t2: T): Int = lookup(t1).compareTo(lookup(t2))
    }

    val allClusters: IndexedSeq[Seq[T]] = for {
      i <- 0 to multiplexTurns
      randomInput = TreeMap.empty[T, MathVector](new RandomOrder) ++ input
      cluster <- super.clusterize(randomInput, groupSize)
    } yield cluster

    val groups = allClusters.groupBy(identity)
    groups.filter(_._2.size >= multiplexThreshold).keySet // take those found at least threshold times
  }
}

class SimpleMultiplexer(underlying: Clusterer, turns: Int, threshold: Int) extends Clusterer {
  protected lazy val multiplexRng = new Random
  protected lazy val multiplexTurns = turns
  protected lazy val multiplexThreshold = threshold

  override def clusterize(input: Cluster, groupSize: Int): Set[Cluster] = {

    val vectors: Map[MathVector, Int] = input.zipWithIndex.toMap

    val allClusters: IndexedSeq[Cluster] = for {
      i <- 1 to multiplexTurns
      randomInput = multiplexRng.shuffle(input)
      cluster <- underlying.clusterize(randomInput, groupSize)
    } yield cluster

    val groups = allClusters.groupBy(_.map(vectors).sorted)

    groups
      .filter(kv => kv._2.size >= multiplexThreshold) // take those found at least threshold times
      .map(_._2.head)
      .filter(_.size == groupSize)
      .toSet
  }
} 
Example 10
Source File: XSet.scala    From topshell   with MIT License 5 votes vote down vote up
package com.github.ahnfelt.topshell.data

import scala.collection.immutable.{SortedSet, TreeMap, TreeSet}
import scala.scalajs.js
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}

@JSExportTopLevel("XSet")
object XSet {

    private implicit val ordering : Ordering[Any] = XOrder.ordering

    type XSet = SortedSet[Any]
    type Fun[A, B] = js.Function1[A, B]

    @JSExport
    def isInstance(any : Any) : Boolean = any.isInstanceOf[scala.collection.immutable.SortedSet[_]]

    @JSExport
    def of(array : js.Array[Any]) : XSet = {
        TreeSet(array : _*)
    }

    @JSExport
    def toList(set : XSet) : js.Array[Any] = {
        js.Array(set.toList : _*)
    }

    @JSExport
    def toMap(f : Fun[Any, Any], set : XSet) : XMap.XMap = {
        set.foldLeft(XMap.empty) ( (m, v) => m + (v -> f(v)) )
    }

    @JSExport
    def add(value : Any, set : XSet) : XSet = {
        set + value
    }

    @JSExport
    def remove(value : Any, set : XSet) : XSet = {
        set - value
    }

    @JSExport
    def union(a : XSet, b : XSet) : XSet = {
        a ++ b
    }

    @JSExport
    def intersect(a : XSet, b : XSet) : XSet = {
        a.intersect(b)
    }

    @JSExport
    def exclude(a : XSet, b : XSet) : XSet = {
        b -- a
    }

    @JSExport
    def has(value : Any, set : XSet) : Boolean = {
        set.contains(value)
    }

    @JSExport
    def from(value : Any, set : XSet) : XSet = {
        set.from(value)
    }

    @JSExport
    def until(value : Any, set : XSet) : XSet = {
        set.until(value)
    }

    @JSExport
    def foldLeft(f : Fun[Any, Fun[Any, Any]], z : Any, set : XSet) : Any = {
        set.foldLeft(z) { (v, p) => f(p)(v) }
    }

    @JSExport
    def foldRight(f : Fun[Any, Fun[Any, Any]], z : Any, set : XSet) : Any = {
        set.foldRight(z) { (p, v) => f(p)(v) }
    }

    @JSExport
    def size(set : XSet) : Int = {
        set.size
    }

    @JSExport
    def isEmpty(set : XSet) : Boolean = {
        set.isEmpty
    }

    @JSExport
    val empty : XSet = TreeSet.empty

} 
Example 11
Source File: XOrder.scala    From topshell   with MIT License 5 votes vote down vote up
package com.github.ahnfelt.topshell.data

import scala.collection.immutable.TreeMap
import scala.scalajs.js
import scala.scalajs.js.annotation.{JSExport, JSExportTopLevel}

@JSExportTopLevel("XOrder")
object XOrder {

    val ordering : Ordering[Any] = (l : Any, r : Any) => (l, r) match {
        case (a : js.Array[_], b : js.Array[_]) =>
            a.zip(b).find { case (x, y) =>
                ordering.compare(x, y) != 0
            }.map { case (x, y) => ordering.compare(x, y) }.getOrElse {
                ordering.compare(a.length, b.length)
            }
        case (a : String, b : String) => a.compareTo(b)
        case (a : Double, b : Double) => a.compareTo(b)
        case (a : Int, b : Int) => a.compareTo(b)
        case _ =>
            val a = l.asInstanceOf[js.Dictionary[Any]]
            val b = r.asInstanceOf[js.Dictionary[Any]]
            var (key, result) = if(a.contains("_") && b.contains("_")) {
                ("_", ordering.compare(a("_"), b("_")))
            } else ("", 0)
            for((k, v) <- a; w <- b.get(k) if k != "_" && (result == 0 || k < key)) {
                val newResult = ordering.compare(v, w)
                if(newResult != 0) {
                    key = k
                    result = newResult
                }
            }
            result
    }

    @JSExport
    def min(a : Any, b : Any) : Any = ordering.min(a, b)

    @JSExport
    def max(a : Any, b : Any) : Any = ordering.max(a, b)

    @JSExport
    def equal(a : Any, b : Any) : Boolean = ordering.equiv(a, b)

    @JSExport
    def notEqual(a : Any, b : Any) : Boolean = !ordering.equiv(a, b)

    @JSExport
    def less(a : Any, b : Any) : Boolean = ordering.lt(a, b)

    @JSExport
    def lessEqual(a : Any, b : Any) : Boolean = ordering.lteq(a, b)

    @JSExport
    def greater(a : Any, b : Any) : Boolean = ordering.gt(a, b)

    @JSExport
    def greaterEqual(a : Any, b : Any) : Boolean = ordering.gteq(a, b)

} 
Example 12
Source File: LedgerEntries.scala    From daml   with Apache License 2.0 5 votes vote down vote up
// Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package com.daml.platform.sandbox.stores.ledger.inmemory

import java.util.concurrent.atomic.AtomicReference

import akka.NotUsed
import akka.stream.scaladsl.Source
import com.daml.ledger.participant.state.v1.Offset
import com.daml.lf.data.Ref
import com.daml.platform.akkastreams.dispatcher.Dispatcher
import com.daml.platform.akkastreams.dispatcher.SubSource.RangeSource
import org.slf4j.LoggerFactory
import com.daml.platform.ApiOffset.ApiOffsetConverter
import com.daml.platform.sandbox.stores.ledger.SandboxOffset

import scala.collection.immutable.TreeMap

private[ledger] class LedgerEntries[T](identify: T => String) {

  private val logger = LoggerFactory.getLogger(this.getClass)

  private case class Entries(ledgerEnd: Offset, items: TreeMap[Offset, T])

  // Tuple of (ledger end cursor, ledger map). There is never an entry for the initial cursor. End is inclusive.
  private val state = new AtomicReference(Entries(ledgerBeginning, TreeMap.empty))

  private def store(item: T): Offset = {
    val Entries(newOffset, _) = state.updateAndGet({
      case Entries(ledgerEnd, ledger) =>
        val newEnd = SandboxOffset.toOffset(SandboxOffset.fromOffset(ledgerEnd) + 1)
        Entries(newEnd, ledger + (newEnd -> item))
    })
    if (logger.isTraceEnabled())
      logger.trace("Recording `{}` at offset `{}`", identify(item): Any, newOffset.toApiString: Any)
    newOffset
  }

  def incrementOffset(increment: Int): Offset = {
    val Entries(newOffset, _) = state.updateAndGet({
      case Entries(ledgerEnd, ledger) =>
        val newEnd = SandboxOffset.toOffset(SandboxOffset.fromOffset(ledgerEnd) + increment)
        Entries(newEnd, ledger)
    })
    if (logger.isTraceEnabled())
      logger.trace("Bumping offset to `{}`", newOffset.toApiString)
    newOffset
  }

  private val dispatcher = Dispatcher[Offset]("inmemory-ledger", Offset.beforeBegin, ledgerEnd)

  def getSource(
      startExclusive: Option[Offset],
      endInclusive: Option[Offset]): Source[(Offset, T), NotUsed] =
    dispatcher.startingAt(
      startExclusive.getOrElse(ledgerBeginning),
      RangeSource(
        (exclusiveStart, inclusiveEnd) =>
          Source[(Offset, T)](
            state.get().items.from(exclusiveStart).filter(_._1 > exclusiveStart).to(inclusiveEnd)),
      ),
      endInclusive
    )

  def publish(item: T): Offset = {
    val newHead = store(item)
    dispatcher.signalNewHead(newHead)
    newHead
  }

  def ledgerBeginning: Offset = SandboxOffset.toOffset(0)

  def items = state.get().items.iterator

  def ledgerEnd: Offset = state.get().ledgerEnd

  def nextTransactionId: Ref.LedgerString =
    Ref.LedgerString.assertFromString((SandboxOffset.fromOffset(ledgerEnd) + 1).toString)
} 
Example 13
Source File: WindowAverageProcessor.scala    From incubator-retired-gearpump   with Apache License 2.0 5 votes vote down vote up
package org.apache.gearpump.streaming.examples.state.processor

import scala.collection.immutable.TreeMap
import com.twitter.algebird.{AveragedGroup, AveragedValue}
import org.slf4j.Logger
import org.apache.gearpump.Message
import org.apache.gearpump.cluster.UserConfig
import org.apache.gearpump.streaming.monoid.AlgebirdGroup
import org.apache.gearpump.streaming.serializer.ChillSerializer
import org.apache.gearpump.streaming.state.api.{PersistentState, PersistentTask}
import org.apache.gearpump.streaming.state.impl.{Interval, Window, WindowConfig, WindowState}
import org.apache.gearpump.streaming.task.TaskContext
import org.apache.gearpump.util.LogUtil

object WindowAverageProcessor {
  val LOG: Logger = LogUtil.getLogger(classOf[WindowAverageProcessor])
}

class WindowAverageProcessor(taskContext: TaskContext, conf: UserConfig)
  extends PersistentTask[AveragedValue](taskContext, conf) {

  override def persistentState: PersistentState[AveragedValue] = {
    val group = new AlgebirdGroup(AveragedGroup)
    val serializer = new ChillSerializer[TreeMap[Interval, AveragedValue]]
    val window = new Window(conf.getValue[WindowConfig](WindowConfig.NAME).get)
    new WindowState[AveragedValue](group, serializer, taskContext, window)
  }

  override def processMessage(state: PersistentState[AveragedValue],
      message: Message): Unit = {
    val value = AveragedValue(message.value.asInstanceOf[String].toLong)
    state.update(message.timestamp.toEpochMilli, value)
  }
} 
Example 14
Source File: SortedMapDeserializerModule.scala    From mango   with Apache License 2.0 5 votes vote down vote up
package com.kakao.shaded.jackson.module.scala.deser

import java.util.AbstractMap
import java.util.Map.Entry

import scala.collection.{mutable, SortedMap}
import scala.collection.immutable.TreeMap

import com.kakao.shaded.jackson.core.JsonParser
import com.kakao.shaded.jackson.databind._
import com.kakao.shaded.jackson.databind.deser.std.{MapDeserializer, ContainerDeserializerBase}
import com.kakao.shaded.jackson.databind.jsontype.TypeDeserializer
import com.kakao.shaded.jackson.databind.`type`.MapLikeType
import com.kakao.shaded.jackson.module.scala.modifiers.MapTypeModifierModule
import deser.{ContextualDeserializer, Deserializers, ValueInstantiator}
import com.kakao.shaded.jackson.module.scala.introspect.OrderingLocator
import scala.language.existentials

private class SortedMapBuilderWrapper[K,V](val builder: mutable.Builder[(K,V), SortedMap[K,V]]) extends AbstractMap[K,V] {
  override def put(k: K, v: V) = { builder += ((k,v)); v }

  // Isn't used by the deserializer
  def entrySet(): java.util.Set[Entry[K, V]] = throw new UnsupportedOperationException
}

private object SortedMapDeserializer {
  def orderingFor = OrderingLocator.locate _

  def builderFor(cls: Class[_], keyCls: JavaType): mutable.Builder[(AnyRef,AnyRef), SortedMap[AnyRef,AnyRef]] =
    if (classOf[TreeMap[_,_]].isAssignableFrom(cls)) TreeMap.newBuilder[AnyRef,AnyRef](orderingFor(keyCls)) else
    SortedMap.newBuilder[AnyRef,AnyRef](orderingFor(keyCls))
}

private class SortedMapDeserializer(
    collectionType: MapLikeType,
    config: DeserializationConfig,
    keyDeser: KeyDeserializer,
    valueDeser: JsonDeserializer[_],
    valueTypeDeser: TypeDeserializer)
  extends ContainerDeserializerBase[SortedMap[_,_]](collectionType)
  with ContextualDeserializer {
  
  private val javaContainerType =
    config.getTypeFactory.constructMapLikeType(classOf[MapBuilderWrapper[_,_]], collectionType.getKeyType, collectionType.getContentType)

  private val instantiator =
    new ValueInstantiator {
      def getValueTypeDesc = collectionType.getRawClass.getCanonicalName
      override def canCreateUsingDefault = true
      override def createUsingDefault(ctx: DeserializationContext) =
        new SortedMapBuilderWrapper[AnyRef,AnyRef](SortedMapDeserializer.builderFor(collectionType.getRawClass, collectionType.getKeyType))
    }

  private val containerDeserializer =
    new MapDeserializer(javaContainerType,instantiator,keyDeser,valueDeser.asInstanceOf[JsonDeserializer[AnyRef]],valueTypeDeser)

  override def getContentType = containerDeserializer.getContentType

  override def getContentDeserializer = containerDeserializer.getContentDeserializer

  override def createContextual(ctxt: DeserializationContext, property: BeanProperty) =
    if (keyDeser != null && valueDeser != null) this
    else {
      val newKeyDeser = Option(keyDeser).getOrElse(ctxt.findKeyDeserializer(collectionType.getKeyType, property))
      val newValDeser = Option(valueDeser).getOrElse(ctxt.findContextualValueDeserializer(collectionType.getContentType, property))
      new SortedMapDeserializer(collectionType, config, newKeyDeser, newValDeser, valueTypeDeser)
    }
  
  override def deserialize(jp: JsonParser, ctxt: DeserializationContext): SortedMap[_,_] = {
    containerDeserializer.deserialize(jp,ctxt) match {
      case wrapper: SortedMapBuilderWrapper[_,_] => wrapper.builder.result()
    }
  }
}

private object SortedMapDeserializerResolver extends Deserializers.Base {
  
  private val SORTED_MAP = classOf[collection.SortedMap[_,_]]

  override def findMapLikeDeserializer(theType: MapLikeType,
                              config: DeserializationConfig,
                              beanDesc: BeanDescription,
                              keyDeserializer: KeyDeserializer,
                              elementTypeDeserializer: TypeDeserializer,
                              elementDeserializer: JsonDeserializer[_]): JsonDeserializer[_] =
    if (!SORTED_MAP.isAssignableFrom(theType.getRawClass)) null
    else new SortedMapDeserializer(theType,config,keyDeserializer,elementDeserializer,elementTypeDeserializer)
}


trait SortedMapDeserializerModule extends MapTypeModifierModule {
  this += (_ addDeserializers SortedMapDeserializerResolver)
} 
Example 15
Source File: PossibleForgersSet.scala    From Sidechains-SDK   with MIT License 5 votes vote down vote up
package com.horizen.fixtures.sidechainblock.generation
import java.math.BigInteger
import java.util.{Random, ArrayList => JArrayList}

import com.horizen.consensus.{ConsensusSlotNumber, NonceConsensusEpochInfo, StakeConsensusEpochInfo, _}
import com.horizen.proof.VrfProof
import com.horizen.utils._
import com.horizen.vrf.VrfOutput

import scala.collection.immutable.TreeMap


class PossibleForgersSet(forgers: Set[PossibleForger]) {
  private val ordering: Ordering[SidechainForgingData] = Ordering[(Long, BigInteger)].on(x => (x.forgerBox.value(), new BigInteger(x.forgerId)))

  val forgingDataToPossibleForger: TreeMap[SidechainForgingData, PossibleForger] = TreeMap(forgers.map(pf => (pf.forgingData.copy(), pf.copy())).toArray:_*)(ordering.reverse)
  require(forgingDataToPossibleForger.size == forgers.size)

  def getRandomPossibleForger(rnd: Random): PossibleForger = forgers.toSeq(rnd.nextInt(forgers.size))

  def getAvailableSidechainForgingData: Set[SidechainForgingData] = forgingDataToPossibleForger.keys.to

  def getNotSpentSidechainForgingData: Set[SidechainForgingData] = forgingDataToPossibleForger.filter{case (forgingData, possibleForger) => possibleForger.isNotSpent}.keys.to

  def getEligibleForger(slotNumber: ConsensusSlotNumber, nonceConsensusEpochInfo: NonceConsensusEpochInfo, totalStake: Long, additionalCheck: Boolean => Boolean): Option[(PossibleForger, VrfProof, VrfOutput)] = {
    val vrfMessage = buildVrfMessage(slotNumber, nonceConsensusEpochInfo)
    forgingDataToPossibleForger
      .values
      .view
      .flatMap{forger => forger.canBeForger(vrfMessage, totalStake, additionalCheck).map{case (proof, vrfOutput) => (forger, proof, vrfOutput)}} //get eligible forgers
      .headOption
  }

  def finishCurrentEpoch(): (PossibleForgersSet, StakeConsensusEpochInfo) = {
    val possibleForgersForNextEpoch: Seq[PossibleForger] = getPossibleForgersForNextEpoch

    val totalStake = possibleForgersForNextEpoch.withFilter(_.isNotSpent).map(_.forgingData.forgerBox.value()).sum
    val merkleTreeForEndOfEpoch: MerkleTree = buildMerkleTree(possibleForgersForNextEpoch.map(_.forgingData.forgerBox.id()))
    val merkleTreeForEndOfEpochRootHash = merkleTreeForEndOfEpoch.rootHash()

    val forgingDataWithUpdatedMerkleTreePathAndMaturity: Seq[PossibleForger] =
      possibleForgersForNextEpoch
        .zipWithIndex.map{case (possibleForger, index) =>
        possibleForger.createPossibleForgerForTheNextEpoch(Some(merkleTreeForEndOfEpoch.getMerklePathForLeaf(index)))}

    val stakeEpochInfo: StakeConsensusEpochInfo = StakeConsensusEpochInfo(merkleTreeForEndOfEpochRootHash, totalStake)
    val newForgers = new PossibleForgersSet(Set(forgingDataWithUpdatedMerkleTreePathAndMaturity.toArray:_*))

    (newForgers, stakeEpochInfo)
  }

  private def getPossibleForgersForNextEpoch: Seq[PossibleForger] = {
    forgingDataToPossibleForger.values.filter(_.couldBePossibleForgerInNextEpoch).to
  }

  def createModified(generationRules: GenerationRules): PossibleForgersSet = {

    val forgingBoxToSpent = generationRules.forgingBoxesToSpent
    val forgingBoxToAdd = generationRules.forgingBoxesToAdd

    val withoutSpentKeys = forgingDataToPossibleForger.keys.toSet -- forgingBoxToSpent
    require((withoutSpentKeys.size + forgingBoxToSpent.size) == forgingDataToPossibleForger.size)

    val withoutSpentPossibleForgers: Set[PossibleForger] = withoutSpentKeys.collect(forgingDataToPossibleForger)
    val spentPossibleForgers: Set[PossibleForger] = forgingBoxToSpent.collect(forgingDataToPossibleForger).map(possibleForger => possibleForger.copy(spentInEpochsAgoOpt = Some(0)))
    val newPossibleForgers: Set[PossibleForger] = forgingBoxToAdd.map(PossibleForger(_, merklePathInPreviousEpochOpt = None, merklePathInPrePreviousEpochOpt = None, spentInEpochsAgoOpt = None))

    new PossibleForgersSet(withoutSpentPossibleForgers ++ spentPossibleForgers ++ newPossibleForgers)
  }

  private def buildMerkleTree(ids: Iterable[Array[Byte]]): MerkleTree = {
    val leavesForMerkleTree =
      ids.foldLeft(new JArrayList[Array[Byte]]()) {(acc, id) =>
        acc.add(id)
        acc
      }

    val filler = leavesForMerkleTree.get(leavesForMerkleTree.size() - 1)
    val additionalLeaves = SidechainBlocksGenerator.merkleTreeSize - leavesForMerkleTree.size()
    (1 to additionalLeaves).foreach(_ => leavesForMerkleTree.add(filler))

    val resultTree = MerkleTree.createMerkleTree(leavesForMerkleTree)
    resultTree
  }
} 
Example 16
Source File: LeftJoin.scala    From flint   with Apache License 2.0 5 votes vote down vote up
package com.twosigma.flint.rdd.function.join

import com.twosigma.flint.rdd.{ PartitionsIterator, PeekableIterator }
import org.apache.spark.{ NarrowDependency, OneToOneDependency }
import com.twosigma.flint.rdd.OrderedRDD

import scala.collection.immutable.TreeMap
import scala.reflect.ClassTag
import java.util.{ HashMap => JHashMap }

protected[flint] object LeftJoin {

  val skMapInitialSize = 1024

  def apply[K: ClassTag, SK, V, V2](
    leftRdd: OrderedRDD[K, V],
    rightRdd: OrderedRDD[K, V2],
    toleranceFn: K => K,
    leftSk: V => SK,
    rightSk: V2 => SK
  )(implicit ord: Ordering[K]): OrderedRDD[K, (V, Option[(K, V2)])] = {
    // A map from left partition index to left range split and right partitions.
    val leftIndexToJoinSplits = TreeMap(RangeMergeJoin.leftJoinSplits(
      toleranceFn, leftRdd.rangeSplits, rightRdd.rangeSplits
    ).map { case (split, parts) => (split.partition.index, (split, parts)) }: _*)

    val leftDep = new OneToOneDependency(leftRdd)
    val rightDep = new NarrowDependency(rightRdd) {
      override def getParents(partitionId: Int) =
        leftIndexToJoinSplits(partitionId)._2.map(_.index)
    }

    // A map from left partition index to right partitions
    val rightPartitions = leftRdd.sc.broadcast(leftIndexToJoinSplits.map {
      case (idx, joinSplit) => (idx, joinSplit._2)
    })

    val joinedSplits = leftIndexToJoinSplits.map { case (_, (split, _)) => split }.toArray

    // We don't need the left dependency as we will just load it on demand here
    new OrderedRDD[K, (V, Option[(K, V2)])](leftRdd.sc, joinedSplits, Seq(leftDep, rightDep))(
      (part, context) => {
        val parts = rightPartitions.value(part.index)
        val rightIter = PeekableIterator(PartitionsIterator(rightRdd, parts, context))
        val lastSeen = new JHashMap[SK, (K, V2)](skMapInitialSize)
        leftRdd.iterator(part, context).map {
          case (k, v) =>
            // Catch-up the iterator for the right table to match the left key. In the
            // process, we'll have the last-seen row for each SK in the right table.
            val sk = leftSk(v)
            catchUp(k, rightSk, rightIter, lastSeen)
            val lastSeenRight = lastSeen.get(sk)
            if (lastSeenRight != null && ord.gteq(lastSeenRight._1, toleranceFn(k))) {
              (k, (v, Some(lastSeenRight)))
            } else {
              (k, (v, None))
            }
        }
      }
    )
  }

  
  @annotation.tailrec
  private[rdd] def catchUp[K, SK, V](
    cur: K,
    skFn: V => SK,
    iter: PeekableIterator[(K, V)],
    lastSeen: JHashMap[SK, (K, V)]
  )(implicit ord: Ordering[K]) {
    val peek = iter.peek
    if (peek.nonEmpty && ord.lteq(peek.get._1, cur)) {
      val (k, v) = iter.next
      val sk = skFn(v)
      lastSeen.put(sk, (k, v))
      catchUp(cur, skFn, iter, lastSeen)
    }
  }

} 
Example 17
Source File: FractionalKnapsack.scala    From functional-way   with GNU General Public License v3.0 5 votes vote down vote up
package greedy
import scala.collection.immutable.TreeMap


type ValuePerWeight = Float
type OptimalSolution = Float
type Weight = Int

def maxValue(itemWeights: Array[Int], itemValues: Array[Int], knapsackCapacity: Int): OptimalSolution =
  val array: Array[(ValuePerWeight, Weight)] = itemValues.zip(itemWeights).map {
      case (vi, wi) => ((vi.toFloat/wi),wi)
  }
  def recurse(map: TreeMap[ValuePerWeight, Weight], currentCapacity: Weight): OptimalSolution =  map match
    case TreeMapExtractor((valuePerWeight, weight), restEntries) => 
      if(weight <= currentCapacity) weight * valuePerWeight + recurse(map.tail, currentCapacity - weight)
      else currentCapacity * valuePerWeight
    case _ => 0
  val map: TreeMap[ValuePerWeight, Weight] = TreeMap(array:_*)(implicitly[Ordering[Float]].reverse)
  recurse(map = map, currentCapacity = knapsackCapacity)

object TreeMapExtractor
  def unapply[K,V](treeMap: TreeMap[K,V]): Option[((K,V), TreeMap[K,V])] = treeMap.headOption.map((_, treeMap.tail)) 
Example 18
Source File: PhaseRes.scala    From Converter   with GNU General Public License v3.0 5 votes vote down vote up
package org.scalablytyped.converter.internal.phases

import java.nio.channels.{ClosedByInterruptException, FileLockInterruptionException}

import com.olvind.logging.Logger
import com.olvind.logging.Logger.LoggedException

import scala.collection.immutable.{SortedMap, TreeMap}
import scala.concurrent.ExecutionException
import scala.util.control.NonFatal

sealed trait PhaseRes[Id, T] extends Product with Serializable {
  import PhaseRes._

  def foreach(f: T => Unit): PhaseRes[Id, Unit] = map(f)

  def map[U](f: T => U): PhaseRes[Id, U] =
    this match {
      case Ok(value)       => Ok(f(value))
      case Ignore()        => Ignore()
      case Failure(errors) => Failure(errors)
    }

  def flatMap[U](f: T => PhaseRes[Id, U]): PhaseRes[Id, U] =
    this match {
      case Ok(value)       => f(value)
      case Ignore()        => Ignore()
      case Failure(errors) => Failure(errors)
    }
}

object PhaseRes {
  final case class Ok[Id, T](value: T) extends PhaseRes[Id, T]
  final case class Ignore[Id, T]() extends PhaseRes[Id, T]
  final case class Failure[Id, T](errors: Map[Id, Either[Throwable, String]]) extends PhaseRes[Id, T]

  def fromEither[Id, L, R](id: Id, e: Either[String, R]): PhaseRes[Id, R] =
    e match {
      case Right(value) => Ok(value)
      case Left(error)  => Failure(Map(id -> Right(error)))
    }

  def fromOption[Id, T](id: Id, e: Option[T], onEmpty: => Either[Throwable, String]): PhaseRes[Id, T] =
    e match {
      case Some(value) => Ok(value)
      case None        => Failure(Map(id -> onEmpty))
    }

  def sequenceSet[Id, T](rs: Set[PhaseRes[Id, T]]): PhaseRes[Id, Set[T]] =
    rs.foldLeft[PhaseRes[Id, Set[T]]](Ok(Set.empty)) {
      case (other, Ignore())                 => other
      case (Ok(ts), Ok(t))                   => Ok(ts + t)
      case (Ok(_), Failure(errors))          => Failure(errors)
      case (Failure(errors), Failure(error)) => Failure(errors ++ error)
      case (error @ Failure(_), Ok(_))       => error
      case (Ignore(), Ok(t))                 => Ok(Set(t))
      case (Ignore(), Failure(error))        => Failure(error)
    }

  def sequenceMap[Id: Ordering, T](rs: SortedMap[Id, PhaseRes[Id, T]]): PhaseRes[Id, SortedMap[Id, T]] =
    rs.foldLeft[PhaseRes[Id, SortedMap[Id, T]]](Ok(TreeMap.empty[Id, T])) {
      case (other, (_, Ignore()))                    => other
      case (Ok(map), (id, Ok(value)))                => Ok(map + ((id, value)))
      case (Ok(_), (_, Failure(errors)))             => Failure(errors)
      case (Failure(errors1), (_, Failure(errors2))) => Failure(errors1 ++ errors2)
      case (error @ Failure(_), _)                   => error
      case (Ignore(), (id, Ok(value)))               => Ok(TreeMap((id, value)))
      case (Ignore(), (_, Failure(errors)))          => Failure(errors)
    }

  def attempt[Id, T](id: Id, logger: Logger[Unit], t: => PhaseRes[Id, T]): PhaseRes[Id, T] =
    try t
    catch {
      case x: InterruptedException => throw x
      case x: ClosedByInterruptException => throw x
      case x: FileLockInterruptionException => throw x
      case x: ExecutionException if x.getCause != null =>
        val th = x.getCause
        logger.error(s"Caught exception: ${th.getMessage}", th)
        Failure[Id, T](Map(id -> Left(th)))
      case th: LoggedException =>
        Failure[Id, T](Map(id -> Left(th)))
      case NonFatal(th) =>
        logger.error(s"Caught exception: ${th.getMessage}", th)
        Failure[Id, T](Map(id -> Left(th)))
      case th: StackOverflowError =>
        logger.error("StackOverflowError", th)
        Failure[Id, T](Map(id -> Left(th)))
    }
} 
Example 19
Source File: OrderFeeSettingsCache.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.caches

import com.wavesplatform.dex.settings.OrderFeeSettings

import scala.collection.immutable.TreeMap

class OrderFeeSettingsCache(orderFeeSettingsMap: Map[Long, OrderFeeSettings]) {

  private val allOrderFeeSettings = {
    if (orderFeeSettingsMap.isEmpty) throw new IllegalArgumentException("Order fee settings should contain at least 1 value!")
    TreeMap.empty[Long, OrderFeeSettings] ++ orderFeeSettingsMap
  }

  def getSettingsForOffset(offset: Long): OrderFeeSettings = {
    allOrderFeeSettings
      .takeWhile { case (o, _) => o <= offset }
      .lastOption
      .map(_._2)
      .getOrElse(throw new IllegalStateException(s"Order fee settings are not set for offset $offset"))
  }
} 
Example 20
Source File: package.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex

import com.wavesplatform.dex.domain.bytes.ByteStr
import com.wavesplatform.dex.domain.model.Price
import com.wavesplatform.dex.domain.order.Order

import scala.collection.immutable.{Queue, TreeMap}

package object model {
  type Level                 = Queue[LimitOrder]
  type OrderBookSideSnapshot = Map[Price, Seq[LimitOrder]]

  type Side = TreeMap[Price, Level]
  implicit class SideExt(val side: Side) extends AnyVal {

    
    def best: Option[(Price, LimitOrder)] = side.headOption.flatMap { case (levelPrice, level) => level.headOption.map(levelPrice -> _) }

    def enqueue(levelPrice: Price, lo: LimitOrder): Side = side.updated(levelPrice, side.getOrElse(levelPrice, Queue.empty).enqueue(lo))

    def unsafeWithoutBest: (Side, Order.Id) = side.headOption match {
      case Some((price, level)) =>
        val updated = if (level.length == 1) side - price else side.updated(price, level.tail)
        (updated, level.head.order.id())
      case None => throw new IllegalArgumentException("Expected side to have at least one order")
    }

    def unsafeUpdateBest(updated: LimitOrder): Side = {
      require(side.nonEmpty, "Cannot replace the best level of an empty side")
      val (price, level) = side.head
      require(level.nonEmpty, "Cannot replace the best element of an empty level")
      val oldHead = level.head
      require(oldHead.order.id() == updated.order.id(), "Expected the same order")
      side.updated(price, updated +: level.tail)
    }

    def unsafeRemove(price: Price, orderId: ByteStr): (Side, LimitOrder) = {
      val (toRemove, toKeep) = side.getOrElse(price, Queue.empty).partition(_.order.id() == orderId)
      require(toRemove.nonEmpty, s"Order $orderId not found at $price")
      val updatedSide = if (toKeep.isEmpty) side - price else side.updated(price, toKeep)
      (updatedSide, toRemove.head)
    }

    def put(price: Price, lo: LimitOrder): Side = side.updated(price, side.getOrElse(price, Queue.empty).enqueue(lo))

    def aggregated: Iterable[LevelAgg] = for { (p, l) <- side.view if l.nonEmpty } yield LevelAgg(l.map(_.amount).sum, p)
    def bestLevel: Option[LevelAgg]    = aggregated.headOption
  }
} 
Example 21
Source File: WsOrderBookState.scala    From matcher   with MIT License 5 votes vote down vote up
package com.wavesplatform.dex.api.ws.state

import akka.actor.typed.ActorRef
import cats.syntax.option._
import com.wavesplatform.dex.api.ws.entities.{WsLastTrade, WsOrderBookSettings}
import com.wavesplatform.dex.api.ws.protocol
import com.wavesplatform.dex.api.ws.protocol.WsOrderBookChanges
import com.wavesplatform.dex.api.ws.state.WsAddressState.getNextUpdateId
import com.wavesplatform.dex.domain.asset.AssetPair
import com.wavesplatform.dex.domain.model.Denormalization.{denormalizeAmountAndFee, denormalizePrice}
import com.wavesplatform.dex.domain.model.{Amount, Price}
import com.wavesplatform.dex.model.{LastTrade, LevelAmounts}
import monocle.macros.GenLens

import scala.collection.immutable.TreeMap

case class WsOrderBookState(wsConnections: Map[ActorRef[WsOrderBookChanges], Long],
                            changedAsks: Set[Price],
                            changedBids: Set[Price],
                            lastTrade: Option[LastTrade],
                            changedTickSize: Option[Double]) {

  val genLens: GenLens[WsOrderBookState] = GenLens[WsOrderBookState]

  def addSubscription(x: ActorRef[WsOrderBookChanges]): WsOrderBookState = copy(wsConnections = wsConnections.updated(x, 0L))

  def withoutSubscription(x: ActorRef[WsOrderBookChanges]): WsOrderBookState =
    if (wsConnections.size == 1) WsOrderBookState(Map.empty, Set.empty, Set.empty, None, None)
    else copy(wsConnections = wsConnections - x)

  def hasSubscriptions: Boolean = wsConnections.nonEmpty

  def hasChanges: Boolean = changedAsks.nonEmpty || changedBids.nonEmpty || lastTrade.nonEmpty || changedTickSize.nonEmpty

  def denormalized(amountDecimals: Int, priceDecimals: Int, xs: TreeMap[Price, Amount]): TreeMap[Double, Double] = xs.map {
    case (price, amount) =>
      denormalizePrice(price, amountDecimals, priceDecimals).toDouble -> denormalizeAmountAndFee(amount, amountDecimals).toDouble
  }

  def lastTrade(amountDecimals: Int, priceDecimals: Int, x: LastTrade): WsLastTrade = WsLastTrade(
    price = denormalizePrice(x.price, amountDecimals, priceDecimals).toDouble,
    amount = denormalizeAmountAndFee(x.amount, amountDecimals).toDouble,
    side = x.side
  )

  def flushed(assetPair: AssetPair,
              amountDecimals: Int,
              priceDecimals: Int,
              asks: TreeMap[Price, Amount],
              bids: TreeMap[Price, Amount],
              timestamp: Long): WsOrderBookState = copy(
    wsConnections = if (hasChanges) {
      val changes =
        protocol.WsOrderBookChanges(
          assetPair = assetPair,
          asks = denormalized(amountDecimals, priceDecimals, take(asks, changedAsks)),
          bids = denormalized(amountDecimals, priceDecimals, take(bids, changedBids)),
          lastTrade = lastTrade.map(lastTrade(amountDecimals, priceDecimals, _)),
          updateId = 0L, // Will be changed below
          timestamp = timestamp,
          settings = if (changedTickSize.isDefined) WsOrderBookSettings(None, changedTickSize).some else None
        )
      wsConnections.map {
        case (conn, updateId) =>
          val newUpdateId = getNextUpdateId(updateId)
          conn ! changes.copy(updateId = newUpdateId)
          conn -> newUpdateId
      }
    } else wsConnections,
    changedAsks = Set.empty,
    changedBids = Set.empty,
    lastTrade = None,
    changedTickSize = None
  )

  def take(xs: TreeMap[Price, Amount], levels: Set[Price]): TreeMap[Price, Amount] = {
    // 1. Levels will be always smaller, than xs
    // 2. A level could gone from xs
    val r = TreeMap.newBuilder[Price, Amount](xs.ordering)
    levels.foreach { level =>
      r += level -> xs.getOrElse(level, 0L)
    }
    r.result()
  }

  def accumulateChanges(lc: LevelAmounts, lt: Option[LastTrade], ts: Option[Double]): WsOrderBookState =
    if (hasSubscriptions) {
      (
        genLens(_.changedAsks).modify(_ ++ lc.asks.keySet) andThen
          genLens(_.changedBids).modify(_ ++ lc.bids.keySet) andThen
          genLens(_.lastTrade).modify { if (lt.isEmpty) _ else lt } andThen
          genLens(_.changedTickSize).modify { if (ts.isEmpty) _ else ts }
      )(this)
    } else this
}