GOSSIP-53 CRDT types

This commit is contained in:
Edward Capriolo
2017-02-19 16:14:30 -05:00
parent 400cb40cba
commit b71be5e16a
9 changed files with 439 additions and 34 deletions

View File

@ -23,6 +23,7 @@ import com.codahale.metrics.MetricRegistry;
import org.apache.gossip.GossipMember;
import org.apache.gossip.LocalGossipMember;
import org.apache.gossip.RemoteGossipMember;
import org.apache.gossip.crdt.Crdt;
import org.apache.gossip.event.GossipState;
import org.apache.gossip.model.*;
import org.apache.gossip.udp.Trackable;
@ -111,15 +112,27 @@ public class GossipCore implements GossipCoreConstants {
}
}
public void addSharedData(SharedGossipDataMessage message){
SharedGossipDataMessage previous = sharedData.get(message.getKey());
if (previous == null){
sharedData.putIfAbsent(message.getKey(), message);
} else {
if (previous.getTimestamp() < message.getTimestamp()){
sharedData.replace(message.getKey(), previous, message);
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public void addSharedData(SharedGossipDataMessage message) {
SharedGossipDataMessage previous = sharedData.get(message.getKey());
if (previous == null) {
sharedData.putIfAbsent(message.getKey(), message);
} else {
if (message.getPayload() instanceof Crdt){
SharedGossipDataMessage m = sharedData.get(message.getKey());
SharedGossipDataMessage merged = new SharedGossipDataMessage();
merged.setExpireAt(message.getExpireAt());
merged.setKey(m.getKey());
merged.setNodeId(message.getNodeId());
merged.setTimestamp(message.getTimestamp());
merged.setPayload( ((Crdt) message.getPayload()).merge((Crdt)m.getPayload()));
sharedData.put(m.getKey(), merged);
} else {
if (previous.getTimestamp() < message.getTimestamp()) {
sharedData.replace(message.getKey(), previous, message);
}
}
}
}
public void addPerNodeData(GossipDataMessage message){
@ -345,4 +358,25 @@ public class GossipCore implements GossipCoreConstants {
"Dead " + gossipManager.getDeadMembers()+ "\n" +
"=======================");
}
@SuppressWarnings("rawtypes")
public Crdt merge(SharedGossipDataMessage message) {
for (;;){
SharedGossipDataMessage ret = sharedData.putIfAbsent(message.getKey(), message);
if (ret == null){
return (Crdt) message.getPayload();
}
SharedGossipDataMessage copy = new SharedGossipDataMessage();
copy.setExpireAt(message.getExpireAt());
copy.setKey(message.getKey());
copy.setNodeId(message.getNodeId());
@SuppressWarnings("unchecked")
Crdt merged = ((Crdt) ret.getPayload()).merge((Crdt) message.getPayload());
message.setPayload(merged);
boolean replaced = sharedData.replace(message.getKey(), ret, copy);
if (replaced){
return merged;
}
}
}
}

View File

@ -22,6 +22,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.gossip.GossipMember;
import org.apache.gossip.GossipSettings;
import org.apache.gossip.LocalGossipMember;
import org.apache.gossip.crdt.Crdt;
import org.apache.gossip.event.GossipListener;
import org.apache.gossip.event.GossipState;
import org.apache.gossip.manager.handlers.MessageInvoker;
@ -291,6 +292,31 @@ public abstract class GossipManager {
gossipCore.addSharedData(message);
}
@SuppressWarnings("rawtypes")
public Crdt findCrdt(String key){
SharedGossipDataMessage l = gossipCore.getSharedData().get(key);
if (l == null){
return null;
}
if (l.getExpireAt() < clock.currentTimeMillis()){
return null;
} else {
return (Crdt) l.getPayload();
}
}
@SuppressWarnings("rawtypes")
public Crdt merge(SharedGossipDataMessage message){
Objects.nonNull(message.getKey());
Objects.nonNull(message.getTimestamp());
Objects.nonNull(message.getPayload());
message.setNodeId(me.getId());
if (! (message.getPayload() instanceof Crdt)){
throw new IllegalArgumentException("Not a subclass of CRDT " + message.getPayload());
}
return gossipCore.merge(message);
}
public GossipDataMessage findPerNodeGossipData(String nodeId, String key){
ConcurrentHashMap<String, GossipDataMessage> j = gossipCore.getPerNodeData().get(nodeId);
if (j == null){