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

mb.pie.runtime.store.InMemory.kt Maven / Gradle / Ivy

The newest version!
package mb.pie.runtime.store

import mb.pie.api.*
import java.util.concurrent.ConcurrentHashMap

class InMemoryStore : Store, StoreReadTxn, StoreWriteTxn {
  private val inputs = ConcurrentHashMap()
  private val outputs = ConcurrentHashMap>()
  private val taskReqs = ConcurrentHashMap>()
  private val callersOf = ConcurrentHashMap>()
  private val fileReqs = ConcurrentHashMap>()
  private val requireesOf = ConcurrentHashMap>()
  private val fileGens = ConcurrentHashMap>()
  private val generatorOf = ConcurrentHashMap()


  override fun readTxn() = this
  override fun writeTxn() = this
  override fun sync() {}
  override fun close() {}


  override fun input(key: TaskKey) = inputs[key]
  override fun setInput(key: TaskKey, input: In) {
    inputs[key] = input
  }

  override fun output(key: TaskKey) = if(!outputs.containsKey(key)) {
    null
  } else {
    val wrapper = outputs[key]!!
    Output(wrapper.output)
  }

  override fun setOutput(key: TaskKey, output: Out) {
    // ConcurrentHashMap does not support null values, so also wrap outputs (which can be null) in an Output object.
    outputs[key] = Output(output)
  }

  override fun taskRequires(key: TaskKey) = taskReqs.getOrEmptyList(key)
  override fun callersOf(key: TaskKey): Set = callersOf.getOrPutSet(key)
  override fun setTaskRequires(key: TaskKey, taskRequires: ArrayList) {
    // Remove old call requirements
    val oldTaskReqs = this.taskReqs.remove(key)
    if(oldTaskReqs != null) {
      for(taskReq in oldTaskReqs) {
        callersOf.getOrPutSet(taskReq.callee).remove(key)
      }
    }
    // OPTO: diff taskReqs and oldCallReqs, remove/add entries based on diff.
    // Add new call requirements
    this.taskReqs[key] = taskRequires
    for(taskReq in taskRequires) {
      callersOf.getOrPutSet(taskReq.callee).add(key)
    }
  }

  override fun resourceRequires(key: TaskKey) = fileReqs.getOrEmptyList(key)
  override fun requireesOf(key: ResourceKey): Set = requireesOf.getOrPutSet(key)
  override fun setResourceRequires(key: TaskKey, resourceRequires: ArrayList) {
    // Remove old file requirements
    val oldFileReqs = this.fileReqs.remove(key)
    if(oldFileReqs != null) {
      for(fileReq in oldFileReqs) {
        requireesOf.getOrPutSet(fileReq.key).remove(key)
      }
    }
    // OPTO: diff fileReqs and oldPathReqs, remove/add entries based on diff.
    // Add new call requirements
    this.fileReqs[key] = resourceRequires
    for(fileReq in resourceRequires) {
      requireesOf.getOrPutSet(fileReq.key).add(key)
    }
  }

  override fun resourceProvides(key: TaskKey) = fileGens.getOrEmptyList(key)
  override fun providerOf(key: ResourceKey): TaskKey? = generatorOf[key]
  override fun setResourceProvides(key: TaskKey, resourceProvides: ArrayList) {
    // Remove old file generators
    val oldFileGens = this.fileGens.remove(key)
    if(oldFileGens != null) {
      for(fileGen in oldFileGens) {
        generatorOf.remove(fileGen.key)
      }
    }
    // OPTO: diff fileGens and oldPathGens, remove/add entries based on diff.
    // Add new file generators
    this.fileGens[key] = resourceProvides
    for(fileGen in resourceProvides) {
      generatorOf[fileGen.key] = key
    }
  }

  override fun data(key: TaskKey): TaskData<*, *>? {
    val input = input(key) ?: return null
    val output = output(key) ?: return null
    val callReqs = taskRequires(key)
    val pathReqs = resourceRequires(key)
    val pathGens = resourceProvides(key)
    return TaskData(input, output.output, callReqs, pathReqs, pathGens)
  }

  override fun setData(key: TaskKey, data: TaskData<*, *>) {
    val (input, output, callReqs, pathReqs, pathGens) = data
    setInput(key, input)
    setOutput(key, output)
    setTaskRequires(key, callReqs)
    setResourceRequires(key, pathReqs)
    setResourceProvides(key, pathGens)
  }


  override fun numSourceFiles(): Int {
    var numSourceFiles = 0
    for(file in requireesOf.keys) {
      if(!generatorOf.containsKey(file)) {
        ++numSourceFiles
      }
    }
    return numSourceFiles
  }


  override fun drop() {
    outputs.clear()
    taskReqs.clear()
    callersOf.clear()
    fileReqs.clear()
    requireesOf.clear()
    fileGens.clear()
    generatorOf.clear()
  }


  override fun toString(): String {
    return "InMemoryStore"
  }
}

@Suppress("NOTHING_TO_INLINE")
private inline fun  ConcurrentHashMap>.getOrPutSet(key: K) = this.getOrPut(key) { ConcurrentHashMap.newKeySet() }!!

@Suppress("NOTHING_TO_INLINE")
private inline fun  ConcurrentHashMap>.getOrEmptyList(key: K) = this.getOrElse(key) { arrayListOf() }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy