From 05e2da7c2257a9c420c775566a403e8aaf7e10a8 Mon Sep 17 00:00:00 2001 From: ragnarok <ragnarok> Date: Thu, 20 Oct 2005 22:05:51 +0000 Subject: [PATCH] Request pieces in rarest-first order, instead of randomly. --- .../src/org/klomp/snark/PeerCoordinator.java | 55 +++++++++++-------- .../java/src/org/klomp/snark/Piece.java | 35 ++++++++++++ 2 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 apps/i2psnark/java/src/org/klomp/snark/Piece.java diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java index 3fb39ce96b..ce4a0658ac 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java @@ -69,13 +69,12 @@ public class PeerCoordinator implements PeerListener this.storage = storage; this.listener = listener; - // Make a random list of piece numbers + // Make a list of pieces wantedPieces = new ArrayList(); BitField bitfield = storage.getBitField(); for(int i = 0; i < metainfo.getPieces(); i++) if (!bitfield.get(i)) - wantedPieces.add(new Integer(i)); - Collections.shuffle(wantedPieces); + wantedPieces.add(new Piece(i)); // Install a timer to check the uploaders. timer.schedule(new PeerCheckerTask(this), CHECK_PERIOD, CHECK_PERIOD); @@ -288,7 +287,7 @@ public class PeerCoordinator implements PeerListener 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(); while (it.hasNext()) { - int i = ((Integer)it.next()).intValue(); + Piece p = (Piece)it.next(); + int i = p.getId(); if (bitfield.get(i)) + p.addPeer(peer); return true; } } @@ -325,28 +326,38 @@ public class PeerCoordinator implements PeerListener 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(); while (piece == null && it.hasNext()) { - Integer i = (Integer)it.next(); - if (havePieces.get(i.intValue())) + Piece p = (Piece)it.next(); + if (havePieces.get(p.getId()) && !p.isRequested()) { - it.remove(); - piece = i; + piece = p; } + else if (p.isRequested()) + { + requested.add(p); + } } - - if (piece == null) - return -1; - - // We add it back at the back of the list. It will be removed - // if gotPiece is called later. This means that the last - // couple of pieces might very well be asked from multiple - // peers but that is OK. - wantedPieces.add(piece); - - return piece.intValue(); + + //Only request a piece we've requested before if there's no other choice. + if (piece == null) { + Iterator it2 = requested.iterator(); + while (piece == null && it2.hasNext()) + { + Piece p = (Piece)it2.next(); + if (havePieces.get(p.getId())) + { + piece = p; + } + } + 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) { - Integer p = new Integer(piece); + Piece p = new Piece(piece); if (!wantedPieces.contains(p)) { if (Snark.debug >= Snark.INFO) diff --git a/apps/i2psnark/java/src/org/klomp/snark/Piece.java b/apps/i2psnark/java/src/org/klomp/snark/Piece.java new file mode 100644 index 0000000000..d98421b992 --- /dev/null +++ b/apps/i2psnark/java/src/org/klomp/snark/Piece.java @@ -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; } +} -- GitLab