implement synchronized Tracker structure
This commit is contained in:
parent
534f827afc
commit
7f75a1ac77
4 changed files with 124 additions and 2 deletions
|
|
@ -31,7 +31,7 @@ public class Torrent {
|
|||
}
|
||||
}
|
||||
|
||||
public <T extends Collection<Peer>> void updatePeers(T src) {
|
||||
public <T extends Collection<Peer>> void putPeers(T src) {
|
||||
for (Peer peer : src) {
|
||||
peers.put(peer);
|
||||
}
|
||||
48
src/main/java/com/mykola2312/retracker/tracker/Tracker.java
Normal file
48
src/main/java/com/mykola2312/retracker/tracker/Tracker.java
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
package com.mykola2312.retracker.tracker;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/* Tracker meant to be called from multiple running threads,
|
||||
* so thread-safety ensured by synchronized methods.
|
||||
*/
|
||||
public class Tracker {
|
||||
private HashMap<InfoHash, Torrent> torrents = new HashMap<InfoHash, Torrent>();
|
||||
|
||||
/* Adds peer to torrent's PeerSet. If no such Torrent present,
|
||||
* creates the Torrent.
|
||||
*/
|
||||
public synchronized void announcePeer(InfoHash infoHash, Peer peer) {
|
||||
Torrent torrent = torrents.get(infoHash);
|
||||
if (torrent != null) {
|
||||
torrent.putPeers(List.of(peer));
|
||||
} else {
|
||||
// create torrent and initiate PeerSet with first announced peer
|
||||
torrent = new Torrent(infoHash, peer);
|
||||
torrents.put(torrent.getInfoHash(), torrent);
|
||||
}
|
||||
}
|
||||
|
||||
/* Adds multiple peers to torrent. If no such Torrent present,
|
||||
* creates the torrent.
|
||||
*/
|
||||
public synchronized <T extends Collection<Peer>> void announcePeers(InfoHash infoHash, T src) {
|
||||
Torrent torrent = torrents.get(infoHash);
|
||||
if (torrent != null) {
|
||||
torrent.putPeers(src);
|
||||
} else {
|
||||
torrent = new Torrent(infoHash);
|
||||
torrent.putPeers(src);
|
||||
torrents.put(torrent.getInfoHash(), torrent);
|
||||
}
|
||||
}
|
||||
|
||||
// Get list of peers at this very moment.
|
||||
public synchronized <T extends Collection<Peer>> void getPeers(InfoHash infoHash, T dst) {
|
||||
Torrent torrent = torrents.get(infoHash);
|
||||
if (torrent != null) {
|
||||
torrent.copyPeers(dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ public class TorrentTest {
|
|||
|
||||
List<Peer> src = Arrays.asList(new Peer(newAddress("127.0.0.1", 1337)),
|
||||
new Peer(newAddress("127.0.0.1", 1338)));
|
||||
torrent.updatePeers(src);
|
||||
torrent.putPeers(src);
|
||||
{
|
||||
ArrayList<Peer> copy = new ArrayList<Peer>();
|
||||
torrent.copyPeers(copy);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
package com.mykola2312.retracker.tracker;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class TrackerTest {
|
||||
private static InetSocketAddress newAddress(String addr, int port) throws UnknownHostException {
|
||||
return new InetSocketAddress(InetAddress.getByName(addr), port);
|
||||
}
|
||||
|
||||
class TrackerJob implements Runnable {
|
||||
private Tracker tracker;
|
||||
private InfoHash infoHash;
|
||||
private Peer peer;
|
||||
|
||||
public TrackerJob(Tracker tracker, InfoHash infoHash, Peer peer) {
|
||||
this.tracker = tracker;
|
||||
this.infoHash = infoHash;
|
||||
this.peer = peer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
tracker.announcePeer(infoHash, peer);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrackerPutAndGet() throws Exception {
|
||||
final InfoHash infoHash = new InfoHash();
|
||||
infoHash.fromString("360775c6629eb06e60d90201aed1b7bc49a1ce16");
|
||||
|
||||
Tracker tracker = new Tracker();
|
||||
|
||||
ArrayList<Thread> threads = new ArrayList<Thread>();
|
||||
for (int i = 0; i < 32; i++) {
|
||||
TrackerJob job = new TrackerJob(tracker, infoHash,
|
||||
new Peer(newAddress("127.0.0.1", 1337 + i)));
|
||||
Thread thread = new Thread(job);
|
||||
thread.start();
|
||||
threads.add(thread);
|
||||
|
||||
}
|
||||
|
||||
// wait for all threads to finish
|
||||
for (Thread thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
|
||||
ArrayList<Peer> peers = new ArrayList<Peer>(32);
|
||||
tracker.getPeers(infoHash, peers);
|
||||
|
||||
assertEquals(32, peers.size());
|
||||
|
||||
// check if every port present
|
||||
for (int i = 0; i < 32; i++) {
|
||||
int port = 1337 + i;
|
||||
boolean peerPortPresent = false;
|
||||
for (Peer peer : peers) {
|
||||
if (peer.getAddress().getPort() == port) {
|
||||
peerPortPresent = true;
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(true, peerPortPresent);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue