Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
75 changes: 75 additions & 0 deletions src/main/java/dev/oxoo2a/sim4da/Actor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package dev.oxoo2a.sim4da;

import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class Actor {
private boolean active;
private double p;
private String lastAction;
private int senderId;
private int receiverId;
private int[] vectorClock;

public Actor(int numActors) {
active = true;
p = 1.0;
vectorClock = new int[numActors];
}

//converging to 0.
public void updateP(int time) {
p -= 0.1;
if (p < 0.0) {
p = 0.0; // Ensure p does not go below 0
}
}

public boolean isActive(int actorIndex) {
if (active) {
System.out.println("[Actor " + actorIndex + " is active. ]");
} else {
System.out.println("[Actor " + actorIndex + " is inactive. Last action: " + lastAction + "]");
}
return active;
}

public void receiveMessage(int senderId, int receiverId, int[] senderVectorClock) {
active = true;
this.senderId = senderId;
this.receiverId = receiverId;
lastAction = "Received from Actor " + senderId;

for (int i = 0; i < vectorClock.length; i++) {
vectorClock[i] = Math.max(vectorClock[i], senderVectorClock[i]);
}

vectorClock[receiverId]++;

System.out.println("Actor " + receiverId + " received a message from Actor " + senderId +
" with Vector Clock: " + Arrays.toString(vectorClock));
}


public boolean sendMessage(List<Actor> actors, int senderIndex) {
if (active && Math.random() < p) {
active = false;
int receiverIndex = getRandoReceiverWithoutSender(actors, senderIndex);
int senderId = actors.indexOf(this);
actors.get(receiverIndex).receiveMessage(senderId, receiverIndex, vectorClock.clone());
lastAction = "Sent to Actor " + receiverIndex;
return true;
}
return false;
}

//to avoid an actor sending messages to themselves.
private int getRandoReceiverWithoutSender(List<Actor> actors, int senderIndex) {
int receiverIndex;
do {
receiverIndex = new Random().nextInt(actors.size());
} while (receiverIndex == senderIndex);
return receiverIndex;
}
}
81 changes: 81 additions & 0 deletions src/main/java/dev/oxoo2a/sim4da/DSSimulation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package dev.oxoo2a.sim4da;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class DSSimulation {
private static final int NUM_ACTORS = 4;
private static final int MAX_STEPS = 100;

public static void main(String[] args) {
List<Actor> actors = new ArrayList<>();
for (int i = 0; i < NUM_ACTORS; i++) {
actors.add(new Actor(NUM_ACTORS));
}

for (int i = 0; i < actors.size(); i++) {
actors.get(i).isActive(i); // Prints initial status of each actor with index
}

int time = 1;
int steps = 0;

DoubleCountingActor doubleCountingActor = new DoubleCountingActor(NUM_ACTORS);
LaggingStateVector vectorClockActor = new LaggingStateVector(NUM_ACTORS);

while (steps < MAX_STEPS) {
System.out.println("------------------------------");
System.out.println("Step " + steps + " starting...");
System.out.println("------------------------------");

List<Actor> activeActors = new ArrayList<>();
for (int i = 0; i < actors.size(); i++) {
Actor actor = actors.get(i);
actor.updateP(time);
if (actor.isActive(i)) {
activeActors.add(actor);
}
}

boolean anyMessagesSent = false;
for (Actor actor : activeActors) {
int senderIndex = actors.indexOf(actor);
if (actor.sendMessage(actors, senderIndex)) {
anyMessagesSent = true;
doubleCountingActor.receiveMessage(senderIndex);
}
}

doubleCountingActor.actorTerminated(activeActors.size());

int[] senderVectorClock = new int[NUM_ACTORS];
vectorClockActor.receiveMessage(activeActors, steps % NUM_ACTORS, senderVectorClock);

System.out.println("Step " + steps + ": Active actors: " + activeActors.size());
System.out.println("Event Clock: " + Arrays.toString(vectorClockActor.getVectorClock()));

if (!anyMessagesSent) {
break;
}

steps++;
time++;
}

boolean doubleCountingTerminated = doubleCountingActor.hasTerminated();
boolean vectorClockTerminated = vectorClockActor.hasTerminated();

if (doubleCountingTerminated) {
System.out.println("Double Counting Termination: All actors have terminated!");
} else {
System.out.println("Double Counting Termination: Not all actors have terminated yet.");
}

if (vectorClockTerminated) {
System.out.println("Lagging State Vector Termination: All actors have terminated!");
} else {
System.out.println("Lagging State Vector Termination: Not all actors have terminated yet.");
}
}
}
45 changes: 45 additions & 0 deletions src/main/java/dev/oxoo2a/sim4da/DoubleCountingActor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package dev.oxoo2a.sim4da;

import java.util.HashSet;
import java.util.Set;

public class DoubleCountingActor {
private Set<Integer> receivedMessages;
private Set<Integer> terminatedActors;
private int count;
private int numActors;

public DoubleCountingActor(int numActors) {
this.numActors = numActors;
receivedMessages = new HashSet<>();
terminatedActors = new HashSet<>();
count = 0;
}

public void receiveMessage(int senderId) {
receivedMessages.add(senderId);
//System.out.println("Actor " + senderId + " received a message.");

// Check termination based on the received messages
if (receivedMessages.size() == numActors) {
actorTerminated(1);
}
}

public void actorTerminated(int numTerminatedActors) {
for (int i = 0; i < numTerminatedActors; i++) {
terminatedActors.add(count);
count++;
}

if (terminatedActors.size() == numActors) {
System.out.println("All actors have terminated.");
} //else {
// System.out.println("Actor " + numTerminatedActors + " inactive.");
//}
}

public boolean hasTerminated() {
return terminatedActors.size() == count;
}
}
45 changes: 45 additions & 0 deletions src/main/java/dev/oxoo2a/sim4da/LaggingStateVector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package dev.oxoo2a.sim4da;

import java.util.Arrays;
import java.util.List;

public class LaggingStateVector {
private int[] vectorClock;
private int numActors;

public LaggingStateVector(int numActors) {
this.numActors = numActors;
vectorClock = new int[numActors];
}

public void receiveMessage(List<Actor> actors, int senderId, int[] senderVectorClock) {
for (int i = 0; i < numActors; i++) {
vectorClock[i] = Math.max(vectorClock[i], senderVectorClock[i]);
}
vectorClock[senderId]++;

// Check termination based on the lagging state vector
for (int i = 0; i < numActors; i++) {
if (i != senderId && vectorClock[i] == vectorClock[senderId] - 1) {
vectorClock[i]++;
}
}
}

public boolean hasTerminated() {
for (int i = 0; i < numActors; i++) {
if (vectorClock[i] == 0)
return false;
}
return true;
}

public int[] getVectorClock() {
return vectorClock.clone();
}

@Override
public String toString() {
return Arrays.toString(vectorClock);
}
}