- Refactor tracker map

This commit is contained in:
zzz
2012-05-22 18:19:52 +00:00
parent 10872f751e
commit 0f321f1597
5 changed files with 107 additions and 59 deletions

View File

@ -8,6 +8,7 @@ import java.io.FilenameFilter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@ -18,7 +19,6 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
@ -58,7 +58,7 @@ public class SnarkManager implements Snark.CompleteListener {
private ConnectionAcceptor _connectionAcceptor;
private Thread _monitor;
private volatile boolean _running;
private final Map<String, String> _trackerMap;
private final Map<String, Tracker> _trackerMap;
public static final String PROP_I2CP_HOST = "i2psnark.i2cpHost";
public static final String PROP_I2CP_PORT = "i2psnark.i2cpPort";
@ -130,7 +130,7 @@ public class SnarkManager implements Snark.CompleteListener {
_configFile = new File(CONFIG_FILE);
if (!_configFile.isAbsolute())
_configFile = new File(_context.getConfigDir(), CONFIG_FILE);
_trackerMap = Collections.synchronizedMap(new TreeMap(new IgnoreCaseComparator()));
_trackerMap = new ConcurrentHashMap(4);
loadConfig(null);
}
@ -1404,40 +1404,67 @@ public class SnarkManager implements Snark.CompleteListener {
}
/**
* Sorted map of name to announceURL=baseURL
* Unsorted map of name to Tracker object
* Modifiable, not a copy
* @since 0.9.1
*/
public Map<String, String> getTrackers() {
public Map<String, Tracker> getTrackerMap() {
return _trackerMap;
}
/**
* Unsorted, do not modify
*/
public Collection<Tracker> getTrackers() {
return _trackerMap.values();
}
/**
* Sorted copy
* @since 0.9.1
*/
public List<Tracker> getSortedTrackers() {
List<Tracker> rv = new ArrayList(_trackerMap.values());
Collections.sort(rv, new IgnoreCaseComparator());
return rv;
}
/** @since 0.9 */
private void initTrackerMap() {
String trackers = _config.getProperty(PROP_TRACKERS);
if ( (trackers == null) || (trackers.trim().length() <= 0) )
trackers = _context.getProperty(PROP_TRACKERS);
_trackerMap.clear();
if ( (trackers == null) || (trackers.trim().length() <= 0) ) {
for (int i = 0; i < DEFAULT_TRACKERS.length; i += 2)
_trackerMap.put(DEFAULT_TRACKERS[i], DEFAULT_TRACKERS[i+1]);
setDefaultTrackerMap(true);
} else {
String[] toks = trackers.split(",");
for (int i = 0; i < toks.length; i += 2) {
String name = toks[i].trim().replace("&#44;", ",");
String url = toks[i+1].trim().replace("&#44;", ",");
if ( (name.length() > 0) && (url.length() > 0) )
_trackerMap.put(name, url);
if ( (name.length() > 0) && (url.length() > 0) ) {
String urls[] = DEFAULT_TRACKERS[i+1].split("=", 2);
String url2 = urls.length > 1 ? urls[1] : null;
_trackerMap.put(name, new Tracker(name, urls[0], url2));
}
}
}
}
/** @since 0.9 */
public void setDefaultTrackerMap() {
setDefaultTrackerMap(true);
}
/** @since 0.9.1 */
private void setDefaultTrackerMap(boolean save) {
_trackerMap.clear();
for (int i = 0; i < DEFAULT_TRACKERS.length; i += 2) {
_trackerMap.put(DEFAULT_TRACKERS[i], DEFAULT_TRACKERS[i+1]);
String name = DEFAULT_TRACKERS[i];
String urls[] = DEFAULT_TRACKERS[i+1].split("=", 2);
String url2 = urls.length > 1 ? urls[1] : null;
_trackerMap.put(name, new Tracker(name, urls[0], url2));
}
if (_config.remove(PROP_TRACKERS) != null) {
if (save && _config.remove(PROP_TRACKERS) != null) {
saveConfig();
}
}
@ -1446,12 +1473,15 @@ public class SnarkManager implements Snark.CompleteListener {
public void saveTrackerMap() {
StringBuilder buf = new StringBuilder(2048);
boolean comma = false;
for (Map.Entry<String, String> e : _trackerMap.entrySet()) {
for (Map.Entry<String, Tracker> e : _trackerMap.entrySet()) {
if (comma)
buf.append(',');
else
comma = true;
buf.append(e.getKey().replace(",", "&#44;")).append(',').append(e.getValue().replace(",", "&#44;"));
Tracker t = e.getValue();
buf.append(e.getKey().replace(",", "&#44;")).append(',').append(t.announceURL.replace(",", "&#44;"));
if (t.baseURL != null)
buf.append('=').append(t.baseURL);
}
_config.setProperty(PROP_TRACKERS, buf.toString());
saveConfig();
@ -1481,9 +1511,9 @@ public class SnarkManager implements Snark.CompleteListener {
* ignore case, current locale
* @since 0.9
*/
private static class IgnoreCaseComparator implements Comparator<String> {
public int compare(String l, String r) {
return l.toLowerCase().compareTo(r.toLowerCase());
private static class IgnoreCaseComparator implements Comparator<Tracker> {
public int compare(Tracker l, Tracker r) {
return l.name.toLowerCase().compareTo(r.name.toLowerCase());
}
}
}

View File

@ -0,0 +1,28 @@
/*
* Released into the public domain
* with no warranty of any kind, either expressed or implied.
*/
package org.klomp.snark;
/**
* A structure for known trackers
*
* @since 0.9.1
*/
public class Tracker {
public final String name;
public final String announceURL;
public final String baseURL;
public final boolean supportsDetails;
/**
* @param baseURL The web site, may be null
*/
public Tracker(String name, String announceURL, String baseURL) {
this.name = name;
this.announceURL = announceURL;
this.baseURL = baseURL;
this.supportsDetails = name.contains("tracker2.postman.i2p");
}
}

View File

@ -37,6 +37,7 @@ import org.klomp.snark.Peer;
import org.klomp.snark.Snark;
import org.klomp.snark.SnarkManager;
import org.klomp.snark.Storage;
import org.klomp.snark.Tracker;
import org.klomp.snark.TrackerClient;
import org.mortbay.jetty.servlet.DefaultServlet;
@ -239,6 +240,7 @@ public class I2PSnarkServlet extends DefaultServlet {
else
out.write("<body onload=\"initAjax()\">");
out.write("<center>");
List<Tracker> sortedTrackers = null;
if (isConfigure) {
out.write("<div class=\"snarknavbar\"><a href=\"/i2psnark/\" title=\"");
out.write(_("Torrents"));
@ -256,16 +258,11 @@ public class I2PSnarkServlet extends DefaultServlet {
out.write(_("Forum"));
out.write("</a>\n");
Map trackers = _manager.getTrackers();
for (Iterator iter = trackers.entrySet().iterator(); iter.hasNext(); ) {
Map.Entry entry = (Map.Entry)iter.next();
String name = (String)entry.getKey();
String baseURL = (String)entry.getValue();
int e = baseURL.indexOf('=');
if (e < 0)
sortedTrackers = _manager.getSortedTrackers();
for (Tracker t : sortedTrackers) {
if (t.baseURL == null || !t.baseURL.startsWith("http"))
continue;
baseURL = baseURL.substring(e + 1);
out.write(" <a href=\"" + baseURL + "\" class=\"snarkRefresh\" target=\"_blank\">" + name + "</a>");
out.write(" <a href=\"" + t.baseURL + "\" class=\"snarkRefresh\" target=\"_blank\">" + t.name + "</a>");
}
}
out.write("</div>\n");
@ -286,7 +283,7 @@ public class I2PSnarkServlet extends DefaultServlet {
// end of mainsection div
out.write("</div><div id=\"lowersection\">\n");
writeAddForm(out, req);
writeSeedForm(out, req);
writeSeedForm(out, req, sortedTrackers);
writeConfigLink(out);
// end of lowersection div
out.write("</div>\n");
@ -773,7 +770,7 @@ public class I2PSnarkServlet extends DefaultServlet {
private void processTrackerForm(String action, HttpServletRequest req) {
if (action.equals(_("Delete selected"))) {
boolean changed = false;
Map<String, String> trackers = _manager.getTrackers();
Map<String, Tracker> trackers = _manager.getTrackerMap();
Enumeration e = req.getParameterNames();
while (e.hasMoreElements()) {
Object o = e.nextElement();
@ -800,8 +797,8 @@ public class I2PSnarkServlet extends DefaultServlet {
hurl = hurl.trim();
aurl = aurl.trim().replace("=", "&#61;");
if (name.length() > 0 && hurl.startsWith("http://") && aurl.startsWith("http://")) {
Map<String, String> trackers = _manager.getTrackers();
trackers.put(name, aurl + '=' + hurl);
Map<String, Tracker> trackers = _manager.getTrackerMap();
trackers.put(name, new Tracker(name, aurl, hurl));
_manager.saveTrackerMap();
} else {
_manager.addMessage(_("Enter valid tracker name and URLs"));
@ -1271,18 +1268,14 @@ public class I2PSnarkServlet extends DefaultServlet {
if (announce != null && (announce.startsWith("http://YRgrgTLG") || announce.startsWith("http://8EoJZIKr") ||
announce.startsWith("http://lnQ6yoBT") || announce.startsWith("http://tracker2.postman.i2p/") ||
announce.startsWith("http://ahsplxkbhemefwvvml7qovzl5a2b5xo5i7lyai7ntdunvcyfdtna.b32.i2p/"))) {
Map<String, String> trackers = _manager.getTrackers();
for (Map.Entry<String, String> entry : trackers.entrySet()) {
String baseURL = entry.getValue();
if (!(baseURL.startsWith(announce) || // vvv hack for non-b64 announce in list vvv
(announce.startsWith("http://lnQ6yoBT") && baseURL.startsWith("http://tracker2.postman.i2p/")) ||
(announce.startsWith("http://ahsplxkbhemefwvvml7qovzl5a2b5xo5i7lyai7ntdunvcyfdtna.b32.i2p/") && baseURL.startsWith("http://tracker2.postman.i2p/"))))
for (Tracker t : _manager.getTrackers()) {
String aURL = t.announceURL;
if (!(aURL.startsWith(announce) || // vvv hack for non-b64 announce in list vvv
(announce.startsWith("http://lnQ6yoBT") && aURL.startsWith("http://tracker2.postman.i2p/")) ||
(announce.startsWith("http://ahsplxkbhemefwvvml7qovzl5a2b5xo5i7lyai7ntdunvcyfdtna.b32.i2p/") && aURL.startsWith("http://tracker2.postman.i2p/"))))
continue;
int e = baseURL.indexOf('=');
if (e < 0)
continue;
baseURL = baseURL.substring(e + 1);
String name = entry.getKey();
String baseURL = t.baseURL;
String name = t.name;
StringBuilder buf = new StringBuilder(128);
buf.append("<a href=\"").append(baseURL).append("details.php?dllist=1&amp;filelist=1&amp;info_hash=")
.append(TrackerClient.urlencode(infohash))
@ -1336,7 +1329,7 @@ public class I2PSnarkServlet extends DefaultServlet {
out.write("</div></form></div>");
}
private void writeSeedForm(PrintWriter out, HttpServletRequest req) throws IOException {
private void writeSeedForm(PrintWriter out, HttpServletRequest req, List<Tracker> sortedTrackers) throws IOException {
String baseFile = req.getParameter("baseFile");
if (baseFile == null || baseFile.trim().length() <= 0)
baseFile = "";
@ -1372,13 +1365,9 @@ public class I2PSnarkServlet extends DefaultServlet {
//out.write(_("Open trackers and DHT only"));
out.write(_("Open trackers only"));
out.write("</option>\n");
Map<String, String> trackers = _manager.getTrackers();
for (Map.Entry<String, String> entry : trackers.entrySet()) {
String name = entry.getKey();
String announceURL = entry.getValue();
int e = announceURL.indexOf('=');
if (e > 0)
announceURL = announceURL.substring(0, e).replace("&#61;", "=");
for (Tracker t : sortedTrackers) {
String name = t.name;
String announceURL = t.announceURL.replace("&#61;", "=");
if (announceURL.equals(_lastAnnounceURL))
announceURL += "\" selected=\"selected";
out.write("\t<option value=\"" + announceURL + "\">" + name + "</option>\n");
@ -1605,15 +1594,10 @@ public class I2PSnarkServlet extends DefaultServlet {
.append("</th><th>")
.append(_("Announce URL"))
.append("</th></tr>\n");
Map<String, String> trackers = _manager.getTrackers();
for (Map.Entry<String, String> entry : trackers.entrySet()) {
String name = entry.getKey();
String announceURL = entry.getValue();
int e = announceURL.indexOf('=');
if (e <= 0)
continue;
String homeURL = announceURL.substring(e + 1);
announceURL = announceURL.substring(0, e).replace("&#61;", "=");
for (Tracker t : _manager.getSortedTrackers()) {
String name = t.name;
String homeURL = t.baseURL;
String announceURL = t.announceURL.replace("&#61;", "=");
buf.append("<tr><td align=\"center\"><input type=\"checkbox\" class=\"optbox\" name=\"delete_")
.append(name).append("\">" +
"</td><td align=\"left\">").append(name)

View File

@ -1,3 +1,9 @@
2012-05-22 zzz
* i2psnark:
- Refactor tracker map
- Prevent torrent shutdown when changing file priority to skip
* RoutingKeyModifier: Update after large clock shift
2012-05-20 zzz
* Console: Add full file path to thread dump message
* i2psnark:

View File

@ -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 = "";