* i2psnark:

- Limit number of parallel requests of a single piece when in the end game
      - Shorten and weight the speed tracker so the display is more
        reflective of current speed
This commit is contained in:
zzz
2010-11-01 14:35:01 +00:00
parent 8d13bcbac0
commit 3678aa157e
5 changed files with 77 additions and 44 deletions

View File

@ -56,8 +56,8 @@ public class Peer implements Comparable
private long _id; private long _id;
final static long CHECK_PERIOD = PeerCoordinator.CHECK_PERIOD; // 40 seconds final static long CHECK_PERIOD = PeerCoordinator.CHECK_PERIOD; // 40 seconds
final static int RATE_DEPTH = PeerCoordinator.RATE_DEPTH; // make following arrays RATE_DEPTH long final static int RATE_DEPTH = PeerCoordinator.RATE_DEPTH; // make following arrays RATE_DEPTH long
private long uploaded_old[] = {-1,-1,-1,-1,-1,-1}; private long uploaded_old[] = {-1,-1,-1};
private long downloaded_old[] = {-1,-1,-1,-1,-1,-1}; private long downloaded_old[] = {-1,-1,-1};
/** /**
* Creates a disconnected peer given a PeerID, your own id and the * Creates a disconnected peer given a PeerID, your own id and the
@ -403,6 +403,15 @@ public class Peer implements Comparable
s.cancelPiece(piece); s.cancelPiece(piece);
} }
/**
* Are we currently requesting the piece?
* @since 0.8.1
*/
boolean isRequesting(int p) {
PeerState s = state;
return s != null && s.isRequesting(p);
}
/** /**
* Update the request queue. * Update the request queue.
* Call after adding wanted pieces. * Call after adding wanted pieces.
@ -572,17 +581,8 @@ public class Peer implements Comparable
*/ */
public void setRateHistory(long up, long down) public void setRateHistory(long up, long down)
{ {
setRate(up, uploaded_old); PeerCoordinator.setRate(up, uploaded_old);
setRate(down, downloaded_old); PeerCoordinator.setRate(down, downloaded_old);
}
private void setRate(long val, long array[])
{
synchronized(array) {
for (int i = RATE_DEPTH-1; i > 0; i--)
array[i] = array[i-1];
array[0] = val;
}
} }
/** /**
@ -590,28 +590,11 @@ public class Peer implements Comparable
*/ */
public long getUploadRate() public long getUploadRate()
{ {
return getRate(uploaded_old); return PeerCoordinator.getRate(uploaded_old);
} }
public long getDownloadRate() public long getDownloadRate()
{ {
return getRate(downloaded_old); return PeerCoordinator.getRate(downloaded_old);
} }
private long getRate(long array[])
{
long rate = 0;
int i = 0;
synchronized(array) {
for ( ; i < RATE_DEPTH; i++){
if (array[i] < 0)
break;
rate += array[i];
}
}
if (i == 0)
return 0;
return rate / (i * CHECK_PERIOD / 1000);
}
} }

View File

