From 1593a6624c1a432ee43d5b81ba8383a3a7d0afdc Mon Sep 17 00:00:00 2001
From: Maxime MORGE <maxime.morge@univ-lille.fr>
Date: Tue, 27 Jun 2023 15:54:01 +0200
Subject: [PATCH] PSSI: Redo XP 4 C^S_H

---
 .../smastaplus/core/ExecutedAllocation.scala  | 50 +++++++++++++++++++
 .../consumer/ConsumptionExperiment.scala      |  2 +-
 2 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/src/main/scala/org/smastaplus/core/ExecutedAllocation.scala b/src/main/scala/org/smastaplus/core/ExecutedAllocation.scala
index 88b3f553..bda3117c 100644
--- a/src/main/scala/org/smastaplus/core/ExecutedAllocation.scala
+++ b/src/main/scala/org/smastaplus/core/ExecutedAllocation.scala
@@ -431,6 +431,56 @@ Allocation(stap, delay){
    * Returns the ongoing mean global flowtime
    */
   def ongoingMeanGlobalFlowtime: Double = ongoingGlobalFlowtime / jobs.size
+
+  /**
+   * Returns the delay of the task for the node, eventually +∞
+   * The delay is the waiting time from the current time before the task is processed
+   */
+  private def exPostDelay(task: Task, node: ComputingNode): Double = {
+    bundle(node).takeWhile(_ != task).foldLeft(0.0) { (sum, previousTask) => sum + simulatedCost.simulatedCost(stap.cost(previousTask, node), node) }
+  }
+
+  /**
+   * Returns the completion time of the task for the computing node
+   * Since we consider time-extended allocation,
+   * the completion time of a task depends on the release time of its job
+   * WARNING the cost unit is a millisecond
+   */
+  private def exPostCompletionTime(task: Task, node: ComputingNode): Double = {
+    val duration = new Duration(stap.jobOf(task).releaseTime.toDateTime(), time.toDateTime())
+    val theTime =
+      duration.getMillis + exPostDelay(task, node) + simulatedCost.simulatedCost(stap.cost(task, node), node)
+    theTime
+  }
+
+  /**
+   * Returns the completion time of the task, eventually +∞
+   */
+  private def exPostCompletionTime(task: Task): Double = {
+    if (node(task).isDefined) return exPostCompletionTime(task, node(task).get)
+    0.0
+  }
+
+
+  /**
+   * Returns the completion time of the job, i.e. its makespan
+   */
+  private def exPostCompletionTime(job: Job): Double = job.tasks.foldLeft(0.0) {
+    (maxCompletionTime, task) => Math.max(exPostCompletionTime(task), maxCompletionTime)
+  }
+
+  /**
+   * Returns the mean globalFlowtime of the jobs
+   */
+  private def exPostGlobalFlowtime: Double = stap.jobs.foldLeft(0.0)(
+    (sum: Double, job: Job) => sum + exPostCompletionTime(job)
+  )
+
+  /**
+   * Returns the mean localFlowtime of the jobs
+   */
+  def exPostMeanGlobalFlowtime: Double = exPostGlobalFlowtime / stap.l
+
 }
 
   /**
diff --git a/src/main/scala/org/smastaplus/experiment/consumer/ConsumptionExperiment.scala b/src/main/scala/org/smastaplus/experiment/consumer/ConsumptionExperiment.scala
index 16b71a34..147fba9f 100644
--- a/src/main/scala/org/smastaplus/experiment/consumer/ConsumptionExperiment.scala
+++ b/src/main/scala/org/smastaplus/experiment/consumer/ConsumptionExperiment.scala
@@ -78,7 +78,7 @@ class ConsumptionExperiment(setting: ConsumptionSetting) extends Experiment[Cons
         "09NbDelegatedTasks" -> setting.consumer.nbDelegatedTasks,
         "10NbFirstStages" -> setting.consumer.nbFirstStages,
         "11NbSecondStages" -> setting.consumer.nbSecondStages,
-        "12MeanSimulatedFlowtime" -> result.consumptions2allocation.realGlobalMeanFlowtime//result.simulatedMeanGlobalFlowtime
+        "12MeanSimulatedFlowtime" -> result.consumptions2allocation.exPostMeanGlobalFlowtime//.realGlobalMeanFlowtime//result.simulatedMeanGlobalFlowtime
       ))
     if (result.isSound) outcome
     else throw new RuntimeException(s"Consumer: the outcome\n $result\nis not sound for\n ${setting.allocation.stap}")
-- 
GitLab