/** * If my peer is responsible, I'll issue a put if absent to make sure all replicas are stored. * * @param locationKey The location key * @param domainKey The domain key * @param dataMapConverted The data to store * @return The future of the put */ protected FutureDone<?> send(final Number160 locationKey) { int replicationFactor = replication.replicationFactor() - 1; List<PeerAddress> closePeers = new ArrayList<PeerAddress>(); SortedSet<PeerStatistic> sortedSet = peer.peerBean().peerMap().closePeers(locationKey, replicationFactor); int count = 0; List<FutureDone<?>> retVal = new ArrayList<FutureDone<?>>(replicationFactor); for (PeerStatistic peerStatistic : sortedSet) { if (replication.rejectReplication(peerStatistic.peerAddress())) { continue; } count++; closePeers.add(peerStatistic.peerAddress()); // this must be inside the loop as we need to retain the data for every peer Number640 min = new Number640(locationKey, Number160.ZERO, Number160.ZERO, Number160.ZERO); Number640 max = new Number640(locationKey, Number160.MAX_VALUE, Number160.MAX_VALUE, Number160.MAX_VALUE); final NavigableMap<Number640, Data> dataMap = peer.storageLayer().get(min, max, -1, true); retVal.add(replicationSender.sendDirect(peerStatistic.peerAddress(), locationKey, dataMap)); if (count == replicationFactor) { break; } } LOG.debug( "[storage refresh] I ({}) restore {} to {}", peer.peerAddress(), locationKey, closePeers); return FutureDone.whenAll(retVal); }
@Override public FutureDone<?> meResponsible(final Number160 locationKey, PeerAddress newPeer) { LOG.debug("I ({}) sync {} to {}", peer.peerAddress(), locationKey, newPeer); Number640 min = new Number640(locationKey, Number160.ZERO, Number160.ZERO, Number160.ZERO); Number640 max = new Number640(locationKey, Number160.MAX_VALUE, Number160.MAX_VALUE, Number160.MAX_VALUE); final NavigableMap<Number640, Data> dataMap = peer.storageLayer().get(min, max, -1, true); return replicationSender.sendDirect(newPeer, locationKey, dataMap); }
@Override public FutureDone<?> otherResponsible(final Number160 locationKey, final PeerAddress other) { LOG.debug( "Other peer {} is responsible for {}. I'm {}", other, locationKey, peer.peerAddress()); Number640 min = new Number640(locationKey, Number160.ZERO, Number160.ZERO, Number160.ZERO); Number640 max = new Number640(locationKey, Number160.MAX_VALUE, Number160.MAX_VALUE, Number160.MAX_VALUE); final NavigableMap<Number640, Data> dataMap = peer.storageLayer().get(min, max, -1, true); LOG.debug("transfer from {} to {} for key {}", peer.peerAddress(), other, locationKey); return replicationSender.sendDirect(other, locationKey, dataMap); }
@Override public void run() { try { // we get called every x seconds for content we are responsible for. So // we need to make sure that there are enough copies. The easy way is to // publish it again... The good way is to do a diff Collection<Number160> locationKeys = peer.storageLayer().findContentForResponsiblePeerID(peer.peerID()); for (Number160 locationKey : locationKeys) { synchronizeData(locationKey); } // recalculate replication factor int replicationFactor = IndirectReplication.this.replicationFactor.replicationFactor(); replication.replicationFactor(replicationFactor); } catch (Throwable t) { t.printStackTrace(); } }