@ -57,9 +57,9 @@ public class PeerCoordinator implements PeerListener
private long uploaded; private long uploaded;
private long downloaded; private long downloaded;
final static int RATE_DEPTH = 6; // make following arrays RATE_DEPTH long final static int RATE_DEPTH = 3; // make following arrays RATE_DEPTH long
private long uploaded_old[] = {-1,-1,-1,-1,-1,-1}; private long uploaded_old[] = {-1,-1,-1};
private long downloaded_old[] = {-1,-1,-1,-1,-1,-1}; private long downloaded_old[] = {-1,-1,-1};
// synchronize on this when changing peers or downloaders // synchronize on this when changing peers or downloaders
final List<Peer> peers = new ArrayList(); final List<Peer> peers = new ArrayList();
@ -193,7 +193,7 @@ public class PeerCoordinator implements PeerListener
setRate(down, downloaded_old); setRate(down, downloaded_old);
} }
private static void setRate(long val, long array[]) static void setRate(long val, long array[])
{ {
synchronized(array) { synchronized(array) {
for (int i = RATE_DEPTH-1; i > 0; i--) for (int i = RATE_DEPTH-1; i > 0; i--)
@ -224,20 +224,23 @@ public class PeerCoordinator implements PeerListener
return (r * 1000) / CHECK_PERIOD; return (r * 1000) / CHECK_PERIOD;
} }
private long getRate(long array[]) static long getRate(long array[])
{ {
long rate = 0; long rate = 0;
int i = 0; int i = 0;
int factor = 0;
synchronized(array) { synchronized(array) {
for ( ; i < RATE_DEPTH; i++) { for ( ; i < RATE_DEPTH; i++) {
if (array[i] < 0) if (array[i] < 0)
break; break;
rate += array[i]; int f = RATE_DEPTH - i;
rate += array[i] * f;
factor += f;
} }
} }
if (i == 0) if (i == 0)
return 0; return 0;
return rate / (i * CHECK_PERIOD / 1000); return rate / (factor * i * CHECK_PERIOD / 1000);
} }
public MetaInfo getMetaInfo() public MetaInfo getMetaInfo()
@ -509,6 +512,12 @@ public class PeerCoordinator implements PeerListener
*/ */
private static final int END_GAME_THRESHOLD = 8; private static final int END_GAME_THRESHOLD = 8;
/**
* Max number of peers to get a piece from when in end game
* @since 0.8.1
*/
private static final int MAX_PARALLEL_REQUESTS = 4;
/** /**
* Returns one of pieces in the given BitField that is still wanted or * Returns one of pieces in the given BitField that is still wanted or
* -1 if none of the given pieces are wanted. * -1 if none of the given pieces are wanted.
@ -551,15 +560,32 @@ public class PeerCoordinator implements PeerListener
if (wantedPieces.size() > END_GAME_THRESHOLD) if (wantedPieces.size() > END_GAME_THRESHOLD)
return -1; // nothing to request and not in end game return -1; // nothing to request and not in end game
// let's not all get on the same piece // let's not all get on the same piece
// Even better would be to sort by number of requests
Collections.shuffle(requested, _random); Collections.shuffle(requested, _random);
Iterator<Piece> it2 = requested.iterator(); Iterator<Piece> it2 = requested.iterator();
while (piece == null && it2.hasNext()) while (piece == null && it2.hasNext())
{ {
Piece p = it2.next(); Piece p = it2.next();
if (havePieces.get(p.getId())) if (havePieces.get(p.getId())) {
{ // limit number of parallel requests
int requestedCount = 0;
synchronized(peers) {
for (Peer pr : peers) {
if (pr.isRequesting(p.getId())) {
if (pr.equals(peer)) {
// don't give it to him again
requestedCount = MAX_PARALLEL_REQUESTS;
break;
}
if (++requestedCount >= MAX_PARALLEL_REQUESTS)
break;
}
}
}
if (requestedCount >= MAX_PARALLEL_REQUESTS)
continue;
piece = p; piece = p;
} }
} }
if (piece == null) { if (piece == null) {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
@ -568,7 +594,7 @@ public class PeerCoordinator implements PeerListener
// + " wanted = " + wantedPieces + " peerHas = " + havePieces); // + " wanted = " + wantedPieces + " peerHas = " + havePieces);
return -1; //If we still can't find a piece we want, so be it. return -1; //If we still can't find a piece we want, so be it.
} else { } else {
// Should be a lot smarter here - limit # of parallel attempts and // Should be a lot smarter here -
// share blocks rather than starting from 0 with each peer. // share blocks rather than starting from 0 with each peer.
// This is where the flaws of the snark data model are really exposed. // This is where the flaws of the snark data model are really exposed.
// Could also randomize within the duplicate set rather than strict rarest-first // Could also randomize within the duplicate set rather than strict rarest-first

View File

@ -470,6 +470,18 @@ class PeerState
} }
} }
/**
* Are we currently requesting the piece?
* @since 0.8.1
*/
synchronized boolean isRequesting(int piece) {
for (Request req : outstandingRequests) {
if (req.piece == piece)
return true;
}
return false;
}
/** /**
* Starts or resumes requesting pieces. * Starts or resumes requesting pieces.
* @param resend should we resend outstanding requests? * @param resend should we resend outstanding requests?

View File

@ -1,3 +1,15 @@
2010-11-01 zzz
* ClientConnectionRunner: Add synch to fix race causing AIOOBE
(http://forum.i2p/viewtopic.php?t=5061)
* configlogging.jsp: Parse log limit with current locale
(ticket #118)
* i2psnark:
- Limit number of parallel requests of a single piece when in the end game
- Shorten and weight the speed tracker so the display is more
reflective of current speed
* logs.jsp: Add message if wrapper log not found
(ticket #103)
2010-10-30 zzz 2010-10-30 zzz
* i2psnark: * i2psnark:
- Priority mapping bugfix - Priority mapping bugfix

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION; public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 6; public final static long BUILD = 7;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";