diff --git a/apps/i2psnark/java/src/org/klomp/snark/BitField.java b/apps/i2psnark/java/src/org/klomp/snark/BitField.java index 4fb6b2815..3f16deb68 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/BitField.java +++ b/apps/i2psnark/java/src/org/klomp/snark/BitField.java @@ -39,7 +39,6 @@ public class BitField this.size = size; int arraysize = ((size-1)/8)+1; bitfield = new byte[arraysize]; - this.count = 0; } /** @@ -99,9 +98,11 @@ public class BitField throw new IndexOutOfBoundsException(Integer.toString(bit)); int index = bit/8; int mask = 128 >> (bit % 8); - if ((bitfield[index] & mask) == 0) { - count++; - bitfield[index] |= mask; + synchronized(this) { + if ((bitfield[index] & mask) == 0) { + count++; + bitfield[index] |= mask; + } } } diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java index 536865b0b..1eb93e111 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java +++ b/apps/i2psnark/java/src/org/klomp/snark/PeerCoordinator.java @@ -649,10 +649,15 @@ class PeerCoordinator implements PeerListener if (listener != null) listener.peerChange(this, peer); - synchronized(wantedPieces) - { - return wantedPieces.contains(new Piece(piece)); - } + synchronized(wantedPieces) { + for (Piece pc : wantedPieces) { + if (pc.getId() == piece) { + pc.addPeer(peer); + return true; + } + } + return false; + } } /** @@ -664,20 +669,17 @@ class PeerCoordinator implements PeerListener if (listener != null) listener.peerChange(this, peer); - synchronized(wantedPieces) - { - Iterator it = wantedPieces.iterator(); - while (it.hasNext()) - { - Piece p = it.next(); + boolean rv = false; + synchronized(wantedPieces) { + for (Piece p : wantedPieces) { int i = p.getId(); if (bitfield.get(i)) { p.addPeer(peer); - return true; + rv = true; } - } - } - return false; + } + } + return rv; } /** @@ -1077,8 +1079,7 @@ class PeerCoordinator implements PeerListener */ public void removePeerFromPieces(Peer peer) { synchronized(wantedPieces) { - for(Iterator iter = wantedPieces.iterator(); iter.hasNext(); ) { - Piece piece = iter.next(); + for (Piece piece : wantedPieces) { piece.removePeer(peer); } } @@ -1172,11 +1173,24 @@ class PeerCoordinator implements PeerListener for(Piece piece : wantedPieces) { if (piece.getId() == savedPiece) { if (peer.isCompleted() && piece.getPeerCount() > 1) { - // Try to preserve rarest-first when we have only one seeder - // by not preferring a partial piece that others have too + // Try to preserve rarest-first + // by not requesting a partial piece that non-seeders also have // from a seeder - skipped = true; - break; + boolean nonSeeds = false; + for (Peer pr : peers) { + PeerState state = pr.state; + if (state == null) continue; + BitField bf = state.bitfield; + if (bf == null) continue; + if (bf.get(savedPiece) && !pr.isCompleted()) { + nonSeeds = true; + break; + } + } + if (nonSeeds) { + skipped = true; + break; + } } iter.remove(); piece.setRequested(peer, true); diff --git a/apps/i2psnark/java/src/org/klomp/snark/Piece.java b/apps/i2psnark/java/src/org/klomp/snark/Piece.java index a9822640b..3ca03ad98 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/Piece.java +++ b/apps/i2psnark/java/src/org/klomp/snark/Piece.java @@ -18,7 +18,7 @@ class Piece implements Comparable { public Piece(int id) { this.id = id; - this.peers = new HashSet(I2PSnarkUtil.MAX_CONNECTIONS); + this.peers = new HashSet(I2PSnarkUtil.MAX_CONNECTIONS / 2); // defer creating requests to save memory } diff --git a/history.txt b/history.txt index c45dbc660..c52500c4f 100644 --- a/history.txt +++ b/history.txt @@ -1,3 +1,13 @@ +2012-09-28 zzz + * i2psnark: + - Fix bugs in rarest-first tracking + - Fix requesting of partial piece when there are multiple seeds + - Synch fix in BitField + * i2ptunnel: Fix wrong server IP in log message + * peers.jsp: Remove SSU "Dev" column + * SessionKeyManager: Store original tagset size for debugging + * Streaming: Don't send RST on globally-blackisted conns + 2012-09-26 zzz * Addresses: Reject numeric IPs of the form n, n.n, and n.n.n * Console, i2ptunnel: More validation of address and port in forms diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 0725033fa..f6e6df3a5 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 3; + public final static long BUILD = 4; /** for example "-test" */ public final static String EXTRA = "";