@Override public void nextCycle() { super.nextCycle(); final Set<NodeAddress> toRemove = new HashSet<NodeAddress>(); // update member table, send alive messages for (final NodeAddress member : memberTable.keySet()) { final MemebrInfo ni = memberTable.get(member); if (Utils.getTime() - ni.lastMessageTime > lifeTimeThreshold) { toRemove.add(member); continue; } ni.aliveTime--; if (ni.aliveTime == 0) { ni.aliveTime = alivePeriod; sendMessage(new AliveMessage(getMessageTag(), network.getAddress(), member)); } } memberTable.keySet().removeAll(toRemove); removeNeighbors(toRemove); // gossip for (final NodeAddress neighbor : getNeighbors()) { final MemebrInfo ni = memberTable.get(neighbor); ni.gossipTime--; if (ni.gossipTime == 0) { ni.gossipTime = gossipPeriod; final List<NodeAddress> memberList = new ArrayList<NodeAddress>(memberTable.keySet()); memberList.remove(neighbor); Collections.shuffle(memberList, r); final List<NodeAddress> sublist = memberList.subList(0, Math.min(gossipSize, memberList.size())); sendMessage( new PartialMembershipViewMessage<Sizeable>( getMessageTag(), network.getAddress(), neighbor, new LinkedList<NodeAddress>(sublist))); } } // replace fallen neighbors from member view final Set<NodeAddress> neighbors = getNeighbors(); if (neighbors.size() < neighborSize && neighborSize < memberTable.size()) { final TreeMap<NodeAddress, MemebrInfo> addCandidates = new TreeMap<NodeAddress, MemebrInfo>(memberTable); addCandidates.keySet().removeAll(getNeighbors()); final Set<NodeAddress> minVal = Utils.findMinValueKeyGroup(addCandidates); for (final NodeAddress n : minVal) { if (neighbors.size() < neighborSize) { addNeighbor(n); network.send( new ConnectionRequestApprovedMessage<Sizeable>( getMessageTag(), network.getAddress(), n)); } } } }
private void chooseNeighborsFromMemberTable( final Collection<NodeAddress> possibleTargets, final int minLatencyNeighborSizeParam) { final Map<NodeAddress, Long /* latency */> latencyMap = new TreeMap<NodeAddress, Long>(); for (final NodeAddress target : possibleTargets) { latencyMap.put(target, network.getEstimatedLatency(target)); } final LinkedHashMap<NodeAddress, Long> sortedMap = Utils.sortByValue(latencyMap); int i = 0; final Set<NodeAddress> toRemove = new HashSet<NodeAddress>(); // find minLatencyNeighborSize neighbors with min latency for (final NodeAddress neighbor : sortedMap.keySet()) { toRemove.add(neighbor); if (!network.isUp(neighbor)) { continue; } final MemebrInfo mi = new MemebrInfo(); mi.aliveTime = alivePeriod; mi.gossipTime = gossipPeriod; memberTable.put(neighbor, mi); if (i < minLatencyNeighborSizeParam) { addNeighbor(neighbor); sendMessage( new ConnectionRequestApprovedMessage<Sizeable>( getMessageTag(), network.getAddress(), neighbor)); } i++; } latencyMap.keySet().removeAll(toRemove); // the rest of the neighbors are chosen randomly from the targets final ArrayList<NodeAddress> seedNodes = new ArrayList<NodeAddress>(latencyMap.keySet()); NodeAddress target = null; final List<NodeAddress> chosenNodes = new LinkedList<NodeAddress>(); Collections.shuffle(seedNodes, r); while (chosenNodes.size() < neighborSize - i && !seedNodes.isEmpty()) { target = seedNodes.get(seedNodes.size() - 1); if (network.isUp(target)) { chosenNodes.add(target); } else { memberTable.keySet().remove(target); } seedNodes.remove(target); } for (final NodeAddress neighbor : seedNodes) { addNeighbor(neighbor); network.send( new ConnectionRequestApprovedMessage<Sizeable>( getMessageTag(), network.getAddress(), neighbor)); } }
@Override public void handleMessage(final Message message) { if (memberTable.containsKey(message.sourceId)) { memberTable.get(message.sourceId).receivedBits += Utils.getSize(message); memberTable.get(message.sourceId).lastMessageTime = Utils.getTime(); } super.handleMessage(message); if (message instanceof PartialMembershipViewMessage) { final Set<NodeAddress> neighborsList = ((PartialMembershipViewMessage<?>) message).infoMap.keySet(); // add the neighbors received in the message for (final NodeAddress newNeighbor : neighborsList) { final MemebrInfo mi = new MemebrInfo(); mi.aliveTime = alivePeriod; mi.gossipTime = gossipPeriod; memberTable.put(newNeighbor, mi); } } else if (message instanceof SeedNodeMultipleTargetsReplyMessage) { handleSeedNodeMultipleTargetsReplyMessage((SeedNodeMultipleTargetsReplyMessage) message); } else if (message instanceof ConnectionRequestApprovedMessage) { handleConnectionRequestApprovedMessage((ConnectionRequestApprovedMessage<?>) message); } }