mirror of
https://github.com/Rogiel/torrent4j
synced 2025-12-05 23:22:49 +00:00
Scoring algorithm
This commit is contained in:
30
pom.xml
30
pom.xml
@@ -5,7 +5,7 @@
|
||||
<artifactId>libtorrent</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>libtorrent</name>
|
||||
<version>1.0</version>
|
||||
<version>1.0.0-alpha2</version>
|
||||
<description>Java library used for downloading and uploading torrent files</description>
|
||||
<url>http://code.google.com/p/libtorrent-java</url>
|
||||
|
||||
@@ -97,6 +97,34 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-pdf-plugin</artifactId>
|
||||
<version>1.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>pdf</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>pdf</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>2.4.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>clean</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
|
||||
@@ -21,6 +21,8 @@ import net.torrent.protocol.algorithm.TorrentPeerAlgorithm;
|
||||
import net.torrent.protocol.algorithm.TorrentPieceDownloadAlgorithm;
|
||||
import net.torrent.protocol.algorithm.TorrentPieceUploadAlgorithm;
|
||||
import net.torrent.protocol.peerwire.manager.TorrentManager;
|
||||
import net.torrent.torrent.piece.PieceSelector;
|
||||
import net.torrent.torrent.piece.ScoredPieceSelector;
|
||||
|
||||
/**
|
||||
* Standard torrent algorithm
|
||||
@@ -28,15 +30,21 @@ import net.torrent.protocol.peerwire.manager.TorrentManager;
|
||||
* @author <a href="http://www.rogiel.com/">Rogiel Josias Sulzbach</a>
|
||||
*/
|
||||
public class TorrentStdAlgorithm implements TorrentAlgorithm {
|
||||
private final PieceSelector pieceSelector;
|
||||
|
||||
private final TorrentPeerAlgorithm peerAlgorithm;
|
||||
private final TorrentInterestAlgorithm interestAlgorithm;
|
||||
private final TorrentPieceDownloadAlgorithm downloadAlgorithm;
|
||||
private final TorrentPieceUploadAlgorithm uploadAlgorithm;
|
||||
|
||||
public TorrentStdAlgorithm(final TorrentManager manager) {
|
||||
pieceSelector = new ScoredPieceSelector(manager);
|
||||
|
||||
peerAlgorithm = new TorrentStdPeerAlgorithm(manager);
|
||||
interestAlgorithm = new TorrentStdInterestAlgorithm(manager);
|
||||
downloadAlgorithm = new TorrentStdPieceDownloadAlgorithm(manager);
|
||||
interestAlgorithm = new TorrentStdInterestAlgorithm(manager,
|
||||
pieceSelector);
|
||||
downloadAlgorithm = new TorrentStdPieceDownloadAlgorithm(manager,
|
||||
pieceSelector);
|
||||
uploadAlgorithm = new TorrentStdPieceUploadAlgorithm(manager);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import net.torrent.protocol.peerwire.manager.TorrentManager;
|
||||
import net.torrent.torrent.context.TorrentPeer;
|
||||
import net.torrent.torrent.context.TorrentPeer.ChokingState;
|
||||
import net.torrent.torrent.context.TorrentPeer.InterestState;
|
||||
import net.torrent.torrent.piece.PieceSelector;
|
||||
|
||||
/**
|
||||
* Standard torrent interest algorithm
|
||||
@@ -29,15 +30,29 @@ import net.torrent.torrent.context.TorrentPeer.InterestState;
|
||||
public class TorrentStdInterestAlgorithm implements TorrentInterestAlgorithm {
|
||||
@SuppressWarnings("unused")
|
||||
private final TorrentManager manager;
|
||||
private final PieceSelector selector;
|
||||
|
||||
public TorrentStdInterestAlgorithm(TorrentManager manager) {
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param manager
|
||||
* the manager
|
||||
* @param pieceSelector
|
||||
* the piece selector
|
||||
*/
|
||||
public TorrentStdInterestAlgorithm(TorrentManager manager,
|
||||
PieceSelector pieceSelector) {
|
||||
this.manager = manager;
|
||||
this.selector = pieceSelector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InterestState interested(TorrentPeer peer) {
|
||||
// if(peer.getPort() == 25944)
|
||||
// return InterestState.UNINTERESTED;
|
||||
int pieces = selector.countPieces(peer);
|
||||
if(pieces >= 5)
|
||||
return InterestState.INTERESTED;
|
||||
|
||||
|
||||
return InterestState.INTERESTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import net.torrent.torrent.TorrentPart;
|
||||
import net.torrent.torrent.TorrentPiece;
|
||||
import net.torrent.torrent.context.TorrentPeer;
|
||||
import net.torrent.torrent.piece.PieceSelector;
|
||||
import net.torrent.torrent.piece.RandomPieceSelector;
|
||||
|
||||
/**
|
||||
* This standard implementation of {@link TorrentPieceDownloadAlgorithm} chooses
|
||||
@@ -39,8 +38,6 @@ public class TorrentStdPieceDownloadAlgorithm implements
|
||||
* The torrent manager
|
||||
*/
|
||||
private final TorrentManager manager;
|
||||
// private final TorrentContext context;
|
||||
// private final Torrent torrent;
|
||||
|
||||
/**
|
||||
* This selector is used to find the next piece to be downloaded. Parts are
|
||||
@@ -61,12 +58,13 @@ public class TorrentStdPieceDownloadAlgorithm implements
|
||||
* @param manager
|
||||
* the torrent manager instance. With this object is possible to
|
||||
* retrieve current downloads/uploads and connections.
|
||||
* @param pieceSelector
|
||||
* the piece selector
|
||||
*/
|
||||
public TorrentStdPieceDownloadAlgorithm(TorrentManager manager) {
|
||||
public TorrentStdPieceDownloadAlgorithm(TorrentManager manager,
|
||||
PieceSelector pieceSelector) {
|
||||
this.manager = manager;
|
||||
// this.context = this.manager.getContext();
|
||||
// this.torrent = this.manager.getTorrent();
|
||||
selector = new RandomPieceSelector(manager);
|
||||
this.selector = pieceSelector;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,7 +45,7 @@ import net.torrent.torrent.context.TorrentPeer;
|
||||
import net.torrent.torrent.context.TorrentPeer.ChokingState;
|
||||
import net.torrent.torrent.context.TorrentPeer.InterestState;
|
||||
import net.torrent.torrent.context.TorrentPeerCapabilities.TorrentPeerCapability;
|
||||
import net.torrent.util.PeerCallback;
|
||||
import net.torrent.util.PeerWirePeerCallback;
|
||||
|
||||
import org.jboss.netty.channel.ChannelFuture;
|
||||
import org.jboss.netty.channel.ChannelHandlerContext;
|
||||
@@ -343,7 +343,7 @@ public class PeerWireAlgorithmHandler extends IdleStateAwareChannelHandler {
|
||||
|
||||
if (datastore.checksum(part.getPiece())) {
|
||||
manager.getContext().getBitfield().setPiece(part.getPiece(), true);
|
||||
manager.getPeerManager().executeActive(new PeerCallback() {
|
||||
manager.getPeerManager().executeActive(new PeerWirePeerCallback() {
|
||||
@Override
|
||||
public void callback(PeerWirePeer peer) {
|
||||
peer.have(part.getPiece().getIndex());
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.Set;
|
||||
import net.torrent.protocol.peerwire.PeerWirePeer;
|
||||
import net.torrent.torrent.context.TorrentContext;
|
||||
import net.torrent.torrent.context.TorrentPeer;
|
||||
import net.torrent.util.PeerCallback;
|
||||
import net.torrent.util.PeerWirePeerCallback;
|
||||
|
||||
import org.jboss.netty.channel.Channel;
|
||||
|
||||
@@ -140,21 +140,21 @@ public class PeerManager implements Iterable<PeerWirePeer> {
|
||||
return Collections.unmodifiableSet(inactivePeers.keySet());
|
||||
}
|
||||
|
||||
public void executeActive(PeerCallback callback) {
|
||||
public void executeActive(PeerWirePeerCallback callback) {
|
||||
for (final Entry<Channel, PeerWirePeer> entry : this.activePeers
|
||||
.entrySet()) {
|
||||
callback.callback(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void executeInactive(PeerCallback callback) {
|
||||
public void executeInactive(PeerWirePeerCallback callback) {
|
||||
for (final Entry<Channel, PeerWirePeer> entry : this.inactivePeers
|
||||
.entrySet()) {
|
||||
callback.callback(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public void execute(PeerCallback callback) {
|
||||
public void execute(PeerWirePeerCallback callback) {
|
||||
executeActive(callback);
|
||||
executeInactive(callback);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class TorrentContext {
|
||||
private final TorrentPeerCapabilities capabilites = new TorrentPeerCapabilities(
|
||||
TorrentPeerCapability.DHT, TorrentPeerCapability.FAST_PEERS);
|
||||
|
||||
private final Set<TorrentPeer> peers = new HashSet<TorrentPeer>();
|
||||
private final TorrentSwarm swarm = new TorrentSwarm(this);
|
||||
/**
|
||||
* Unknown peers does not have their IDs, consequently they cannot be
|
||||
* queried using their Id and must be done through IP.
|
||||
@@ -103,8 +103,8 @@ public class TorrentContext {
|
||||
*
|
||||
* @return the list of peers
|
||||
*/
|
||||
public Set<TorrentPeer> getPeers() {
|
||||
return Collections.unmodifiableSet(peers);
|
||||
public TorrentSwarm getSwarm() {
|
||||
return swarm;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,73 +116,15 @@ public class TorrentContext {
|
||||
return Collections.unmodifiableSet(unknownPeers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an peer by its PeerID
|
||||
*
|
||||
* @param peerId
|
||||
* the peer id
|
||||
* @return the found peer. Null if not found.
|
||||
*/
|
||||
public TorrentPeer getPeer(TorrentPeerID peerId) {
|
||||
for (final TorrentPeer peer : peers) {
|
||||
if (peer.getPeerID().equals(peerId))
|
||||
return peer;
|
||||
}
|
||||
return null;
|
||||
return swarm.getPeer(peerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an peer by its address
|
||||
*
|
||||
* @param address
|
||||
* the address
|
||||
* @return the found peer. Null if not found.
|
||||
*/
|
||||
public TorrentPeer getPeer(InetSocketAddress address) {
|
||||
for (final TorrentPeer peer : peers) {
|
||||
if (peer.getSocketAddress().equals(address))
|
||||
return peer;
|
||||
}
|
||||
return null;
|
||||
return swarm.getPeer(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup for a peer first by its id, then by address, if still not found,
|
||||
* creates a new entry.
|
||||
*
|
||||
* @param id
|
||||
* the peer id
|
||||
* @param address
|
||||
* the address
|
||||
* @return the found or newly created peer
|
||||
*/
|
||||
public TorrentPeer getPeer(TorrentPeerID id, InetSocketAddress address) {
|
||||
TorrentPeer peer = getPeer(id);
|
||||
if (peer == null) {
|
||||
peer = getPeer(address);
|
||||
if (peer != null) {
|
||||
if (peers.remove(peer))
|
||||
peer = peer.createWithID(id);
|
||||
} else {
|
||||
peer = new TorrentPeer(this, id, null);
|
||||
}
|
||||
peers.add(peer);
|
||||
}
|
||||
return peer;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this peer already exists, will update its IP.
|
||||
*
|
||||
* @param peerInfo
|
||||
* the peer info object, returned from the tracker
|
||||
*/
|
||||
public TorrentPeer addPeerByPeerInfo(PeerInfo peerInfo) {
|
||||
final TorrentPeerID id = TorrentPeerID.create(peerInfo.getPeerId());
|
||||
final InetSocketAddress address = new InetSocketAddress(
|
||||
peerInfo.getIp(), peerInfo.getPort());
|
||||
TorrentPeer peer = getPeer(id, address);
|
||||
peer.setSocketAddress(address);
|
||||
return peer;
|
||||
return swarm.getPeer(id, address);
|
||||
}
|
||||
}
|
||||
|
||||
175
src/main/java/net/torrent/torrent/context/TorrentSwarm.java
Normal file
175
src/main/java/net/torrent/torrent/context/TorrentSwarm.java
Normal file
@@ -0,0 +1,175 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package net.torrent.torrent.context;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.torrent.protocol.tracker.message.PeerListMessage.PeerInfo;
|
||||
import net.torrent.torrent.TorrentPiece;
|
||||
import net.torrent.util.SwarmCallback;
|
||||
|
||||
/**
|
||||
* An torrent swarm is an set of all connected peers.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com/">Rogiel Josias Sulzbach</a>
|
||||
*/
|
||||
public class TorrentSwarm implements Iterable<TorrentPeer> {
|
||||
/**
|
||||
* The torrent context
|
||||
*/
|
||||
private final TorrentContext context;
|
||||
|
||||
/**
|
||||
* The list of active peers
|
||||
*/
|
||||
private List<TorrentPeer> peers = new ArrayList<TorrentPeer>();
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param context
|
||||
* the torrent context
|
||||
*/
|
||||
public TorrentSwarm(final TorrentContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an given peer to the swarm
|
||||
*
|
||||
* @param peer
|
||||
* the peer
|
||||
* @return true if was not present in swarm
|
||||
*/
|
||||
public boolean add(TorrentPeer peer) {
|
||||
return this.peers.add(peer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an given peer from the swarm
|
||||
*
|
||||
* @param peer
|
||||
* the peer
|
||||
* @return true if peer was in swarm
|
||||
*/
|
||||
public boolean remove(TorrentPeer peer) {
|
||||
return this.peers.remove(peer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes an callback on each peer in the swarm
|
||||
*
|
||||
* @param callback
|
||||
* the callback
|
||||
*/
|
||||
public void execute(SwarmCallback callback) {
|
||||
for (final TorrentPeer peer : this) {
|
||||
callback.callback(peer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the peers which have the <tt>piece</tt>
|
||||
*
|
||||
* @param piece
|
||||
* the piece
|
||||
* @return list of peers with piece
|
||||
*/
|
||||
public List<TorrentPeer> getPeersWithPiece(TorrentPiece piece) {
|
||||
final List<TorrentPeer> hasPieces = new ArrayList<TorrentPeer>();
|
||||
for (final TorrentPeer peer : peers) {
|
||||
if (!peer.getBitfield().hasPiece(piece))
|
||||
continue;
|
||||
hasPieces.add(peer);
|
||||
}
|
||||
return hasPieces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an peer by its PeerID
|
||||
*
|
||||
* @param peerId
|
||||
* the peer id
|
||||
* @return the found peer. Null if not found.
|
||||
*/
|
||||
public TorrentPeer getPeer(TorrentPeerID peerId) {
|
||||
for (final TorrentPeer peer : peers) {
|
||||
if (peer.getPeerID().equals(peerId))
|
||||
return peer;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an peer by its address
|
||||
*
|
||||
* @param address
|
||||
* the address
|
||||
* @return the found peer. Null if not found.
|
||||
*/
|
||||
public TorrentPeer getPeer(InetSocketAddress address) {
|
||||
for (final TorrentPeer peer : peers) {
|
||||
if (peer.getSocketAddress().equals(address))
|
||||
return peer;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup for a peer first by its id, then by address, if still not found,
|
||||
* creates a new entry.
|
||||
*
|
||||
* @param id
|
||||
* the peer id
|
||||
* @param address
|
||||
* the address
|
||||
* @return the found or newly created peer
|
||||
*/
|
||||
public TorrentPeer getPeer(TorrentPeerID id, InetSocketAddress address) {
|
||||
TorrentPeer peer = getPeer(id);
|
||||
if (peer == null) {
|
||||
peer = getPeer(address);
|
||||
if (peer != null) {
|
||||
if (remove(peer))
|
||||
peer = peer.createWithID(id);
|
||||
} else {
|
||||
peer = new TorrentPeer(context, id, null);
|
||||
}
|
||||
add(peer);
|
||||
}
|
||||
return peer;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this peer already exists, will update its IP.
|
||||
*
|
||||
* @param peerInfo
|
||||
* the peer info object, returned from the tracker
|
||||
*/
|
||||
public TorrentPeer addPeerByPeerInfo(PeerInfo peerInfo) {
|
||||
final TorrentPeerID id = TorrentPeerID.create(peerInfo.getPeerId());
|
||||
final InetSocketAddress address = new InetSocketAddress(
|
||||
peerInfo.getIp(), peerInfo.getPort());
|
||||
TorrentPeer peer = getPeer(id, address);
|
||||
peer.setSocketAddress(address);
|
||||
return peer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<TorrentPeer> iterator() {
|
||||
return peers.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the torrent context
|
||||
*
|
||||
* @return the torrent context
|
||||
*/
|
||||
public TorrentContext getContext() {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
@@ -34,4 +34,11 @@ public interface PieceSelector {
|
||||
* @return the {@link TorrentPiece piece} selected for download.
|
||||
*/
|
||||
public TorrentPiece select(TorrentPeer peer);
|
||||
|
||||
/**
|
||||
* Return the amount of pieces available to select
|
||||
*
|
||||
* @return the amount of pieces available
|
||||
*/
|
||||
public int countPieces(TorrentPeer peer);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2011 Rogiel Josias Sulzbach
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.torrent.torrent.piece;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.torrent.protocol.peerwire.manager.TorrentManager;
|
||||
import net.torrent.torrent.TorrentPiece;
|
||||
import net.torrent.torrent.context.TorrentPeer;
|
||||
import net.torrent.torrent.piece.score.PieceRarenessScoreAlgorithm;
|
||||
import net.torrent.torrent.piece.score.ScoredPieceComparator;
|
||||
|
||||
/**
|
||||
* Select pieces in sequential order. Can be used for streaming purposes.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com/">Rogiel Josias Sulzbach</a>
|
||||
*/
|
||||
public class ScoredPieceSelector extends SortedListPieceSelector {
|
||||
/**
|
||||
* Sort again the list each <tt>n</tt> calls to {@link #select(TorrentPeer)}
|
||||
*/
|
||||
private static final int SORT_INTERVAL = 10;
|
||||
|
||||
/**
|
||||
* Call counter. Used to sort the list.
|
||||
*/
|
||||
private int calls = 0;
|
||||
|
||||
/**
|
||||
* The piece comparator
|
||||
*/
|
||||
private final ScoredPieceComparator comparator;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param manager
|
||||
* the torrent manager
|
||||
*/
|
||||
public ScoredPieceSelector(TorrentManager manager) {
|
||||
super(manager, Arrays.asList(manager.getTorrent().getPieces()));
|
||||
this.comparator = new ScoredPieceComparator(manager.getContext()
|
||||
.getSwarm(), new PieceRarenessScoreAlgorithm());
|
||||
// initial sort will be skipped because comparator is null.
|
||||
this.sort(pieces);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sort(List<TorrentPiece> pieces) {
|
||||
if (comparator != null)
|
||||
Collections.sort(pieces, comparator);
|
||||
System.out.println(pieces);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized TorrentPiece select(TorrentPeer peer) {
|
||||
if (calls % SORT_INTERVAL == 0)
|
||||
this.sort(pieces);
|
||||
calls++;
|
||||
return super.select(peer);
|
||||
}
|
||||
}
|
||||
@@ -32,11 +32,11 @@ public abstract class SortedListPieceSelector implements PieceSelector {
|
||||
/**
|
||||
* The torrent manager
|
||||
*/
|
||||
private final TorrentManager manager;
|
||||
protected final TorrentManager manager;
|
||||
/**
|
||||
* The sorted list of pieces
|
||||
*/
|
||||
private final List<TorrentPiece> pieces;
|
||||
protected final List<TorrentPiece> pieces;
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
@@ -53,6 +53,14 @@ public abstract class SortedListPieceSelector implements PieceSelector {
|
||||
this.sort(this.pieces);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the set using an implementation specific algorithm.
|
||||
*
|
||||
* @param pieces
|
||||
* the unsorted pieces list that will be sorted.
|
||||
*/
|
||||
protected abstract void sort(List<TorrentPiece> pieces);
|
||||
|
||||
@Override
|
||||
public synchronized TorrentPiece select(TorrentPeer peer) {
|
||||
for (int index = 0; index < pieces.size(); index++) {
|
||||
@@ -68,11 +76,19 @@ public abstract class SortedListPieceSelector implements PieceSelector {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the set using an implementation specific algorithm.
|
||||
*
|
||||
* @param pieces
|
||||
* the unsorted pieces list that will be sorted.
|
||||
*/
|
||||
protected abstract void sort(List<TorrentPiece> pieces);
|
||||
@Override
|
||||
public int countPieces(TorrentPeer peer) {
|
||||
int count = 0;
|
||||
for (int index = 0; index < pieces.size(); index++) {
|
||||
final TorrentPiece piece = pieces.get(index);
|
||||
if (manager.getContext().getBitfield().hasPiece(piece))
|
||||
continue;
|
||||
if (!peer.getBitfield().hasPiece(piece))
|
||||
continue;
|
||||
if (manager.getDownloadManager().isDownloading(piece))
|
||||
continue;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package net.torrent.torrent.piece.score;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import net.torrent.torrent.TorrentPiece;
|
||||
import net.torrent.torrent.context.TorrentPeer;
|
||||
import net.torrent.torrent.context.TorrentSwarm;
|
||||
import net.torrent.util.SwarmCallback;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com/">Rogiel Josias Sulzbach</a>
|
||||
*/
|
||||
public class PieceRarenessScoreAlgorithm implements PieceScoreAlgorithm {
|
||||
@Override
|
||||
public int calculate(TorrentSwarm swarm, final TorrentPiece piece) {
|
||||
final AtomicInteger score = new AtomicInteger();
|
||||
swarm.execute(new SwarmCallback() {
|
||||
@Override
|
||||
public void callback(TorrentPeer peer) {
|
||||
int peerScore = (int) (Math.random() * 10); // bit of randomness
|
||||
if (!peer.isAccessible()) {
|
||||
peerScore += 100;
|
||||
}
|
||||
if (!peer.getBitfield().hasPiece(piece))
|
||||
peerScore += 1000;
|
||||
score.addAndGet(peerScore);
|
||||
}
|
||||
});
|
||||
return score.get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package net.torrent.torrent.piece.score;
|
||||
|
||||
import net.torrent.torrent.TorrentPiece;
|
||||
import net.torrent.torrent.context.TorrentSwarm;
|
||||
|
||||
/**
|
||||
* Computes the score of an piece inside the swarm.
|
||||
* <p>
|
||||
* Pieces with higher scores will be more suitable to download than others.
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com/">Rogiel Josias Sulzbach</a>
|
||||
*/
|
||||
public interface PieceScoreAlgorithm {
|
||||
/**
|
||||
* Computes the score of an piece inside an swarm.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int calculate(TorrentSwarm swarm, TorrentPiece piece);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package net.torrent.torrent.piece.score;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import net.torrent.torrent.TorrentPiece;
|
||||
import net.torrent.torrent.context.TorrentSwarm;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com/">Rogiel Josias Sulzbach</a>
|
||||
*/
|
||||
public class ScoredPieceComparator implements Comparator<TorrentPiece> {
|
||||
private final PieceScoreAlgorithm score;
|
||||
private final TorrentSwarm swarm;
|
||||
|
||||
public ScoredPieceComparator(TorrentSwarm swarm, PieceScoreAlgorithm score) {
|
||||
this.swarm = swarm;
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(TorrentPiece piece1, TorrentPiece piece2) {
|
||||
return score.calculate(swarm, piece1) - score.calculate(swarm, piece2);
|
||||
}
|
||||
}
|
||||
34
src/main/java/net/torrent/util/PeerWirePeerCallback.java
Normal file
34
src/main/java/net/torrent/util/PeerWirePeerCallback.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2011 Rogiel Josias Sulzbach
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package net.torrent.util;
|
||||
|
||||
import net.torrent.protocol.peerwire.PeerWirePeer;
|
||||
import net.torrent.protocol.peerwire.manager.PeerManager;
|
||||
|
||||
/**
|
||||
* Callback used in {@link PeerManager#execute(PeerCallback)}
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com/">Rogiel Josias Sulzbach</a>
|
||||
*/
|
||||
public interface PeerWirePeerCallback {
|
||||
/**
|
||||
* Execute the desired action for <tt>peer</tt>
|
||||
*
|
||||
* @param peer
|
||||
* the peer
|
||||
*/
|
||||
void callback(PeerWirePeer peer);
|
||||
}
|
||||
22
src/main/java/net/torrent/util/SwarmCallback.java
Normal file
22
src/main/java/net/torrent/util/SwarmCallback.java
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package net.torrent.util;
|
||||
|
||||
import net.torrent.torrent.context.TorrentPeer;
|
||||
import net.torrent.torrent.context.TorrentSwarm;
|
||||
|
||||
/**
|
||||
* Callback used in {@link TorrentSwarm#execute(SwarmCallback)}
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com/">Rogiel Josias Sulzbach</a>
|
||||
*/
|
||||
public interface SwarmCallback {
|
||||
/**
|
||||
* Execute the desired action for <tt>peer</tt>
|
||||
*
|
||||
* @param peer
|
||||
* the peer
|
||||
*/
|
||||
void callback(TorrentPeer peer);
|
||||
}
|
||||
Reference in New Issue
Block a user