2005-10-20 22:05:51 +00:00
|
|
|
package org.klomp.snark;
|
|
|
|
|
2011-01-07 00:23:25 +00:00
|
|
|
import java.util.HashSet;
|
2008-07-16 13:42:54 +00:00
|
|
|
import java.util.Set;
|
2005-10-20 22:05:51 +00:00
|
|
|
|
2010-11-26 00:44:00 +00:00
|
|
|
/**
|
|
|
|
* This class is used solely by PeerCoordinator.
|
2011-01-07 00:23:25 +00:00
|
|
|
* Caller must synchronize on many of these methods.
|
2010-11-26 00:44:00 +00:00
|
|
|
*/
|
|
|
|
class Piece implements Comparable {
|
2005-10-20 22:05:51 +00:00
|
|
|
|
2011-01-07 00:23:25 +00:00
|
|
|
private final int id;
|
|
|
|
private final Set<PeerID> peers;
|
2011-01-05 20:21:29 +00:00
|
|
|
/** @since 0.8.3 */
|
2012-10-14 16:38:36 +00:00
|
|
|
private volatile Set<PeerID> requests;
|
2010-10-15 13:48:36 +00:00
|
|
|
/** @since 0.8.1 */
|
|
|
|
private int priority;
|
2005-10-20 22:05:51 +00:00
|
|
|
|
|
|
|
public Piece(int id) {
|
|
|
|
this.id = id;
|
2013-11-21 12:43:45 +00:00
|
|
|
this.peers = new HashSet<PeerID>(I2PSnarkUtil.MAX_CONNECTIONS / 2);
|
2011-01-07 00:23:25 +00:00
|
|
|
// defer creating requests to save memory
|
2005-10-20 22:05:51 +00:00
|
|
|
}
|
|
|
|
|
2010-10-15 13:48:36 +00:00
|
|
|
/**
|
|
|
|
* Highest priority first,
|
|
|
|
* then rarest first
|
|
|
|
*/
|
2005-10-20 22:05:51 +00:00
|
|
|
public int compareTo(Object o) throws ClassCastException {
|
2010-10-15 13:48:36 +00:00
|
|
|
int pdiff = ((Piece)o).priority - this.priority; // reverse
|
|
|
|
if (pdiff != 0)
|
|
|
|
return pdiff;
|
2005-10-20 22:05:51 +00:00
|
|
|
return this.peers.size() - ((Piece)o).peers.size();
|
|
|
|
}
|
|
|
|
|
2009-08-11 21:58:56 +00:00
|
|
|
@Override
|
2005-10-20 22:05:51 +00:00
|
|
|
public boolean equals(Object o) {
|
2011-01-10 17:14:34 +00:00
|
|
|
if (o == null) return false;
|
2009-08-11 21:58:56 +00:00
|
|
|
if (o instanceof Piece) {
|
2009-10-11 22:51:43 +00:00
|
|
|
return this.id == ((Piece)o).id;
|
2005-10-20 22:05:51 +00:00
|
|
|
}
|
2009-08-11 21:58:56 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
int hash = 5;
|
|
|
|
hash = 31 * hash + this.id;
|
|
|
|
return hash;
|
2005-10-20 22:05:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public int getId() { return this.id; }
|
2011-01-07 00:23:25 +00:00
|
|
|
|
|
|
|
/** caller must synchronize */
|
2005-10-20 22:05:51 +00:00
|
|
|
public boolean addPeer(Peer peer) { return this.peers.add(peer.getPeerID()); }
|
2011-01-07 00:23:25 +00:00
|
|
|
|
2012-10-14 16:38:36 +00:00
|
|
|
/**
|
|
|
|
* Caller must synchronize.
|
|
|
|
* @return true if removed
|
|
|
|
*/
|
2005-10-20 23:28:32 +00:00
|
|
|
public boolean removePeer(Peer peer) { return this.peers.remove(peer.getPeerID()); }
|
2011-01-07 00:23:25 +00:00
|
|
|
|
2012-05-30 15:21:37 +00:00
|
|
|
/**
|
|
|
|
* How many peers have this piece?
|
|
|
|
* Caller must synchronize
|
|
|
|
* @since 0.9.1
|
|
|
|
*/
|
|
|
|
public int getPeerCount() {
|
|
|
|
return this.peers.size();
|
|
|
|
}
|
|
|
|
|
2011-01-07 00:23:25 +00:00
|
|
|
/** caller must synchronize */
|
|
|
|
public boolean isRequested() {
|
|
|
|
return this.requests != null && !this.requests.isEmpty();
|
|
|
|
}
|
2011-01-05 20:21:29 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Since 0.8.3, keep track of who is requesting here,
|
|
|
|
* to avoid deadlocks from querying each peer.
|
2011-01-07 00:23:25 +00:00
|
|
|
* Caller must synchronize
|
2011-01-05 20:21:29 +00:00
|
|
|
*/
|
|
|
|
public void setRequested(Peer peer, boolean requested) {
|
2011-01-07 00:23:25 +00:00
|
|
|
if (requested) {
|
|
|
|
if (this.requests == null)
|
2013-11-21 12:43:45 +00:00
|
|
|
this.requests = new HashSet<PeerID>(2);
|
2011-01-05 20:21:29 +00:00
|
|
|
this.requests.add(peer.getPeerID());
|
2011-01-07 00:23:25 +00:00
|
|
|
} else {
|
|
|
|
if (this.requests != null)
|
|
|
|
this.requests.remove(peer.getPeerID());
|
|
|
|
}
|
2011-01-05 20:21:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Is peer requesting this piece?
|
2011-01-07 00:23:25 +00:00
|
|
|
* Caller must synchronize
|
2011-01-05 20:21:29 +00:00
|
|
|
* @since 0.8.3
|
|
|
|
*/
|
|
|
|
public boolean isRequestedBy(Peer peer) {
|
2011-01-07 00:23:25 +00:00
|
|
|
return this.requests != null && this.requests.contains(peer.getPeerID());
|
2011-01-05 20:21:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* How many peers are requesting this piece?
|
2011-01-07 00:23:25 +00:00
|
|
|
* Caller must synchronize
|
2011-01-05 20:21:29 +00:00
|
|
|
* @since 0.8.3
|
|
|
|
*/
|
|
|
|
public int getRequestCount() {
|
2011-01-07 00:23:25 +00:00
|
|
|
return this.requests == null ? 0 : this.requests.size();
|
2011-01-05 20:21:29 +00:00
|
|
|
}
|
2012-10-14 16:38:36 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Clear all knowledge of peers
|
|
|
|
* Caller must synchronize
|
|
|
|
* @since 0.9.3
|
|
|
|
*/
|
|
|
|
public void clear() {
|
|
|
|
peers.clear();
|
|
|
|
if (requests != null)
|
|
|
|
requests.clear();
|
|
|
|
}
|
2005-12-30 23:33:52 +00:00
|
|
|
|
2010-10-15 13:48:36 +00:00
|
|
|
/** @return default 0 @since 0.8.1 */
|
|
|
|
public int getPriority() { return this.priority; }
|
|
|
|
|
|
|
|
/** @since 0.8.1 */
|
|
|
|
public void setPriority(int p) { this.priority = p; }
|
|
|
|
|
|
|
|
/** @since 0.8.1 */
|
|
|
|
public boolean isDisabled() { return this.priority < 0; }
|
|
|
|
|
|
|
|
/** @since 0.8.1 */
|
|
|
|
public void setDisabled() { this.priority = -1; }
|
|
|
|
|
2009-08-11 21:58:56 +00:00
|
|
|
@Override
|
2005-12-30 23:33:52 +00:00
|
|
|
public String toString() {
|
|
|
|
return String.valueOf(id);
|
|
|
|
}
|
2005-10-20 22:05:51 +00:00
|
|
|
}
|