package com.limegroup.gnutella.messagehandlers; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.limewire.collection.IntSet; import org.limewire.inspection.Inspectable; import org.limewire.io.GUID; import org.limewire.security.SecurityToken; import com.limegroup.gnutella.Response; import com.limegroup.gnutella.URN; /** * A session of OOB result exchange between the local host and a remote host. */ class OOBSession implements Inspectable { // inspection-related fields private final List<Long> responseTimestamps = new ArrayList<Long>(10); private final List<Integer> responseCounts = new ArrayList<Integer>(10); private final List<Integer> addedResponses = new ArrayList<Integer>(10); private final long start; // end inspection-related fields private final SecurityToken token; private final IntSet urnHashCodes; private IntSet responseHashCodes; private final int requestedResponseCount; private final GUID guid; OOBSession(SecurityToken token, int requestedResponseCount, GUID guid) { this.token = token; this.requestedResponseCount = requestedResponseCount; this.urnHashCodes = new IntSet(requestedResponseCount); this.guid = guid; start = System.currentTimeMillis(); } GUID getGUID() { return guid; } /** * Counts the responses uniquely. */ int countAddedResponses(Response[] responses) { int added = 0; for (Response response : responses) { Set<URN> urns = response.getUrns(); if (!urns.isEmpty()) { added += urnHashCodes.add(urns.iterator().next().hashCode()) ? 1 : 0; } else { // create lazily since responses should have urns if (responseHashCodes == null) { responseHashCodes = new IntSet(); } added += responseHashCodes.add(response.hashCode()) ? 1 : 0; } } // inspection-related code responseTimestamps.add(System.currentTimeMillis()); responseCounts.add(responses.length); addedResponses.add(added); // end inspection-related code return added; } /** * Returns the number of results that are still expected to come in. */ final int getRemainingResultsCount() { return requestedResponseCount - urnHashCodes.size() - (responseHashCodes != null ? responseHashCodes.size() : 0); } @Override public boolean equals(Object o) { if (! (o instanceof OOBSession)) return false; OOBSession other = (OOBSession) o; return Arrays.equals(token.getBytes(), other.token.getBytes()); } @Override public Object inspect() { Map<String,Object> ret = new HashMap<String,Object>(); ret.put("start",start); ret.put("urnh",urnHashCodes.size()); if (responseHashCodes != null) ret.put("rhh",responseHashCodes.size()); ret.put("rrc",requestedResponseCount); ret.put("timestamps",responseTimestamps); ret.put("rcounts",responseCounts); ret.put("added",addedResponses); return ret; } }