<commit_before>package rescala.graph

import java.util

import rescala.graph.Pulse.{Diff, NoChange}
import rescala.turns.{Ticket, Turn}

import scala.collection.JavaConverters.asScalaSetConverter

/** A Reactive is something that can be reevaluated */
trait Reactive {
  final override val hashCode: Int = Globals.nextID().hashCode()

  protected[rescala] def lock: ITurnLock

  protected[rescala] def syncFactory: SynchronizationFactory

  final private[rescala] val level: Buffer[Int] = syncFactory.buffer(0, math.max, lock)

  final private[rescala] val outgoing: Buffer[Set[Reactive]] = syncFactory.buffer(Set(), Buffer.commitAsIs, lock)

  protected[rescala] def incoming(implicit turn: Turn): Set[Reactive]

  /** called when it is this events turn to be evaluated
    * (head of the evaluation queue) */
  protected[rescala] def reevaluate()(implicit turn: Turn): ReevaluationResult

  /** for debugging */
  private val name = Globals.declarationLocationName()
  override def toString = name
}


/** helper class to initialise engine and select lock */
abstract class Base(
  final override protected[rescala] val syncFactory: SynchronizationFactory,
  knownDependencies: Set[Reactive] = Set.empty) extends {
  final override val lock: ITurnLock =
    if (knownDependencies.size == 1) knownDependencies.head.lock
    else syncFactory.lock()
} with Reactive {

  val weakKnownDependencies = {
    val whs = util.Collections.newSetFromMap(new util.WeakHashMap[Reactive, java.lang.Boolean](knownDependencies.size))
    knownDependencies.foreach(whs.add)
    whs
  }

  def staticIncoming: Set[Reactive] = weakKnownDependencies.asScala.toSet
}

class Reader[+P](pulses: Buffer[Pulse[P]]) {
  def pulse(implicit turn: Turn): Pulse[P] = pulses.get

  final def get(implicit turn: Turn): P = pulse match {
    case NoChange(Some(value)) => value
    case Diff(value, oldOption) => value
    case NoChange(None) => throw new IllegalStateException("stateful reactive has never pulsed")
  }
}

/** A node that has nodes that depend on it */
trait Pulsing[+P] extends Reactive {
  protected[this] def strategy: (Pulse[P], Pulse[P]) => Pulse[P] = Buffer.transactionLocal[Pulse[P]]
  final protected[this] val pulses: Buffer[Pulse[P]] = syncFactory.buffer(Pulse.none, strategy, lock)

  final def pulse(implicit turn: Turn): Pulse[P] = pulses.get

  final val reader: Reader[P] = new Reader[P](pulses)
}


/** a node that has a current state */
trait Stateful[+A] extends Pulsing[A] {
  override protected[this] def strategy: (Pulse[A], Pulse[A]) => Pulse[A] = Buffer.keepPulse
<commit_msg>disable weak dependencies, because unavailable on JS<commit_after>package rescala.graph

import java.util

import rescala.graph.Pulse.{Diff, NoChange}
import rescala.turns.{Ticket, Turn}

import scala.collection.JavaConverters.asScalaSetConverter

/** A Reactive is something that can be reevaluated */
trait Reactive {
  final override val hashCode: Int = Globals.nextID().hashCode()

  protected[rescala] def lock: ITurnLock

  protected[rescala] def syncFactory: SynchronizationFactory

  final private[rescala] val level: Buffer[Int] = syncFactory.buffer(0, math.max, lock)

  final private[rescala] val outgoing: Buffer[Set[Reactive]] = syncFactory.buffer(Set(), Buffer.commitAsIs, lock)

  protected[rescala] def incoming(implicit turn: Turn): Set[Reactive]

  /** called when it is this events turn to be evaluated
    * (head of the evaluation queue) */
  protected[rescala] def reevaluate()(implicit turn: Turn): ReevaluationResult

  /** for debugging */
  private val name = Globals.declarationLocationName()
  override def toString = name
}


/** helper class to initialise engine and select lock */
abstract class Base(
  final override protected[rescala] val syncFactory: SynchronizationFactory,
  knownDependencies: Set[Reactive] = Set.empty) extends {
  final override val lock: ITurnLock =
    if (knownDependencies.size == 1) knownDependencies.head.lock
    else syncFactory.lock()
} with Reactive {

  def staticIncoming: Set[Reactive] = knownDependencies
}

class Reader[+P](pulses: Buffer[Pulse[P]]) {
  def pulse(implicit turn: Turn): Pulse[P] = pulses.get

  final def get(implicit turn: Turn): P = pulse match {
    case NoChange(Some(value)) => value
    case Diff(value, oldOption) => value
    case NoChange(None) => throw new IllegalStateException("stateful reactive has never pulsed")
  }
}

/** A node that has nodes that depend on it */
trait Pulsing[+P] extends Reactive {
  protected[this] def strategy: (Pulse[P], Pulse[P]) => Pulse[P] = Buffer.transactionLocal[Pulse[P]]
  final protected[this] val pulses: Buffer[Pulse[P]] = syncFactory.buffer(Pulse.none, strategy, lock)

  final def pulse(implicit turn: Turn): Pulse[P] = pulses.get

  final val reader: Reader[P] = new Reader[P](pulses)
}


/** a node that has a current state */
trait Stateful[+A] extends Pulsing[A] {
  override protected[this] def strategy: (Pulse[A], Pulse[A]) => Pulse[A] = Buffer.keepPulse

{'fraction_non_alphanumeric': 0.11349508722678965, 'fraction_numerical': 0.0008020854220974534, 'mean_word_length': 4.9169632265717675, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4664247', 'n_tokens_mistral': 1590, 'n_tokens_neox': 1524, 'n_words': 455}