From 8e87ff8c40dcfa9f8c2192bdff1a50cba919737d Mon Sep 17 00:00:00 2001
From: arnaudlabourel <arnaud.labourel@univ-amu.fr>
Date: Tue, 30 Nov 2021 17:42:05 +0100
Subject: [PATCH] =?UTF-8?q?Premi=C3=A8re=20version=20correction?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md                                     |  3 +-
 src/main/java/cluster/App.java                |  7 +-
 src/main/java/cluster/Controller.java         | 53 ++++++++++++++
 src/main/java/cluster/Job.java                | 46 +++++++++++++
 src/main/java/cluster/JobGenerator.java       |  5 ++
 src/main/java/cluster/Main.java               | 30 ++++++++
 src/main/java/cluster/Node.java               | 69 +++++++++++++++++++
 .../NotEnoughRemainingFlopException.java      | 12 ++++
 .../NotEnoughRemainingMemoryException.java    | 12 ++++
 .../cluster/NotEnoughResourceException.java   | 18 +++++
 .../cluster/NotEnoughTotalFlopException.java  | 12 ++++
 .../NotEnoughTotalMemoryException.java        | 12 ++++
 src/main/java/cluster/PriorityJob.java        | 15 ++++
 src/main/java/cluster/PriorityScheduler.java  | 31 +++++++++
 src/main/java/cluster/RandomJobGenerator.java | 27 ++++++++
 src/main/java/cluster/RandomScheduler.java    | 27 ++++++++
 src/main/java/cluster/Scheduler.java          |  7 ++
 .../java/cluster/UniformJobGenerator.java     | 16 +++++
 src/test/java/cluster/JobTest.java            |  5 +-
 19 files changed, 397 insertions(+), 10 deletions(-)
 create mode 100644 src/main/java/cluster/Controller.java
 create mode 100644 src/main/java/cluster/Job.java
 create mode 100644 src/main/java/cluster/JobGenerator.java
 create mode 100644 src/main/java/cluster/Main.java
 create mode 100644 src/main/java/cluster/Node.java
 create mode 100644 src/main/java/cluster/NotEnoughRemainingFlopException.java
 create mode 100644 src/main/java/cluster/NotEnoughRemainingMemoryException.java
 create mode 100644 src/main/java/cluster/NotEnoughResourceException.java
 create mode 100644 src/main/java/cluster/NotEnoughTotalFlopException.java
 create mode 100644 src/main/java/cluster/NotEnoughTotalMemoryException.java
 create mode 100644 src/main/java/cluster/PriorityJob.java
 create mode 100644 src/main/java/cluster/PriorityScheduler.java
 create mode 100644 src/main/java/cluster/RandomJobGenerator.java
 create mode 100644 src/main/java/cluster/RandomScheduler.java
 create mode 100644 src/main/java/cluster/Scheduler.java
 create mode 100644 src/main/java/cluster/UniformJobGenerator.java

diff --git a/README.md b/README.md
index 4ff0176..c16a2ea 100644
--- a/README.md
+++ b/README.md
@@ -10,5 +10,4 @@ sur les nœuds de manière à maximiser l'utilisation de la mémoire et du nombr
 
 ## Membres du projet
 
-- NOM, prénom, numéro de groupe, du premier participant
-- NOM, prénom, numéro de groupe, du deuxième participant
\ No newline at end of file
+- LABOUREL, Arnaud
\ No newline at end of file
diff --git a/src/main/java/cluster/App.java b/src/main/java/cluster/App.java
index 5ef8100..f0dbb57 100644
--- a/src/main/java/cluster/App.java
+++ b/src/main/java/cluster/App.java
@@ -4,14 +4,11 @@ public class App {
 
 
   public static void main(String[] args) throws Exception{
-    // TODO : décommenter pour tester le main.
-    /*
     Job job1 = new Job(1000, 1000);
     Job job2 = new Job(3000, 1000);
     Node node = new Node("Calcul", 10000, 3000);
-    node.acceptJob(job1);
-    node.acceptJob(job2);
+    node.accept(job1);
+    node.accept(job2);
     node.printJobs();
-     */
   }
 }
