m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java')
-rw-r--r--src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java82
1 files changed, 59 insertions, 23 deletions
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java
index 70d57d9..0525f41 100644
--- a/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java
+++ b/src/main/java/pl/edu/mimuw/cloudatlas/agent/modules/GossipGirlState.java
@@ -13,9 +13,13 @@ import java.util.Set;
import pl.edu.mimuw.cloudatlas.agent.messages.AttributesMessage;
import pl.edu.mimuw.cloudatlas.agent.messages.HejkaMessage;
import pl.edu.mimuw.cloudatlas.agent.messages.NoCoTamMessage;
+import pl.edu.mimuw.cloudatlas.agent.messages.QueryMessage;
import pl.edu.mimuw.cloudatlas.model.Attribute;
+import pl.edu.mimuw.cloudatlas.model.AttributesMap;
import pl.edu.mimuw.cloudatlas.model.PathName;
import pl.edu.mimuw.cloudatlas.model.ValueContact;
+import pl.edu.mimuw.cloudatlas.model.ValueDuration;
+import pl.edu.mimuw.cloudatlas.model.ValueInt;
import pl.edu.mimuw.cloudatlas.model.ValueQuery;
import pl.edu.mimuw.cloudatlas.model.ValueTime;
import pl.edu.mimuw.cloudatlas.model.ValueUtils;
@@ -48,18 +52,22 @@ public class GossipGirlState {
public ValueTime hejkaSendTimestamp;
public ValueTime hejkaReceiveTimestamp;
public ValueTime noCoTamSendTimestamp;
- public ValueTime noCoTamSendReceiveTimestamp;
+ public ValueTime noCoTamReceiveTimestamp;
+ public ValueDuration offset;
private Map<PathName, ValueTime> theirZoneTimestamps;
private Map<Attribute, ValueTime> theirQueryTimestamps;
private List<PathName> zonesToSend;
private List<Attribute> queriesToSend;
private Set<PathName> waitingForZones;
private Set<Attribute> waitingForQueries;
+ private boolean initiating;
public GossipGirlState(long gossipId, PathName ourPath, ValueContact theirContact, boolean initiating) {
this.gossipId = gossipId;
this.ourPath = ourPath;
this.theirContact = theirContact;
+ this.initiating = initiating;
+ System.out.println("INFO: initializing Gossip state, their contact " + theirContact.toString());
if (initiating) {
state = State.WAIT_FOR_STATE_INITIALIZER;
} else {
@@ -129,16 +137,23 @@ public class GossipGirlState {
}
public void handleNoCoTam(NoCoTamMessage message) {
+ System.out.println("DEBUG: in GossipGirlState handleNoCoTam");
switch (state) {
case WAIT_FOR_NO_CO_TAM:
+ System.out.println("DEBUG: lets do this");
theirGossipId = message.getSenderGossipId();
theirZoneTimestamps = message.getZoneTimestamps();
theirQueryTimestamps = message.getQueryTimestamps();
hejkaSendTimestamp = message.getHejkaSendTimestamp();
hejkaReceiveTimestamp = message.getHejkaReceiveTimestamp();
+ noCoTamSendTimestamp = message.getSentTimestamp();
+ noCoTamReceiveTimestamp = message.getReceivedTimestamp();
+ computeOffset();
+ System.out.println("DEBUG: set basic stuff");
setZonesToSend();
setQueriesToSend();
setWaitingFor();
+ System.out.println("DEBUG: set big stuff");
state = State.SEND_INFO;
break;
default:
@@ -147,6 +162,23 @@ public class GossipGirlState {
}
}
+ public void computeOffset() {
+ ValueDuration rtd = (ValueDuration) (noCoTamReceiveTimestamp.subtract(hejkaSendTimestamp))
+ .subtract(noCoTamSendTimestamp.subtract(hejkaReceiveTimestamp));
+ offset = (ValueDuration) (noCoTamSendTimestamp.addValue(rtd.divide(new ValueInt(2l))))
+ .subtract(noCoTamReceiveTimestamp);
+ System.out.println("INFO: GossipGirlState calculated offset: " + offset.toString());
+ }
+
+ public AttributesMap modifyAttributes(AttributesMap attributes) {
+ ValueDuration delta = offset;
+ if (!initiating) {
+ delta = delta.negate();
+ }
+ attributes.addOrChange("timestamp", attributes.getOrNull("timestamp").subtract(delta));
+ return attributes;
+ }
+
private void setWaitingFor() {
setWaitingForZones();
setWaitingForQueries();
@@ -168,6 +200,8 @@ public class GossipGirlState {
public Map<PathName, ValueTime> getZoneTimestampsToSend() {
Map<PathName, ValueTime> timestamps = new HashMap();
+ System.out.println("Getting zone timestamps to send to " + theirContact.getName().toString());
+ System.out.println("hierarchy is " + hierarchy.toString());
collectZoneTimestamps(timestamps, hierarchy, theirContact.getName());
return timestamps;
}
@@ -183,12 +217,14 @@ public class GossipGirlState {
public void setZonesToSend() {
zonesToSend = new LinkedList();
+ System.out.println("DEBUG: timestamps to send: " + getZoneTimestampsToSend().toString());
for (Entry<PathName, ValueTime> timestampedPath : getZoneTimestampsToSend().entrySet()) {
ValueTime theirTimestamp = theirZoneTimestamps.get(timestampedPath.getKey());
if (theirTimestamp == null || ValueUtils.valueLower(theirTimestamp, timestampedPath.getValue())) {
zonesToSend.add(timestampedPath.getKey());
}
}
+ System.out.println("DEBUG: zones to send: " + zonesToSend.toString());
}
public void setQueriesToSend() {
@@ -199,6 +235,7 @@ public class GossipGirlState {
queriesToSend.add(timestampedQuery.getKey());
}
}
+ System.out.println("DEBUG: Queries to send: " + queriesToSend.toString());
}
public List<ZMI> getZMIsToSend() {
@@ -227,6 +264,7 @@ public class GossipGirlState {
}
public void collectZoneTimestamps(Map<PathName, ValueTime> timestamps, ZMI currentZMI, PathName recipientPath) {
+ System.out.println("collecting timestamps, on " + currentZMI.getPathName().toString());
for (ZMI zmi : currentZMI.getSons()) {
if (interestedIn(recipientPath, zmi.getPathName())) {
ValueTime timestamp = (ValueTime) zmi.getAttributes().getOrNull("timestamp");
@@ -242,26 +280,7 @@ public class GossipGirlState {
}
public boolean interestedIn(PathName recipientPath, PathName zmiPath) {
- return isPrefix(zmiPath.levelUp(), recipientPath) && !isPrefix(zmiPath, recipientPath);
- }
-
- public boolean isPrefix(PathName prefix, PathName path) {
- List<String> prefixComponents = prefix.getComponents();
- List<String> pathComponents = path.getComponents();
-
- if (prefixComponents.size() > pathComponents.size()) {
- return false;
- }
-
- Iterator<String> prefixIterator = prefixComponents.iterator();
- Iterator<String> pathIterator = pathComponents.iterator();
-
- while (prefixIterator.hasNext()) {
- if (!prefixIterator.next().equals(pathIterator.next())) {
- return false;
- }
- }
- return true;
+ return ValueUtils.isPrefix(zmiPath.levelUp(), recipientPath) && !ValueUtils.isPrefix(zmiPath, recipientPath);
}
public void sentInfo() {
@@ -294,6 +313,7 @@ public class GossipGirlState {
setZonesToSend();
setQueriesToSend();
setWaitingFor();
+ offset = message.getOffset();
state = State.SEND_INFO;
if (!waitingForZones.remove(message.getPath())) {
@@ -310,10 +330,26 @@ public class GossipGirlState {
}
}
- public void gotQuery(Attribute name) {
+ public void gotQuery(QueryMessage message) {
switch (state) {
+ case WAIT_FOR_FIRST_INFO:
+ // TODO: use offset to setup GTP
+ offset = message.getOffset();
+ setZonesToSend();
+ setQueriesToSend();
+ setWaitingFor();
+ state = State.SEND_INFO;
+
+ if (!waitingForQueries.remove(message.getName())) {
+ System.out.println("DEBUG: got query we weren't expecting");
+ }
+ if (waitingForZones.isEmpty() && waitingForQueries.isEmpty()) {
+ System.out.println("INFO: done waiting for info");
+ state = state.SEND_INFO_AND_FINISH;
+ }
+ break;
case WAIT_FOR_INFO:
- if (!waitingForQueries.remove(name)) {
+ if (!waitingForQueries.remove(message.getName())) {
System.out.println("DEBUG: got query we weren't expecting");
}
if (waitingForZones.isEmpty() && waitingForQueries.isEmpty()) {