package lbms.plugins.mldht.kad.tasks; import lbms.plugins.mldht.kad.DHTConstants; import lbms.plugins.mldht.kad.GenericStorage.StorageItem; import lbms.plugins.mldht.kad.KBucketEntry; import lbms.plugins.mldht.kad.Node; import lbms.plugins.mldht.kad.RPCCall; import lbms.plugins.mldht.kad.RPCServer; import lbms.plugins.mldht.kad.messages.MessageBase; import lbms.plugins.mldht.kad.messages.PutRequest; import java.util.Map; import java.util.NavigableMap; import java.util.TreeMap; public class PutTask extends TargetedTask { NavigableMap<KBucketEntry, byte[]> todo; StorageItem toPut; public PutTask(RPCServer rpc, Node node, Map<KBucketEntry, byte[]> candidatesAndTokens, StorageItem it) { super(it.fingerprint(), rpc, node); toPut = it; todo = new TreeMap<>(new KBucketEntry.DistanceOrder(targetKey)); todo.putAll(candidatesAndTokens); } @Override void update() { for(;;) { if(getRecvResponses() >= DHTConstants.MAX_ENTRIES_PER_BUCKET) return; RequestPermit p = checkFreeSlot(); // we don't care about stalls here; if(p != RequestPermit.FREE_SLOT) return; Map.Entry<KBucketEntry, byte[]> me = todo.firstEntry(); if(me == null) return; KBucketEntry e = me.getKey(); PutRequest put = new PutRequest(); put.populateFromStorage(toPut); put.setDestination(e.getAddress()); put.setToken(me.getValue()); if(!rpcCall(put,e.getID(),c -> { c.builtFromEntry(e); todo.entrySet().remove(me); })) { break; } } } @Override void callFinished(RPCCall c, MessageBase rsp) { // TODO Auto-generated method stub } @Override void callTimeout(RPCCall c) { // TODO Auto-generated method stub } @Override public int getTodoCount() { return todo.size(); } @Override protected boolean isDone() { if(getRecvResponses() >= DHTConstants.MAX_ENTRIES_PER_BUCKET) return true; if(todo.isEmpty() && getNumOutstandingRequests() == 0) return true; return false; } }