diff --git a/src/main/java/cluster/Controller.java b/src/main/java/cluster/Controller.java
new file mode 100644
index 0000000..b519c63
--- /dev/null
+++ b/src/main/java/cluster/Controller.java
@@ -0,0 +1,53 @@
+package cluster;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Controller<J extends Job> {
+  private List<J> nonScheduledJobs = new ArrayList<>();
+  private final List<Node> nodes = new ArrayList<>();
+  private final String name;
+  private final Scheduler<J> scheduler;
+
+  void addNode(Node node){
+    nodes.add(node);
+  }
+
+  void submitJob(J job){
+    nonScheduledJobs.add(job);
+  }
+
+  Controller(String name, Scheduler<J> scheduler){
+    this.name = name;
+    this.scheduler = scheduler;
+  }
+
+  void printNodesAndNonScheduledJobs(){
+    System.out.println(this);
+    printNodes();
+    System.out.println("Non scheduled jobs");
+    printNonScheduledJobs();
+  }
+
+  private void printNodes(){
+    for (Node node : nodes){
+      node.printJobs();
+      System.out.println();
+    }
+  }
+
+  private void printNonScheduledJobs(){
+    for (Job job : nonScheduledJobs){
+      System.out.println(job);
+    }
+  }
+
+  public void scheduleJobs(){
+    nonScheduledJobs = scheduler.scheduleJobs(nonScheduledJobs, nodes);
+  }
+
+  @Override
+  public String toString() {
+    return "Controller " + name;
+  }
+}
diff --git a/src/main/java/cluster/Job.java b/src/main/java/cluster/Job.java
new file mode 100644
index 0000000..848c7a0
--- /dev/null
+++ b/src/main/java/cluster/Job.java
@@ -0,0 +1,46 @@
+package cluster;
+
+public class Job {
+  private final int memory;
+  private final int flop;
+  private final int id;
+  private static int jobCount = 0;
+
+  public Job(int memory, int flop) {
+    if (memory <= 0){
+      throw new IllegalArgumentException("Cannot create a job with negative memory : " + getMemory());
+    }
+    if (flop <= 0){
+      throw new IllegalArgumentException("Cannot create a job with a negative number of operations : " + getMemory());
+    }
+    this.memory = memory;
+    this.flop = flop;
+    id = jobCount++;
+  }
+
+  public int getFlop() {
+    return flop;
+  }
+
+  public int getMemory() {
+    return memory;
+  }
+
+  public int getId() {
+    return id;
+  }
+
+  public static void resetJobCount() {
+    jobCount = 0;
+  }
+
+  public static int getJobCount() {
+    return jobCount;
+  }
+
+  public String toString(){
+    return "Job "+ getId()
+            + " (" + getFlop() + "FLOP, "
+            + getMemory() + "o)";
+  }
+}
diff --git a/src/main/java/cluster/JobGenerator.java b/src/main/java/cluster/JobGenerator.java
new file mode 100644
index 0000000..ffd564a
--- /dev/null
+++ b/src/main/java/cluster/JobGenerator.java
@@ -0,0 +1,5 @@
+package cluster;
+
+public interface JobGenerator {
+  Job generateJob();
+}
diff --git a/src/main/java/cluster/Main.java b/src/main/java/cluster/Main.java
new file mode 100644
index 0000000..d729e9b
--- /dev/null
+++ b/src/main/java/cluster/Main.java
@@ -0,0 +1,30 @@
+package cluster;
+
+public class Main {
+  public static void main(String[] args){
+    JobGenerator randomJobGenerator = new RandomJobGenerator(10, 100, 10, 11, 0);
+    Node node = new Node("Calcul", 10000, 3000);
+    for(int i = 0; i<10; i++){
+      try {
+        node.accept(randomJobGenerator.generateJob());
+      }
+      catch (NotEnoughResourceException e){
+        e.printStackTrace();
+      }
+    }
+    node.printJobs();
+    /*
+    Job job1 = new Job(1000, 1000);
+    Job job2 = new Job(3000, 1000);
+    Node node = new Node("Calcul", 10000, 3000);
+    Scheduler<Job> randomScheduler = new RandomScheduler();
+    Controller<Job> controller = new Controller<>("Pharo", randomScheduler);
+    controller.addNode(node);
+    controller.submitJob(job1);
+    controller.submitJob(job2);
+    controller.scheduleJobs();
+    controller.printNodesAndNonScheduledJobs();
+    */
+
+  }
+}
\ No newline at end of file
diff --git a/src/main/java/cluster/Node.java b/src/main/java/cluster/Node.java
new file mode 100644
index 0000000..11dafeb
--- /dev/null
+++ b/src/main/java/cluster/Node.java
@@ -0,0 +1,69 @@
+package cluster;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Node {
+  private final String name;
+  private final int memoryCapacity;
+  private final int flopCapacity;
+
+  private int availableMemory;
+  private int availableFlop;
+  private final List<Job> assignedJobs = new ArrayList<>();
+
+  Node(String name, int memoryCapacity, int flopCapacity) {
+    this.name = name;
+    this.memoryCapacity = memoryCapacity;
+    this.flopCapacity = flopCapacity;
+    availableMemory = memoryCapacity;
+    availableFlop = flopCapacity;
+  }
+
+  boolean canAccept(Job job){
+    return availableMemory >= job.getMemory() &&
+            availableFlop >= job.getFlop();
+  }
+
+  boolean canHandle(Job job){
+    return memoryCapacity >= job.getMemory() &&
+            flopCapacity >= job.getFlop();
+  }
+
+  void accept(Job job) throws NotEnoughResourceException{
+    if(memoryCapacity < job.getMemory()){
+      throw new NotEnoughTotalMemoryException(this, job);
+    }
+    if(availableMemory < job.getMemory()){
+      throw new NotEnoughRemainingMemoryException(this, job);
+    }
+    if(flopCapacity < job.getFlop()){
+      throw new NotEnoughTotalFlopException(this, job);
+    }
+    if(availableFlop < job.getFlop()){
+      throw new NotEnoughRemainingFlopException(this, job);
+    }
+    assignedJobs.add(job);
+    availableMemory -= job.getMemory();
+    availableFlop -= job.getFlop();
+  }
+
+  int usedMemory(){
+    return memoryCapacity - availableMemory;
+  }
+
+  int usedFlop(){
+    return flopCapacity - availableFlop;
+  }
+
+  public String toString(){
+    return "Node " + name + " (" + usedFlop() + "/" + flopCapacity + "FLOP, " + usedMemory() + "/" + memoryCapacity +"o)";
+  }
+
+  void printJobs(){
+    System.out.println(this);
+    for(Job job : assignedJobs){
+      System.out.println(job);
+    }
+  }
+}
diff --git a/src/main/java/cluster/NotEnoughRemainingFlopException.java b/src/main/java/cluster/NotEnoughRemainingFlopException.java
new file mode 100644
index 0000000..bb0f015
--- /dev/null
+++ b/src/main/java/cluster/NotEnoughRemainingFlopException.java
@@ -0,0 +1,12 @@
+package cluster;
+
+public class NotEnoughRemainingFlopException extends NotEnoughResourceException {
+  public NotEnoughRemainingFlopException(Node node, Job job) {
+    super(node, job);
+  }
+
+  @Override
+  public String getSentenceMessage() {
+    return " has not enough remaining FLOP to handle ";
+  }
+}
diff --git a/src/main/java/cluster/NotEnoughRemainingMemoryException.java b/src/main/java/cluster/NotEnoughRemainingMemoryException.java
new file mode 100644
index 0000000..40818f7
--- /dev/null
+++ b/src/main/java/cluster/NotEnoughRemainingMemoryException.java
@@ -0,0 +1,12 @@
+package cluster;
+
+public class NotEnoughRemainingMemoryException extends NotEnoughResourceException{
+  public NotEnoughRemainingMemoryException(Node node, Job job) {
+    super(node, job);
+  }
+
+  @Override
+  public String getSentenceMessage() {
+    return " has not enough remaining memory to handle ";
+  }
+}
diff --git a/src/main/java/cluster/NotEnoughResourceException.java b/src/main/java/cluster/NotEnoughResourceException.java
new file mode 100644
index 0000000..4edcb22
--- /dev/null
+++ b/src/main/java/cluster/NotEnoughResourceException.java
@@ -0,0 +1,18 @@
+package cluster;
+
+public abstract class NotEnoughResourceException extends Exception {
+  private final Node node;
+  private final Job job;
+
+  public NotEnoughResourceException(Node node, Job job) {
+    this.node = node;
+    this.job = job;
+  }
+
+  @Override
+  public String getMessage() {
+    return node + getSentenceMessage() + job;
+  }
+
+  public abstract String getSentenceMessage();
+}
diff --git a/src/main/java/cluster/NotEnoughTotalFlopException.java b/src/main/java/cluster/NotEnoughTotalFlopException.java
new file mode 100644
index 0000000..0a36b25
--- /dev/null
+++ b/src/main/java/cluster/NotEnoughTotalFlopException.java
@@ -0,0 +1,12 @@
+package cluster;
+
+public class NotEnoughTotalFlopException extends NotEnoughResourceException{
+  public NotEnoughTotalFlopException(Node node, Job job) {
+    super(node, job);
+  }
+
+  @Override
+  public String getSentenceMessage() {
+    return " has not enough total number of operations to handle ";
+  }
+}
diff --git a/src/main/java/cluster/NotEnoughTotalMemoryException.java b/src/main/java/cluster/NotEnoughTotalMemoryException.java
new file mode 100644
index 0000000..23d8d37
--- /dev/null
+++ b/src/main/java/cluster/NotEnoughTotalMemoryException.java
@@ -0,0 +1,12 @@
+package cluster;
+
+public class NotEnoughTotalMemoryException extends NotEnoughResourceException {
+  public NotEnoughTotalMemoryException(Node node, Job job) {
+    super(node, job);
+  }
+
+  @Override
+  public String getSentenceMessage() {
+    return " has not enough total memory to handle ";
+  }
+}
diff --git a/src/main/java/cluster/PriorityJob.java b/src/main/java/cluster/PriorityJob.java
new file mode 100644
index 0000000..9287779
--- /dev/null
+++ b/src/main/java/cluster/PriorityJob.java
@@ -0,0 +1,15 @@
+package cluster;
+
+public class PriorityJob extends Job implements Comparable<PriorityJob>{
+  private final int priority;
+
+  public PriorityJob(int memory, int flop, int priority) {
+    super(memory, flop);
+    this.priority = priority;
+  }
+
+  @Override
+  public int compareTo(PriorityJob job) {
+    return job.priority - this.priority;
+  }
+}
diff --git a/src/main/java/cluster/PriorityScheduler.java b/src/main/java/cluster/PriorityScheduler.java
new file mode 100644
index 0000000..cf1d5fd
--- /dev/null
+++ b/src/main/java/cluster/PriorityScheduler.java
@@ -0,0 +1,31 @@
+package cluster;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class PriorityScheduler implements Scheduler<PriorityJob> {
+  @Override
+  public List<PriorityJob> scheduleJobs(List<PriorityJob> jobs, List<Node> nodes) {
+    List<PriorityJob> nonScheduledJobs = new ArrayList<>();
+    Collections.sort(jobs);
+    for (PriorityJob job : jobs) {
+      if(!scheduleJob(job, nodes)){
+        nonScheduledJobs.add(job);
+      }
+    }
+    return nonScheduledJobs;
+  }
+
+
+  private boolean scheduleJob(Job job, List<Node> nodes){
+    for (Node node : nodes) {
+      try {
+        node.accept(job);
+        return true;
+      }
+      catch (NotEnoughResourceException e){}
+    }
+    return false;
+  }
+}
diff --git a/src/main/java/cluster/RandomJobGenerator.java b/src/main/java/cluster/RandomJobGenerator.java
new file mode 100644
index 0000000..69ee89a
--- /dev/null
+++ b/src/main/java/cluster/RandomJobGenerator.java
@@ -0,0 +1,27 @@
+package cluster;
+
+import java.util.Random;
+
+public class RandomJobGenerator implements JobGenerator{
+  private final int minMemory;
+  private final int maxMemory;
+  private final int minFlop;
+  private final int maxFlop;
+  private final Random random;
+
+  public RandomJobGenerator(int minMemory, int maxMemory, int minFlop, int maxFlop, long seed) {
+    this.minMemory = minMemory;
+    this.maxMemory = maxMemory;
+    this.minFlop = minFlop;
+    this.maxFlop = maxFlop;
+    this.random = new Random(seed);
+  }
+
+  private int nextInt(int min, int max){
+    return min + random.nextInt(max - min + 1);
+  }
+
+  public Job generateJob(){
+    return new Job(nextInt(minMemory, maxMemory), nextInt(minFlop, maxFlop));
+  }
+}
diff --git a/src/main/java/cluster/RandomScheduler.java b/src/main/java/cluster/RandomScheduler.java
new file mode 100644
index 0000000..c8571bb
--- /dev/null
+++ b/src/main/java/cluster/RandomScheduler.java
@@ -0,0 +1,27 @@
+package cluster;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+public class RandomScheduler implements Scheduler<Job>{
+  private Random random = new Random();
+
+  public Node randomNode(List<Node> nodes){
+    return nodes.get(random.nextInt(nodes.size()));
+  }
+
+  @Override
+  public List<Job> scheduleJobs(List<Job> jobs, List<Node> nodes) {
+    List<Job> nonScheduledJobs  = new ArrayList<>();
+    for(Job job : jobs){
+      try{
+        randomNode(nodes).accept(job);
+      }
+      catch (NotEnoughResourceException e){
+        nonScheduledJobs.add(job);
+      }
+    }
+    return nonScheduledJobs ;
+  }
+}
diff --git a/src/main/java/cluster/Scheduler.java b/src/main/java/cluster/Scheduler.java
new file mode 100644
index 0000000..9111ad2
--- /dev/null
+++ b/src/main/java/cluster/Scheduler.java
@@ -0,0 +1,7 @@
+package cluster;
+
+import java.util.List;
+
+public interface Scheduler<J extends Job> {
+  List<J> scheduleJobs(List<J> jobs, List<Node> nodes);
+}
diff --git a/src/main/java/cluster/UniformJobGenerator.java b/src/main/java/cluster/UniformJobGenerator.java
new file mode 100644
index 0000000..0260cf7
--- /dev/null
+++ b/src/main/java/cluster/UniformJobGenerator.java
@@ -0,0 +1,16 @@
+package cluster;
+
+public class UniformJobGenerator implements JobGenerator{
+  private final int memory;
+  private final int flop;
+
+  public UniformJobGenerator(int memory, int flop) {
+    this.memory = memory;
+    this.flop = flop;
+  }
+
+  @Override
+  public Job generateJob() {
+    return new Job(memory, flop);
+  }
+}
diff --git a/src/test/java/cluster/JobTest.java b/src/test/java/cluster/JobTest.java
index 1b87f83..820e28e 100644
--- a/src/test/java/cluster/JobTest.java
+++ b/src/test/java/cluster/JobTest.java
@@ -5,8 +5,7 @@ import static org.junit.jupiter.api.Assertions.*;
 import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
 
 public class JobTest {
-    //TODO : décommenter pour tester la classe Job
-/*
+
     @Test
     void testToString(){
         // Test with Junit
@@ -44,6 +43,6 @@ public class JobTest {
             assertThat(Job.getJobCount()).isEqualTo(jobCount);
         }
     }
-    */
+
 
 }
-- 
GitLab