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