From 0f321f1597f68ef14cc13c20289fcabc1a4cede6 Mon Sep 17 00:00:00 2001 From: zzz Date: Tue, 22 May 2012 18:19:52 +0000 Subject: [PATCH] - Refactor tracker map --- .../src/org/klomp/snark/SnarkManager.java | 64 +++++++++++++----- .../java/src/org/klomp/snark/Tracker.java | 28 ++++++++ .../org/klomp/snark/web/I2PSnarkServlet.java | 66 +++++++------------ history.txt | 6 ++ .../src/net/i2p/router/RouterVersion.java | 2 +- 5 files changed, 107 insertions(+), 59 deletions(-) create mode 100644 apps/i2psnark/java/src/org/klomp/snark/Tracker.java diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java index 36db296a29..107ac43ec5 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java +++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java @@ -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 _trackerMap; + private final Map _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 getTrackers() { + public Map getTrackerMap() { return _trackerMap; } + /** + * Unsorted, do not modify + */ + public Collection getTrackers() { + return _trackerMap.values(); + } + + /** + * Sorted copy + * @since 0.9.1 + */ + public List getSortedTrackers() { + List 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(",", ","); String url = toks[i+1].trim().replace(",", ","); - 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 e : _trackerMap.entrySet()) { + for (Map.Entry e : _trackerMap.entrySet()) { if (comma) buf.append(','); else comma = true; - buf.append(e.getKey().replace(",", ",")).append(',').append(e.getValue().replace(",", ",")); + Tracker t = e.getValue(); + buf.append(e.getKey().replace(",", ",")).append(',').append(t.announceURL.replace(",", ",")); + 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 { - public int compare(String l, String r) { - return l.toLowerCase().compareTo(r.toLowerCase()); + private static class IgnoreCaseComparator implements Comparator { + public int compare(Tracker l, Tracker r) { + return l.name.toLowerCase().compareTo(r.name.toLowerCase()); } } } diff --git a/apps/i2psnark/java/src/org/klomp/snark/Tracker.java b/apps/i2psnark/java/src/org/klomp/snark/Tracker.java new file mode 100644 index 0000000000..995130ed40 --- /dev/null +++ b/apps/i2psnark/java/src/org/klomp/snark/Tracker.java @@ -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"); + } +} diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index b012d9b5ee..01dd3a4f01 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -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(""); out.write("
"); + List sortedTrackers = null; if (isConfigure) { out.write("\n"); @@ -286,7 +283,7 @@ public class I2PSnarkServlet extends DefaultServlet { // end of mainsection div out.write("
\n"); writeAddForm(out, req); - writeSeedForm(out, req); + writeSeedForm(out, req, sortedTrackers); writeConfigLink(out); // end of lowersection div out.write("
\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 trackers = _manager.getTrackers(); + Map 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("=", "="); if (name.length() > 0 && hurl.startsWith("http://") && aurl.startsWith("http://")) { - Map trackers = _manager.getTrackers(); - trackers.put(name, aurl + '=' + hurl); + Map 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 trackers = _manager.getTrackers(); - for (Map.Entry 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(""); } - private void writeSeedForm(PrintWriter out, HttpServletRequest req) throws IOException { + private void writeSeedForm(PrintWriter out, HttpServletRequest req, List 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("\n"); - Map trackers = _manager.getTrackers(); - for (Map.Entry entry : trackers.entrySet()) { - String name = entry.getKey(); - String announceURL = entry.getValue(); - int e = announceURL.indexOf('='); - if (e > 0) - announceURL = announceURL.substring(0, e).replace("=", "="); + for (Tracker t : sortedTrackers) { + String name = t.name; + String announceURL = t.announceURL.replace("=", "="); if (announceURL.equals(_lastAnnounceURL)) announceURL += "\" selected=\"selected"; out.write("\t\n"); @@ -1605,15 +1594,10 @@ public class I2PSnarkServlet extends DefaultServlet { .append("") .append(_("Announce URL")) .append("\n"); - Map trackers = _manager.getTrackers(); - for (Map.Entry 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("=", "="); + for (Tracker t : _manager.getSortedTrackers()) { + String name = t.name; + String homeURL = t.baseURL; + String announceURL = t.announceURL.replace("=", "="); buf.append("" + "").append(name) diff --git a/history.txt b/history.txt index 96ab4bcb8d..a29368b6cb 100644 --- a/history.txt +++ b/history.txt @@ -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: diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index 0725033fa6..f6e6df3a5c 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 = "";