Baseline. Q1 is about to be done.
This commit is contained in:
commit
f59aeac67b
10 changed files with 459 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
target/
|
||||||
|
.vim/
|
30
pom.xml
Normal file
30
pom.xml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>usherbrooke.ift630</groupId>
|
||||||
|
<artifactId>proj2</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>proj2</name>
|
||||||
|
<url>http://maven.apache.org</url>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
81
src/main/java/usherbrooke/ift630/App.java
Normal file
81
src/main/java/usherbrooke/ift630/App.java
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
package usherbrooke.ift630;
|
||||||
|
|
||||||
|
import java.lang.Long;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
/**
|
||||||
|
* Hello world!
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class App
|
||||||
|
{
|
||||||
|
static private int numStops = 10;
|
||||||
|
static private int numBusses = 10;
|
||||||
|
static private int numStopPerBus = 2;
|
||||||
|
static private int numPassengersPerBus = 2;
|
||||||
|
static private int numPassengers = 20;
|
||||||
|
static private int numPassengersPerStop = 2;
|
||||||
|
static private int numThreads = 5;
|
||||||
|
static private int timeBetweenStops = 5;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
ExecutorService threads = Executors.newFixedThreadPool(numThreads);
|
||||||
|
ArrayList<Stop> stops = new ArrayList<Stop>();
|
||||||
|
ArrayList<Bus> busses = new ArrayList<Bus>();
|
||||||
|
ArrayList<Passenger> passengers = new ArrayList<Passenger>();
|
||||||
|
|
||||||
|
for (int k = 0; k < numStops; k++) {
|
||||||
|
Stop s = new Stop(k, numPassengersPerStop);
|
||||||
|
stops.add(s);
|
||||||
|
|
||||||
|
threads.submit(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int k = 0; k < numPassengers; k++) {
|
||||||
|
Stop start, dest;
|
||||||
|
|
||||||
|
// select start where there is some room left
|
||||||
|
do {
|
||||||
|
start = stops.get(((int) (Math.random() * numStops)));
|
||||||
|
} while (start.getCurrentCapacity() >= start.getMaxCapacity());
|
||||||
|
|
||||||
|
dest = stops.get((int) (Math.random() * numStops));
|
||||||
|
|
||||||
|
Passenger p = new Passenger(k, dest, start);
|
||||||
|
passengers.add(p);
|
||||||
|
start.addPassenger(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int k = 0; k < numBusses; k++) {
|
||||||
|
ArrayList<Stop> s_list = new ArrayList<Stop>();
|
||||||
|
Stop s;
|
||||||
|
while (s_list.size() < numStopPerBus) {
|
||||||
|
do {
|
||||||
|
s = stops.get((int) (Math.random() * numStops));
|
||||||
|
} while (s_list.contains(s));
|
||||||
|
s_list.add(s);
|
||||||
|
}
|
||||||
|
Bus b = new Bus(s_list, k, timeBetweenStops, numPassengersPerBus);
|
||||||
|
|
||||||
|
b.printDetails();
|
||||||
|
|
||||||
|
busses.add(b);
|
||||||
|
|
||||||
|
synchronized (b) {
|
||||||
|
b.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// start bus thread
|
||||||
|
// (here so init logs are clean)
|
||||||
|
for (Bus b : busses) {
|
||||||
|
threads.submit(b);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
threads.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
110
src/main/java/usherbrooke/ift630/Bus.java
Normal file
110
src/main/java/usherbrooke/ift630/Bus.java
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
package usherbrooke.ift630;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class Bus extends Thread {
|
||||||
|
private ArrayList<Passenger> passengers;
|
||||||
|
private ArrayList<Stop> stops;
|
||||||
|
private String name;
|
||||||
|
private int id;
|
||||||
|
private int maxCapacity;
|
||||||
|
private int currentCapacity;
|
||||||
|
private int timeBetweenStops;
|
||||||
|
private Stop currentStop;
|
||||||
|
|
||||||
|
private int timeBetweenStops() {
|
||||||
|
return (int) (Math.random() * timeBetweenStops * timeBetweenStops);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Stop goToNextStop() {
|
||||||
|
currentStop = stops.remove(0);
|
||||||
|
try {
|
||||||
|
Thread.sleep(timeBetweenStops() * 1000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
return currentStop;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO ??
|
||||||
|
private ArrayList<Passenger> getNextStopPassengers() {
|
||||||
|
ArrayList<Passenger> res = new ArrayList<Passenger>();
|
||||||
|
|
||||||
|
for (Passenger p : passengers) {
|
||||||
|
Stop next = stops.get(1);
|
||||||
|
next.getPassengerByDest(stops);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (currentStop != null) {
|
||||||
|
embarkPassengers();
|
||||||
|
disembarkPassengers();
|
||||||
|
|
||||||
|
currentStop = goToNextStop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Bus(ArrayList<Stop> s, int id, int time, int maxCapacity) {
|
||||||
|
this.timeBetweenStops = time;
|
||||||
|
this.name = "Bus n°" + id;
|
||||||
|
this.id = id;
|
||||||
|
this.passengers = new ArrayList<Passenger>();
|
||||||
|
this.stops = s;
|
||||||
|
this.currentStop = stops.get(0);
|
||||||
|
this.currentCapacity = 0;
|
||||||
|
this.maxCapacity = maxCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void disembarkPassengers() {
|
||||||
|
for (Passenger p : passengers) {
|
||||||
|
Logger.getInstance().print(id, "[BUS] " + p.getName() + " got out of " + name);
|
||||||
|
|
||||||
|
if (p.getDest() == currentStop) {
|
||||||
|
p.disembark();
|
||||||
|
currentCapacity--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void embarkPassengers() {
|
||||||
|
try {
|
||||||
|
ArrayList<Passenger> list = currentStop.getPassengerByDest(stops);
|
||||||
|
Logger.getInstance().print(id, "[BUS] hop into " + name + "!");
|
||||||
|
if (currentCapacity >= maxCapacity)
|
||||||
|
throw new OverCapacityException("Over bus capacity.");
|
||||||
|
for (Passenger p : list) {
|
||||||
|
passengers.add(p);
|
||||||
|
currentStop.removePassenger(p);
|
||||||
|
currentCapacity++;
|
||||||
|
|
||||||
|
Logger.getInstance().print(id,
|
||||||
|
"[BUS] " + p.getName() + " embarked in " + name + " at " + currentStop.getName());
|
||||||
|
}
|
||||||
|
} catch (IndexOutOfBoundsException | OverCapacityException e) {
|
||||||
|
Logger.getInstance().print(id, "ERROR " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printDetails(int indent) {
|
||||||
|
Logger.getInstance().print(id, "\t".repeat(indent) + "---".repeat(3) + " Bus details " + "---".repeat(3));
|
||||||
|
Logger.getInstance().print(id, "\t".repeat(indent) + name);
|
||||||
|
Logger.getInstance().print(id, "\t".repeat(indent) + "time between stops: " + timeBetweenStops);
|
||||||
|
Logger.getInstance().print(id, "\t".repeat(indent) + "max capacity: " + maxCapacity);
|
||||||
|
Logger.getInstance().print(id, "\t".repeat(indent) + "current stop: " + currentStop.getName());
|
||||||
|
Logger.getInstance().print(id, "\t".repeat(indent) + "stops: " );
|
||||||
|
|
||||||
|
|
||||||
|
for (Stop s : stops) {
|
||||||
|
s.printDetails(indent + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printDetails() {
|
||||||
|
printDetails(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
51
src/main/java/usherbrooke/ift630/Logger.java
Normal file
51
src/main/java/usherbrooke/ift630/Logger.java
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
package usherbrooke.ift630;
|
||||||
|
|
||||||
|
public class Logger {
|
||||||
|
private static Logger logger;
|
||||||
|
|
||||||
|
private static final String RED = "\u001B[31m";
|
||||||
|
private static final String GREEN = "\u001B[32m";
|
||||||
|
private static final String YELLOW = "\u001B[33m";
|
||||||
|
private static final String BLUE = "\u001B[34m";
|
||||||
|
private static final String PURPLE = "\u001B[35m";
|
||||||
|
private static final String CYAN = "\u001B[36m";
|
||||||
|
private static final String RESET = "\u001B[0m" ;
|
||||||
|
private static final String WHITE = "\u001B[0m";
|
||||||
|
|
||||||
|
private String[] cols = {
|
||||||
|
WHITE,
|
||||||
|
RED,
|
||||||
|
GREEN,
|
||||||
|
YELLOW,
|
||||||
|
BLUE,
|
||||||
|
PURPLE,
|
||||||
|
CYAN,
|
||||||
|
};
|
||||||
|
|
||||||
|
private Logger() {}
|
||||||
|
|
||||||
|
public void printTime() {
|
||||||
|
System.out.println(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printTime(String s) {
|
||||||
|
System.out.println(System.currentTimeMillis() + s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printTime(int c, String s) {
|
||||||
|
System.out.println(cols[c % cols.length] +System.currentTimeMillis() + s + RESET);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void print(int c, String s) {
|
||||||
|
System.out.println(cols[c % cols.length] + s + RESET);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Logger getInstance() {
|
||||||
|
if(logger == null) {
|
||||||
|
logger = new Logger();
|
||||||
|
}
|
||||||
|
|
||||||
|
return logger;
|
||||||
|
}
|
||||||
|
}
|
10
src/main/java/usherbrooke/ift630/NotFoundException.java
Normal file
10
src/main/java/usherbrooke/ift630/NotFoundException.java
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package usherbrooke.ift630;
|
||||||
|
|
||||||
|
public class NotFoundException extends Exception {
|
||||||
|
NotFoundException() {}
|
||||||
|
|
||||||
|
public NotFoundException(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
10
src/main/java/usherbrooke/ift630/OverCapacityException.java
Normal file
10
src/main/java/usherbrooke/ift630/OverCapacityException.java
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package usherbrooke.ift630;
|
||||||
|
|
||||||
|
public class OverCapacityException extends Exception {
|
||||||
|
OverCapacityException() {}
|
||||||
|
|
||||||
|
public OverCapacityException(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
41
src/main/java/usherbrooke/ift630/Passenger.java
Normal file
41
src/main/java/usherbrooke/ift630/Passenger.java
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
package usherbrooke.ift630;
|
||||||
|
|
||||||
|
public class Passenger {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private int id;
|
||||||
|
private Stop dest;
|
||||||
|
private Stop start;
|
||||||
|
|
||||||
|
Passenger(int id, Stop dest, Stop start) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = "Passenger " + id;
|
||||||
|
this.dest = dest;
|
||||||
|
this.start = start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void embark() {}
|
||||||
|
|
||||||
|
public synchronized void disembark() {}
|
||||||
|
|
||||||
|
public Stop getStart() {
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stop getDest() {
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printDetails(int indent) {
|
||||||
|
Logger.getInstance().print(id, "\t".repeat(indent) + "---".repeat(3) + " Passenger details " + "---".repeat(3));
|
||||||
|
Logger.getInstance().print(id, "\t".repeat(indent) + name + " start: " + start.getName() + " dest: " + dest.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printDetails() {
|
||||||
|
printDetails(0);
|
||||||
|
}
|
||||||
|
}
|
84
src/main/java/usherbrooke/ift630/Stop.java
Normal file
84
src/main/java/usherbrooke/ift630/Stop.java
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
package usherbrooke.ift630;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class Stop implements Runnable {
|
||||||
|
private String name;
|
||||||
|
private int id;
|
||||||
|
private int maxCapacity;
|
||||||
|
private ArrayList<Passenger> passengers;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// xd do nothing for now
|
||||||
|
//for (Passenger p : passengers) {
|
||||||
|
// //
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
// run once. Then, queue the same thread, and exit.
|
||||||
|
// Message a bus their current number of passenger ; and the
|
||||||
|
// number of passenger willing to take this bus.
|
||||||
|
Stop(int id, int maxCapacity) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = "Stop " + id;
|
||||||
|
this.passengers = new ArrayList<Passenger>();
|
||||||
|
this.maxCapacity = maxCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Passenger getPassenger() {
|
||||||
|
return passengers.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPassenger(Passenger p) {
|
||||||
|
passengers.add(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return all passenger that stops at a stop in the list
|
||||||
|
public ArrayList<Passenger> getPassengerByDest(ArrayList<Stop> list) {
|
||||||
|
// res for a little cleaner code
|
||||||
|
ArrayList<Passenger> res = new ArrayList<Passenger>();
|
||||||
|
for (Stop s : list) {
|
||||||
|
for (Passenger p : passengers) {
|
||||||
|
if (p.getDest() == s) {
|
||||||
|
// if we got one, return & abort loop
|
||||||
|
res.add(p);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCurrentCapacity() {
|
||||||
|
return passengers.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxCapacity() {
|
||||||
|
return maxCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void printDetails(int indent) {
|
||||||
|
Logger.getInstance().print(id, "\t".repeat(indent) + "---".repeat(3) + " Stop details " + "---".repeat(3));
|
||||||
|
Logger.getInstance().print(id, "\t".repeat(indent) + name);
|
||||||
|
|
||||||
|
for (Passenger p : passengers) {
|
||||||
|
p.printDetails(indent + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printDetails() {
|
||||||
|
printDetails(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removePassenger(Passenger p) {
|
||||||
|
// Logger.getInstance().print(id, "Passenger " + p.getName() + " left " + name);
|
||||||
|
passengers.remove(p);
|
||||||
|
}
|
||||||
|
}
|
40
src/test/java/usherbrooke/ift630/AppTest.java
Normal file
40
src/test/java/usherbrooke/ift630/AppTest.java
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
package usherbrooke.ift630;
|
||||||
|
import usherbrooke.ift630.App;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit test for simple App.
|
||||||
|
*/
|
||||||
|
public class AppTest
|
||||||
|
extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create the test case
|
||||||
|
*
|
||||||
|
* @param testName name of the test case
|
||||||
|
*/
|
||||||
|
public AppTest( String testName )
|
||||||
|
{
|
||||||
|
super( testName );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the suite of tests being tested
|
||||||
|
*/
|
||||||
|
public static Test suite()
|
||||||
|
{
|
||||||
|
return new TestSuite( AppTest.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rigourous Test :-)
|
||||||
|
*/
|
||||||
|
public void testApp()
|
||||||
|
{
|
||||||
|
String args[] = null;
|
||||||
|
App.main(args);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue