Request pieces in rarest-first order, instead of randomly.
This commit is contained in:
@ -69,13 +69,12 @@ public class PeerCoordinator implements PeerListener
|
|||||||
this.storage = storage;
|
this.storage = storage;
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
|
|
||||||
// Make a random list of piece numbers
|
// Make a list of pieces
|
||||||
wantedPieces = new ArrayList();
|
wantedPieces = new ArrayList();
|
||||||
BitField bitfield = storage.getBitField();
|
BitField bitfield = storage.getBitField();
|
||||||
for(int i = 0; i < metainfo.getPieces(); i++)
|
for(int i = 0; i < metainfo.getPieces(); i++)
|
||||||
if (!bitfield.get(i))
|
if (!bitfield.get(i))
|
||||||
wantedPieces.add(new Integer(i));
|
wantedPieces.add(new Piece(i));
|
||||||
Collections.shuffle(wantedPieces);
|
|
||||||
|
|
||||||
// Install a timer to check the uploaders.
|
// Install a timer to check the uploaders.
|
||||||
timer.schedule(new PeerCheckerTask(this), CHECK_PERIOD, CHECK_PERIOD);
|
timer.schedule(new PeerCheckerTask(this), CHECK_PERIOD, CHECK_PERIOD);
|
||||||
@ -288,7 +287,7 @@ public class PeerCoordinator implements PeerListener
|
|||||||
|
|
||||||
synchronized(wantedPieces)
|
synchronized(wantedPieces)
|
||||||
{
|
{
|
||||||
return wantedPieces.contains(new Integer(piece));
|
return wantedPieces.contains(new Piece(piece));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,8 +305,10 @@ public class PeerCoordinator implements PeerListener
|
|||||||
Iterator it = wantedPieces.iterator();
|
Iterator it = wantedPieces.iterator();
|
||||||
while (it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
int i = ((Integer)it.next()).intValue();
|
Piece p = (Piece)it.next();
|
||||||
|
int i = p.getId();
|
||||||
if (bitfield.get(i))
|
if (bitfield.get(i))
|
||||||
|
p.addPeer(peer);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -325,28 +326,38 @@ public class PeerCoordinator implements PeerListener
|
|||||||
|
|
||||||
synchronized(wantedPieces)
|
synchronized(wantedPieces)
|
||||||
{
|
{
|
||||||
Integer piece = null;
|
Piece piece = null;
|
||||||
|
Collections.sort(wantedPieces); // Sort in order of rarest first.
|
||||||
|
List requested = new ArrayList();
|
||||||
Iterator it = wantedPieces.iterator();
|
Iterator it = wantedPieces.iterator();
|
||||||
while (piece == null && it.hasNext())
|
while (piece == null && it.hasNext())
|
||||||
{
|
{
|
||||||
Integer i = (Integer)it.next();
|
Piece p = (Piece)it.next();
|
||||||
if (havePieces.get(i.intValue()))
|
if (havePieces.get(p.getId()) && !p.isRequested())
|
||||||
{
|
{
|
||||||
it.remove();
|
piece = p;
|
||||||
piece = i;
|
|
||||||
}
|
}
|
||||||
|
else if (p.isRequested())
|
||||||
|
{
|
||||||
|
requested.add(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (piece == null)
|
//Only request a piece we've requested before if there's no other choice.
|
||||||
return -1;
|
if (piece == null) {
|
||||||
|
Iterator it2 = requested.iterator();
|
||||||
// We add it back at the back of the list. It will be removed
|
while (piece == null && it2.hasNext())
|
||||||
// if gotPiece is called later. This means that the last
|
{
|
||||||
// couple of pieces might very well be asked from multiple
|
Piece p = (Piece)it2.next();
|
||||||
// peers but that is OK.
|
if (havePieces.get(p.getId()))
|
||||||
wantedPieces.add(piece);
|
{
|
||||||
|
piece = p;
|
||||||
return piece.intValue();
|
}
|
||||||
|
}
|
||||||
|
if (piece == null) return -1; //If we still can't find a piece we want, so be it.
|
||||||
|
}
|
||||||
|
piece.setRequested(true);
|
||||||
|
return piece.getId();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,7 +415,7 @@ public class PeerCoordinator implements PeerListener
|
|||||||
|
|
||||||
synchronized(wantedPieces)
|
synchronized(wantedPieces)
|
||||||
{
|
{
|
||||||
Integer p = new Integer(piece);
|
Piece p = new Piece(piece);
|
||||||
if (!wantedPieces.contains(p))
|
if (!wantedPieces.contains(p))
|
||||||
{
|
{
|
||||||
if (Snark.debug >= Snark.INFO)
|
if (Snark.debug >= Snark.INFO)
|
||||||
|
35
apps/i2psnark/java/src/org/klomp/snark/Piece.java
Normal file
35
apps/i2psnark/java/src/org/klomp/snark/Piece.java
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package org.klomp.snark;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
public class Piece implements Comparable {
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private Set peers;
|
||||||
|
private boolean requested;
|
||||||
|
|
||||||
|
public Piece(int id) {
|
||||||
|
this.id = id;
|
||||||
|
this.peers = new HashSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(Object o) throws ClassCastException {
|
||||||
|
return this.peers.size() - ((Piece)o).peers.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == null) return false;
|
||||||
|
try {
|
||||||
|
return this.id == ((Piece)o).id;
|
||||||
|
} catch (ClassCastException cce) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() { return this.id; }
|
||||||
|
public Set getPeers() { return this.peers; }
|
||||||
|
public boolean addPeer(Peer peer) { return this.peers.add(peer.getPeerID()); }
|
||||||
|
public boolean isRequested() { return this.requested; }
|
||||||
|
public void setRequested(boolean requested) { this.requested = requested; }
|
||||||
|
}
|
Reference in New Issue
Block a user