package org.jgroups.util; import org.jgroups.Address; import java.util.*; import java.util.stream.Collectors; /** * Contains responses from all members. Marks faulty members. * A RspList is a response list used in peer-to-peer protocols. This class is unsynchronized */ public class RspList<T> extends HashMap<Address,Rsp<T>> implements Iterable<Rsp<T>> { private static final long serialVersionUID=6085009056724212815L; public RspList() { } public RspList(int size) { super(size); } public RspList(Map<Address,Rsp<T>> map) { putAll(map); } /** * Returns the value associated with address key * @param key * @return Object value */ public T getValue(Object key) { Rsp<T> rsp=get(key); return rsp != null? rsp.getValue() : null; } public RspList<T> addRsp(Address sender, T retval) { Rsp<T> rsp=get(sender); if(rsp != null) { rsp.setValue(retval); return this; } put(sender, new Rsp<>(retval)); return this; } public boolean isReceived(Address sender) { Rsp<T> rsp=get(sender); return rsp != null && rsp.wasReceived(); } public int numSuspectedMembers() { return (int)values().stream().filter(Rsp::wasSuspected).count(); } public int numReceived() { return (int)values().stream().filter(Rsp::wasReceived).count(); } /** Returns the first value in the response set. This is random, but we try to return a non-null value first */ public T getFirst() { Optional<Rsp<T>> retval=values().stream().filter(rsp -> rsp.getValue() != null).findFirst(); return retval.isPresent()? retval.get().getValue() : null; } /** * Returns the results from non-suspected members that are not null. */ public List<T> getResults() { return values().stream().filter(rsp -> rsp.wasReceived() && rsp.getValue() != null) .collect(() -> new ArrayList<>(size()), (list,rsp) -> list.add(rsp.getValue()), (l,r) -> {}); } public List<Address> getSuspectedMembers() { return entrySet().stream().filter(entry -> entry.getValue() != null && entry.getValue().wasSuspected()) .map(Entry::getKey).collect(Collectors.toList()); } public boolean isSuspected(Address sender) { Rsp<T> rsp=get(sender); return rsp != null && rsp.wasSuspected(); } public String toString() { return entrySet().stream() .collect(StringBuilder::new, (sb,entry) -> sb.append("[").append(entry.getKey()).append(": ").append(entry.getValue()).append("]\n"), (l,r)->{}).toString(); } boolean contains(Address sender) { return containsKey(sender); } public Iterator<Rsp<T>> iterator() { return values().iterator(); } }