(zzz)
* i2psnark: Mark a peer's requests as unrequested on disconnect, preventing premature end game * i2psnark: Randomize selection of next piece during end game * i2psnark: Don't restore a partial piece to a peer that is already working on it * i2psnark: strip ".torrent" on web page * i2psnark: Limit piece size in generated torrent to 1MB max
This commit is contained in:
@ -321,8 +321,10 @@ public class Peer implements Comparable
|
|||||||
// try to save partial piece
|
// try to save partial piece
|
||||||
if (this.deregister) {
|
if (this.deregister) {
|
||||||
PeerListener p = state.listener;
|
PeerListener p = state.listener;
|
||||||
if (p != null)
|
if (p != null) {
|
||||||
p.savePeerPartial(state);
|
p.savePeerPartial(state);
|
||||||
|
p.markUnrequested(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
state = null;
|
state = null;
|
||||||
|
|
||||||
|
@ -438,6 +438,8 @@ public class PeerCoordinator implements PeerListener
|
|||||||
|
|
||||||
//Only request a piece we've requested before if there's no other choice.
|
//Only request a piece we've requested before if there's no other choice.
|
||||||
if (piece == null) {
|
if (piece == null) {
|
||||||
|
// let's not all get on the same piece
|
||||||
|
Collections.shuffle(requested);
|
||||||
Iterator it2 = requested.iterator();
|
Iterator it2 = requested.iterator();
|
||||||
while (piece == null && it2.hasNext())
|
while (piece == null && it2.hasNext())
|
||||||
{
|
{
|
||||||
@ -701,5 +703,59 @@ public class PeerCoordinator implements PeerListener
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Clear the requested flag for a piece if the peer
|
||||||
|
** is the only one requesting it
|
||||||
|
*/
|
||||||
|
private void markUnrequestedIfOnlyOne(Peer peer, int piece)
|
||||||
|
{
|
||||||
|
// see if anybody else is requesting
|
||||||
|
synchronized (peers)
|
||||||
|
{
|
||||||
|
Iterator it = peers.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Peer p = (Peer)it.next();
|
||||||
|
if (p.equals(peer))
|
||||||
|
continue;
|
||||||
|
if (p.state == null)
|
||||||
|
continue;
|
||||||
|
int[] arr = p.state.getRequestedPieces();
|
||||||
|
for (int i = 0; arr[i] >= 0; i++)
|
||||||
|
if(arr[i] == piece) {
|
||||||
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("Another peer is requesting piece " + piece);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// nobody is, so mark unrequested
|
||||||
|
synchronized(wantedPieces)
|
||||||
|
{
|
||||||
|
Iterator it = wantedPieces.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Piece p = (Piece)it.next();
|
||||||
|
if (p.getId() == piece) {
|
||||||
|
p.setRequested(false);
|
||||||
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("Removing from request list piece " + piece);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Mark a peer's requested pieces unrequested when it is disconnected
|
||||||
|
** Once for each piece
|
||||||
|
** This is enough trouble, maybe would be easier just to regenerate
|
||||||
|
** the requested list from scratch instead.
|
||||||
|
*/
|
||||||
|
public void markUnrequested(Peer peer)
|
||||||
|
{
|
||||||
|
if (peer.state == null)
|
||||||
|
return;
|
||||||
|
int[] arr = peer.state.getRequestedPieces();
|
||||||
|
for (int i = 0; arr[i] >= 0; i++)
|
||||||
|
markUnrequestedIfOnlyOne(peer, arr[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,4 +160,12 @@ public interface PeerListener
|
|||||||
* @return request (contains the partial data and valid length)
|
* @return request (contains the partial data and valid length)
|
||||||
*/
|
*/
|
||||||
Request getPeerPartial(BitField havePieces);
|
Request getPeerPartial(BitField havePieces);
|
||||||
|
|
||||||
|
/** Mark a peer's requested pieces unrequested when it is disconnected
|
||||||
|
* This prevents premature end game
|
||||||
|
*
|
||||||
|
* @param peer the peer that is disconnecting
|
||||||
|
*/
|
||||||
|
void markUnrequested(Peer peer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -363,6 +363,31 @@ class PeerState
|
|||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return array of pieces terminated by -1
|
||||||
|
// remove most duplicates
|
||||||
|
// but still could be some duplicates, not guaranteed
|
||||||
|
int[] getRequestedPieces()
|
||||||
|
{
|
||||||
|
int size = outstandingRequests.size();
|
||||||
|
int[] arr = new int[size+2];
|
||||||
|
int pc = -1;
|
||||||
|
int pos = 0;
|
||||||
|
if (pendingRequest != null) {
|
||||||
|
pc = pendingRequest.piece;
|
||||||
|
arr[pos++] = pc;
|
||||||
|
}
|
||||||
|
Request req = null;
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
Request r1 = (Request)outstandingRequests.get(i);
|
||||||
|
if (pc != r1.piece) {
|
||||||
|
pc = r1.piece;
|
||||||
|
arr[pos++] = pc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arr[pos] = -1;
|
||||||
|
return(arr);
|
||||||
|
}
|
||||||
|
|
||||||
void cancelMessage(int piece, int begin, int length)
|
void cancelMessage(int piece, int begin, int length)
|
||||||
{
|
{
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
@ -498,12 +523,23 @@ class PeerState
|
|||||||
// Check for adopting an orphaned partial piece
|
// Check for adopting an orphaned partial piece
|
||||||
Request r = listener.getPeerPartial(bitfield);
|
Request r = listener.getPeerPartial(bitfield);
|
||||||
if (r != null) {
|
if (r != null) {
|
||||||
|
// Check that r not already in outstandingRequests
|
||||||
|
int[] arr = getRequestedPieces();
|
||||||
|
boolean found = false;
|
||||||
|
for (int i = 0; arr[i] >= 0; i++) {
|
||||||
|
if (arr[i] == r.piece) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
outstandingRequests.add(r);
|
outstandingRequests.add(r);
|
||||||
if (!choked)
|
if (!choked)
|
||||||
out.sendRequest(r);
|
out.sendRequest(r);
|
||||||
lastRequest = r;
|
lastRequest = r;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
int nextPiece = listener.wantPiece(peer, bitfield);
|
int nextPiece = listener.wantPiece(peer, bitfield);
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug(peer + " want piece " + nextPiece);
|
_log.debug(peer + " want piece " + nextPiece);
|
||||||
|
@ -48,6 +48,7 @@ public class Storage
|
|||||||
|
|
||||||
/** The default piece size. */
|
/** The default piece size. */
|
||||||
private static int MIN_PIECE_SIZE = 256*1024;
|
private static int MIN_PIECE_SIZE = 256*1024;
|
||||||
|
private static int MAX_PIECE_SIZE = 1024*1024;
|
||||||
/** The maximum number of pieces in a torrent. */
|
/** The maximum number of pieces in a torrent. */
|
||||||
private static long MAX_PIECES = 100*1024/20;
|
private static long MAX_PIECES = 100*1024/20;
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ public class Storage
|
|||||||
|
|
||||||
piece_size = MIN_PIECE_SIZE;
|
piece_size = MIN_PIECE_SIZE;
|
||||||
pieces = (int) ((total - 1)/piece_size) + 1;
|
pieces = (int) ((total - 1)/piece_size) + 1;
|
||||||
while (pieces > MAX_PIECES)
|
while (pieces > MAX_PIECES && piece_size < MAX_PIECE_SIZE)
|
||||||
{
|
{
|
||||||
piece_size = piece_size*2;
|
piece_size = piece_size*2;
|
||||||
pieces = (int) ((total - 1)/piece_size) +1;
|
pieces = (int) ((total - 1)/piece_size) +1;
|
||||||
|
@ -294,6 +294,9 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
String filename = snark.torrent;
|
String filename = snark.torrent;
|
||||||
File f = new File(filename);
|
File f = new File(filename);
|
||||||
filename = f.getName(); // the torrent may be the canonical name, so lets just grab the local name
|
filename = f.getName(); // the torrent may be the canonical name, so lets just grab the local name
|
||||||
|
int i = filename.lastIndexOf(".torrent");
|
||||||
|
if (i > 0)
|
||||||
|
filename = filename.substring(0, i);
|
||||||
if (filename.length() > MAX_DISPLAYED_FILENAME_LENGTH)
|
if (filename.length() > MAX_DISPLAYED_FILENAME_LENGTH)
|
||||||
filename = filename.substring(0, MAX_DISPLAYED_FILENAME_LENGTH) + "...";
|
filename = filename.substring(0, MAX_DISPLAYED_FILENAME_LENGTH) + "...";
|
||||||
long total = snark.meta.getTotalLength();
|
long total = snark.meta.getTotalLength();
|
||||||
@ -309,12 +312,14 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
else
|
else
|
||||||
remainingSeconds = -1;
|
remainingSeconds = -1;
|
||||||
long uploaded = snark.coordinator.getUploaded();
|
long uploaded = snark.coordinator.getUploaded();
|
||||||
|
boolean isRunning = !snark.stopped;
|
||||||
stats[0] += snark.coordinator.getDownloaded();
|
stats[0] += snark.coordinator.getDownloaded();
|
||||||
stats[1] += uploaded;
|
stats[1] += uploaded;
|
||||||
|
if (isRunning) {
|
||||||
stats[2] += downBps;
|
stats[2] += downBps;
|
||||||
stats[3] += upBps;
|
stats[3] += upBps;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isRunning = !snark.stopped;
|
|
||||||
boolean isValid = snark.meta != null;
|
boolean isValid = snark.meta != null;
|
||||||
boolean singleFile = snark.meta.getFiles() == null;
|
boolean singleFile = snark.meta.getFiles() == null;
|
||||||
|
|
||||||
|
10
history.txt
10
history.txt
@ -1,4 +1,12 @@
|
|||||||
$Id: history.txt,v 1.517 2006-09-09 17:15:06 zzz Exp $
|
$Id: history.txt,v 1.518 2006-09-09 20:55:38 zzz Exp $
|
||||||
|
|
||||||
|
2006-09-10 zzz
|
||||||
|
* i2psnark: Mark a peer's requests as unrequested on disconnect,
|
||||||
|
preventing premature end game
|
||||||
|
* i2psnark: Randomize selection of next piece during end game
|
||||||
|
* i2psnark: Don't restore a partial piece to a peer that is already working on it
|
||||||
|
* i2psnark: strip ".torrent" on web page
|
||||||
|
* i2psnark: Limit piece size in generated torrent to 1MB max
|
||||||
|
|
||||||
2006-09-09 zzz
|
2006-09-09 zzz
|
||||||
* i2psnark: Add "Stalled" indication and stat totals on web page
|
* i2psnark: Add "Stalled" indication and stat totals on web page
|
||||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RouterVersion {
|
public class RouterVersion {
|
||||||
public final static String ID = "$Revision: 1.455 $ $Date: 2006-09-09 17:15:05 $";
|
public final static String ID = "$Revision: 1.456 $ $Date: 2006-09-09 20:55:37 $";
|
||||||
public final static String VERSION = "0.6.1.25";
|
public final static String VERSION = "0.6.1.25";
|
||||||
public final static long BUILD = 2;
|
public final static long BUILD = 3;
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
||||||
System.out.println("Router ID: " + RouterVersion.ID);
|
System.out.println("Router ID: " + RouterVersion.ID);
|
||||||
|
Reference in New Issue
Block a user