ReadMe, Explication stratégies et tests
This commit is contained in:
57
README.md
57
README.md
@@ -10,9 +10,60 @@
|
||||
|
||||
## Stratégies de diffusions :
|
||||
|
||||
### Diffusion Atomique :
|
||||
Nous avons ajouté dans l'interface ``AlgoDiffusion`` la fonction ``getValue()``, cette fonction permet de retourner une valeur du capteur gardé en mémoire par l'algorithme de diffusion. La valeur gardée en mémoire est gérée différemment en fonction de la stratégie de diffusion.
|
||||
On a donc aussi ajouté à l'interface ``Capteur`` la focntion ``getValueDiffusion()`` permettant de récupérer la valeur de l'algo de diffusion.
|
||||
|
||||
### Diffusion Sequencielle :
|
||||
### - Diffusion Atomique :
|
||||
|
||||
### Diffusion Epoque :
|
||||
La diffusion atomique permet que tous les afficheurs affichent toutes les valeurs du capteur, ils affichent donc les mêmes valeurs.
|
||||
Le capteur change de valeur toutes les 500 ms alors que les canaux prennent entre 2s et 3s pour passer à la valeur suivante, les afficheurs prennent donc du retard. Si les capteurs tournent 1h, les afficheurs auront jusqu'à 5h de retard et au mieux 3h de retard.
|
||||
|
||||
On doit donc enregistrer les valeurs du capteur dans une file d'attente ``Queue<Integer> values``. Alors ``getValue()`` de l'aglo de diffusion n'a qu'à faire un ``peek()`` sur cette file d'attente. À chaque appel de ``execute()`` on rajoute la valeur.
|
||||
Pour que les canaux soient synchronisés, on a une liste ``List<Future<?>> futures`` qui stocke les Future en cours de traitement (cette liste a donc au maxium comme taille le nombre de canaux).
|
||||
À chaque appel de ``execute()``, on retire de la liste les Future terminés, quand la liste est vide alors ils sont tous terminés, on retire l'élément à la file d'attente, et on relance des nouveaux Future en faisant un ``update()`` sur chaque canal.
|
||||
|
||||
### - Diffusion Sequencielle :
|
||||
|
||||
Ici, il faut simplement que les afficheurs aient des valeurs synchronisées et que les valeurs soient dans l'ordre chronologique. On n'a donc pas besoin d'afficher toutes les valeurs du capteur.
|
||||
|
||||
On a donc simplement besoin d'une valeur ``int value`` permettant de garder en mémoire une valeur du capteur commune pour tous les afficheurs. C'est cette valeur qui est retournée dans le ``getValue()``.
|
||||
On a encore une liste ``List<Future<?>> futures`` qui a le même fonctionnement que pour Atomique, à la différence qu'il remplace simplement ``value`` par la nouvelle valeur quand ``futures`` est vide.
|
||||
|
||||
|
||||
### - Diffusion Epoque :
|
||||
|
||||
Cette dernière stratégie est la plus simple, les afficheurs doivent juste afficher chacune des valeurs dans l'ordre chronologique. Il n'y a donc pas de synchronisation entre les afficheurs, et pas non plus besoin d'afficher toutes les valeurs.
|
||||
|
||||
Il nous reste donc plus que ``futures``, mais cette fois en tant que tableau de taille fixe ``Future<?>[] futures`` (nombre de canaux). On n'a pas besoin d'attendre que tous les Future soient finis pour passer à la suite, dès qu'un Future est fini, on relance directement un update() sur le canal associé.
|
||||
La fonction ``getValue()`` retourne donc directement la valeur courante du capteur sans rien sauvegarder au préalable.
|
||||
|
||||
## Tests :
|
||||
|
||||
|
||||
### - Tests :
|
||||
|
||||
L'exécution dans chaque test on environ la même forme :
|
||||
- on initialise les afficheurs, le Sceduler, le capteur, l'algo de diffusion, les canaux
|
||||
- on lance le tick avec le scheduler.
|
||||
- on laisse tourner pendant quelques secondes (5s pour la stratégie atomique, et 10s pour les 2 autres)
|
||||
- on attend les potentiels derniers Future (25s pour la stratégie atomique, et 3s pour les 2 autres)
|
||||
- affichage des résulat des afficheur pour debug
|
||||
|
||||
ps : Pour l'ago de diffusion atomique une constante ``TEST_TIME`` est au début du test pour modifier la durée totale du test (1/6 de run + 5/6 d'attente)
|
||||
|
||||
Dans l'afficheur, nous avons ajouté une liste ``ArrayList<Integer> vals`` permettant de sauvegarder les valeurs affichées, qui sera utilisée ensuite par l'oracle.
|
||||
|
||||
### - Oracle
|
||||
|
||||
Notre capteur envoie des valeurs de 1 en 1 à chaque ticket en commençant par 1
|
||||
|
||||
#### - Diffusion Atomique
|
||||
On a deux oracles :
|
||||
- Un qui vérifie que les éléments sont strictement croissants de 1 en 1 en commençant par 1
|
||||
- Et un second qui vérifie que tous les canaux ont les mêmes éléments entre eux.
|
||||
#### - Diffusion Sequencielle
|
||||
On a deux oracles :
|
||||
- Un qui vérifie que les éléments sont strictement croissants.
|
||||
- Et un second qui vérifie que tous les canaux ont les mêmes éléments entre eux.
|
||||
#### - Diffusion Epoque
|
||||
Ici on a qu'un seul oracle qui vérifie simplement que les valeurs sont strictement dans l'ordre croissant
|
||||
@@ -1,7 +1,7 @@
|
||||
package impl;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.Future;
|
||||
@@ -19,7 +19,7 @@ public class DiffusionAtomique implements AlgoDiffusion {
|
||||
public DiffusionAtomique(CapteurImpl c){
|
||||
this.capteur = c;
|
||||
this.futures = new ArrayList<Future<?>>();
|
||||
this.values = new LinkedList<>();
|
||||
this.values = new ArrayDeque<>();
|
||||
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ public class DiffusionAtomique implements AlgoDiffusion {
|
||||
}
|
||||
}
|
||||
|
||||
// si futures est empty, alors tous les futures canaux précédents sont finis
|
||||
// et on peut relancer des futures sans attendre le prochain ticket
|
||||
// si futures est empty, alors tous les Future des canaux précédents sont finis
|
||||
// et on peut relancer des futures sans attendre le prochain ticket, pour ne pas accumuler encore plus de retard
|
||||
if(this.futures.isEmpty()){
|
||||
if(!this.values.isEmpty()){ //le capteur ne répond pas (car stopé ici)
|
||||
for (ObserverDeCapteurAsync canal : capteur.observers) {
|
||||
|
||||
@@ -26,7 +26,11 @@ public class DiffusionSequencielle implements AlgoDiffusion {
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
if(this.futures.isEmpty()){
|
||||
if(!this.futures.isEmpty()){
|
||||
futures.removeIf(Future::isDone);
|
||||
}
|
||||
|
||||
if(this.futures.isEmpty()){ //pas de else pour ne pas perdre 500ms à ne rien faire
|
||||
this.value = capteur.getValue();
|
||||
System.out.println("execute");
|
||||
for (ObserverDeCapteurAsync canal : capteur.observers) {
|
||||
@@ -34,9 +38,5 @@ public class DiffusionSequencielle implements AlgoDiffusion {
|
||||
this.futures.add(f);
|
||||
}
|
||||
}
|
||||
else{
|
||||
futures.removeIf(Future::isDone);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
|
||||
import impl.Afficheur;
|
||||
import impl.Canal;
|
||||
import impl.CapteurImpl;
|
||||
@@ -21,10 +19,21 @@ import impl.Scheduler;
|
||||
public class TestAlgoDiffusionAtom {
|
||||
|
||||
static int NB_CANAUX = 3;
|
||||
static int TEST_TIME = 30; // TEST_TIME/6 + TEST_TIME-TEST_TIME/6
|
||||
static int TEST_TIME = 30; // TEST_TIME/6 + 5*TEST_TIME/6
|
||||
public static List<Integer>[] rAtom;
|
||||
|
||||
|
||||
private static void display(List<Integer>[] res){
|
||||
for(int i = 0; i< NB_CANAUX; i++){
|
||||
System.out.println("canal " + i + ":");
|
||||
for(int j = 0; j< res[i].size(); j++){
|
||||
System.out.print(res[i].get(j));
|
||||
if(j<res[i].size()-1) System.out.print(", ");
|
||||
}
|
||||
System.out.println(" ");
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public static void testAtom() throws InterruptedException{
|
||||
|
||||
@@ -39,7 +48,6 @@ public class TestAlgoDiffusionAtom {
|
||||
CapteurImpl c = new CapteurImpl();
|
||||
|
||||
DiffusionAtomique algo = new DiffusionAtomique(c);
|
||||
|
||||
c.setAlgoDiffusion(algo);
|
||||
|
||||
for(int i = 0; i<NB_CANAUX; i++){
|
||||
@@ -62,7 +70,7 @@ public class TestAlgoDiffusionAtom {
|
||||
c.stop(); //arrête la mise à jour du capteur (mais stop pas le tick)
|
||||
System.out.println("waitting for lasts display...");
|
||||
|
||||
for(int i = TEST_TIME-TEST_TIME/6; i>0; i--){
|
||||
for(int i = 5*TEST_TIME/6; i>0; i--){
|
||||
System.out.println("restant " + i + "s");
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
@@ -70,35 +78,50 @@ public class TestAlgoDiffusionAtom {
|
||||
future.cancel(false);
|
||||
|
||||
clock.shutdown();
|
||||
//Thread.sleep(1500);
|
||||
|
||||
for(int i = 0; i<NB_CANAUX; i++){
|
||||
r[i] = a[i].vals;
|
||||
}
|
||||
rAtom = r;
|
||||
|
||||
display(rAtom);
|
||||
}
|
||||
|
||||
|
||||
// ORACLE
|
||||
|
||||
@Test
|
||||
void testHaveAllElement(){
|
||||
boolean r = true;
|
||||
|
||||
for(int i = 0; i< NB_CANAUX && r; i++){
|
||||
int valTest = 1;
|
||||
for(int j = 0; j< rAtom[i].size() && r; j++){
|
||||
r = r && rAtom[i].get(j)==valTest;
|
||||
valTest++;
|
||||
}
|
||||
}
|
||||
assertTrue(r);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testAtomOracle(){
|
||||
void sameElements(){
|
||||
boolean r = true;
|
||||
|
||||
for(int i = 0; i< NB_CANAUX-1 && r; i++){
|
||||
r = rAtom[i].size()==rAtom[i+1].size();
|
||||
}
|
||||
if(!r) System.out.println("pas de la même taille :");
|
||||
|
||||
for(int i = 0; i< NB_CANAUX && r; i++){
|
||||
|
||||
int valTest = 1;
|
||||
System.out.println("canal " + i + ":");
|
||||
for(int j = 0; j< rAtom[i].size() && r; j++){
|
||||
System.out.print(rAtom[i].get(j));
|
||||
if(j<rAtom[i].size()-1) System.out.print(", ");
|
||||
r = r && rAtom[i].get(j)==valTest;
|
||||
valTest++;
|
||||
if(!r){
|
||||
System.err.println("Pas de la même taille !");
|
||||
}
|
||||
else{
|
||||
for(int j = 0; j< rAtom[0].size() && r; j++){
|
||||
int temp = rAtom[0].get(j);
|
||||
for(int i = 1; i< NB_CANAUX && r; i++){
|
||||
r = r && rAtom[i].get(j)==temp;
|
||||
}
|
||||
}
|
||||
System.out.println(" ");
|
||||
}
|
||||
assertTrue(r);
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
|
||||
import impl.Afficheur;
|
||||
import impl.Canal;
|
||||
import impl.CapteurImpl;
|
||||
@@ -24,6 +22,18 @@ public class TestAlgoDiffusionEpoq {
|
||||
public static List<Integer>[] rEpoq;
|
||||
|
||||
|
||||
|
||||
private static void display(List<Integer>[] res){
|
||||
for(int i = 0; i< NB_CANAUX; i++){
|
||||
System.out.println("canal " + i + ":");
|
||||
for(int j = 0; j< res[i].size(); j++){
|
||||
System.out.print(res[i].get(j));
|
||||
if(j<res[i].size()-1) System.out.print(", ");
|
||||
}
|
||||
System.out.println(" ");
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public static void testAtom() throws InterruptedException{
|
||||
|
||||
@@ -47,10 +57,6 @@ public class TestAlgoDiffusionEpoq {
|
||||
|
||||
DiffusionEpoque algo = new DiffusionEpoque(c);
|
||||
c.setAlgoDiffusion(algo);
|
||||
|
||||
|
||||
|
||||
//algo.configure();
|
||||
|
||||
ScheduledExecutorService clock = scheduler.getScheculer();
|
||||
ScheduledFuture<?> future = clock.scheduleAtFixedRate(() -> c.tick(), 0, 500, TimeUnit.MILLISECONDS);
|
||||
@@ -62,31 +68,26 @@ public class TestAlgoDiffusionEpoq {
|
||||
Thread.sleep(3100); //3000ms max + 100ms de marge
|
||||
|
||||
clock.shutdown();
|
||||
//Thread.sleep(1500);
|
||||
|
||||
for(int i = 0; i<NB_CANAUX; i++){
|
||||
r[i] = a[i].vals;
|
||||
}
|
||||
rEpoq = r;
|
||||
|
||||
display(rEpoq);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testAtomOracle(){
|
||||
void testGoodOrder(){
|
||||
boolean r = true;
|
||||
|
||||
|
||||
for(int i = 0; i< NB_CANAUX && r; i++){
|
||||
|
||||
int valTest = 0;
|
||||
System.out.println("canal " + i + ":");
|
||||
int test = 0;
|
||||
for(int j = 0; j< rEpoq[i].size() && r; j++){
|
||||
System.out.print(rEpoq[i].get(j));
|
||||
if(j<rEpoq[i].size()-1) System.out.print(", ");
|
||||
r = r && rEpoq[i].get(j)>valTest;
|
||||
valTest=rEpoq[i].get(j);
|
||||
r = r && rEpoq[i].get(j)>test;
|
||||
test=rEpoq[i].get(j);
|
||||
}
|
||||
System.out.println(" ");
|
||||
}
|
||||
assertTrue(r);
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
|
||||
import impl.Afficheur;
|
||||
import impl.Canal;
|
||||
import impl.CapteurImpl;
|
||||
@@ -24,6 +22,18 @@ public class TestAlgoDiffusionSeq {
|
||||
public static List<Integer>[] rSeq;
|
||||
|
||||
|
||||
|
||||
private static void display(List<Integer>[] res){
|
||||
for(int i = 0; i< NB_CANAUX; i++){
|
||||
System.out.println("canal " + i + ":");
|
||||
for(int j = 0; j< res[i].size(); j++){
|
||||
System.out.print(res[i].get(j));
|
||||
if(j<res[i].size()-1) System.out.print(", ");
|
||||
}
|
||||
System.out.println(" ");
|
||||
}
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
public static void testAtom() throws InterruptedException{
|
||||
|
||||
@@ -58,45 +68,47 @@ public class TestAlgoDiffusionSeq {
|
||||
Thread.sleep(3100); //3000ms max + 100ms de marge
|
||||
|
||||
clock.shutdown();
|
||||
//Thread.sleep(1500);
|
||||
|
||||
for(int i = 0; i<NB_CANAUX; i++){
|
||||
r[i] = a[i].vals;
|
||||
}
|
||||
rSeq = r;
|
||||
|
||||
display(rSeq);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void testAtomOracle(){
|
||||
void testGoodOrder(){
|
||||
boolean r = true;
|
||||
|
||||
for(int i = 0; i< NB_CANAUX && r; i++){
|
||||
int test = 0;
|
||||
for(int j = 0; j< rSeq[i].size() && r; j++){
|
||||
r = r && rSeq[i].get(j) > test;
|
||||
test = rSeq[i].get(j);
|
||||
}
|
||||
}
|
||||
assertTrue(r);
|
||||
}
|
||||
|
||||
@Test
|
||||
void sameElements(){
|
||||
boolean r = true;
|
||||
|
||||
for(int i = 0; i< NB_CANAUX-1 && r; i++){
|
||||
r = rSeq[i].size()==rSeq[i+1].size();
|
||||
}
|
||||
if(!r) System.out.println("pas de la même taille :");
|
||||
|
||||
int test = 0;
|
||||
for(int j = 0; j< rSeq[0].size() && r; j++){
|
||||
for(int i = 0; i< NB_CANAUX && r; i++){
|
||||
if(i==0){
|
||||
r = r && rSeq[i].get(j)>test;
|
||||
test = rSeq[i].get(j);
|
||||
}
|
||||
else{
|
||||
r = r && rSeq[i].get(j) == test;
|
||||
}
|
||||
}
|
||||
if(!r){
|
||||
System.err.println("Pas de la même taille !");
|
||||
}
|
||||
|
||||
//display
|
||||
for(int i = 0; i< NB_CANAUX && r; i++){
|
||||
System.out.println("canal " + i + ":");
|
||||
for(int j = 0; j< rSeq[i].size() && r; j++){
|
||||
System.out.print(rSeq[i].get(j));
|
||||
if(j<rSeq[i].size()-1) System.out.print(", ");
|
||||
else{
|
||||
for(int j = 0; j< rSeq[0].size() && r; j++){
|
||||
int temp = rSeq[0].get(j);
|
||||
for(int i = 1; i< NB_CANAUX && r; i++){
|
||||
r = r && rSeq[i].get(j)==temp;
|
||||
}
|
||||
}
|
||||
System.out.println(" ");
|
||||
}
|
||||
assertTrue(r);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user