Pluck of revision 45a25185236e38606e761060427ee8fa60144a8c from branch i2p.i2p.zzz.test
--------------------------------------------------------------------------------------- * netdb.jsp: Add country chart at bottom, clean up version chart
This commit is contained in:
42
core/java/src/net/i2p/util/ObjectCounter.java
Normal file
42
core/java/src/net/i2p/util/ObjectCounter.java
Normal file
@ -0,0 +1,42 @@
|
||||
package net.i2p.util;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Count things.
|
||||
*
|
||||
* @author zzz
|
||||
*/
|
||||
public class ObjectCounter<K> {
|
||||
private ConcurrentHashMap<K, Integer> _map;
|
||||
public ObjectCounter() {
|
||||
_map = new ConcurrentHashMap();
|
||||
}
|
||||
/**
|
||||
* Add one.
|
||||
* Not perfectly concurrent, new AtomicInteger(1) would be better,
|
||||
* at the cost of some object churn.
|
||||
*/
|
||||
public void increment(K h) {
|
||||
Integer i = _map.putIfAbsent(h, Integer.valueOf(1));
|
||||
if (i != null)
|
||||
_map.put(h, Integer.valueOf(i.intValue() + 1));
|
||||
}
|
||||
/**
|
||||
* @return current count
|
||||
*/
|
||||
public int count(K h) {
|
||||
Integer i = _map.get(h);
|
||||
if (i != null)
|
||||
return i.intValue();
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* @return set of objects with counts > 0
|
||||
*/
|
||||
public Set<K> objects() {
|
||||
return _map.keySet();
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ public abstract class CommSystemFacade implements Service {
|
||||
public byte[] getIP(Hash dest) { return null; }
|
||||
public void queueLookup(byte[] ip) {}
|
||||
public String getCountry(Hash peer) { return null; }
|
||||
public String getCountryName(String code) { return code; }
|
||||
public String renderPeerHTML(Hash peer) { return null; }
|
||||
|
||||
/**
|
||||
|
@ -10,12 +10,15 @@ package net.i2p.router.networkdb.kademlia;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
@ -42,6 +45,7 @@ import net.i2p.router.networkdb.DatabaseStoreMessageHandler;
|
||||
import net.i2p.router.networkdb.PublishLocalRouterInfoJob;
|
||||
import net.i2p.router.peermanager.PeerProfile;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.ObjectCounter;
|
||||
|
||||
/**
|
||||
* Kademlia based version of the network database
|
||||
@ -999,8 +1003,8 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
|
||||
/* coreVersion to Map of routerVersion to Integer */
|
||||
Map versions = new TreeMap();
|
||||
ObjectCounter<String> versions = new ObjectCounter();
|
||||
ObjectCounter<String> countries = new ObjectCounter();
|
||||
|
||||
Set routers = new TreeSet(new RouterInfoComparator());
|
||||
routers.addAll(getRouters());
|
||||
@ -1012,40 +1016,47 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
|
||||
renderRouterInfo(buf, ri, false, full);
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
String coreVersion = ri.getOption("coreVersion");
|
||||
String routerVersion = ri.getOption("router.version");
|
||||
if ( (coreVersion != null) && (routerVersion != null) ) {
|
||||
Map routerVersions = (Map)versions.get(coreVersion);
|
||||
if (routerVersions == null) {
|
||||
routerVersions = new TreeMap();
|
||||
versions.put(coreVersion, routerVersions);
|
||||
}
|
||||
Integer val = (Integer)routerVersions.get(routerVersion);
|
||||
if (val == null)
|
||||
routerVersions.put(routerVersion, Integer.valueOf(1));
|
||||
else
|
||||
routerVersions.put(routerVersion, Integer.valueOf(val.intValue() + 1));
|
||||
}
|
||||
if (routerVersion != null)
|
||||
versions.increment(routerVersion);
|
||||
String country = _context.commSystem().getCountry(key);
|
||||
if(country != null)
|
||||
countries.increment(country);
|
||||
}
|
||||
}
|
||||
|
||||
if (versions.size() > 0) {
|
||||
buf.append("<table border=\"0\" cellspacing=\"30\"><tr><td valign=\"top\">");
|
||||
List<String> versionList = new ArrayList(versions.objects());
|
||||
if (versionList.size() > 0) {
|
||||
Collections.sort(versionList, Collections.reverseOrder());
|
||||
buf.append("<table border=\"1\">\n");
|
||||
buf.append("<tr><td><b>Core version</b></td><td><b>Router version</b></td><td><b>Number</b></td></tr>\n");
|
||||
for (Iterator iter = versions.entrySet().iterator(); iter.hasNext(); ) {
|
||||
Map.Entry entry = (Map.Entry)iter.next();
|
||||
String coreVersion = (String)entry.getKey();
|
||||
Map routerVersions = (Map)entry.getValue();
|
||||
for (Iterator routerIter = routerVersions.keySet().iterator(); routerIter.hasNext(); ) {
|
||||
String routerVersion = (String)routerIter.next();
|
||||
Integer num = (Integer)routerVersions.get(routerVersion);
|
||||
buf.append("<tr><td>").append(DataHelper.stripHTML(coreVersion));
|
||||
buf.append("</td><td>").append(DataHelper.stripHTML(routerVersion));
|
||||
buf.append("</td><td>").append(num.intValue()).append("</td></tr>\n");
|
||||
}
|
||||
buf.append("<tr><th>Version</th><th>Count</th></tr>\n");
|
||||
for (String routerVersion : versionList) {
|
||||
int num = versions.count(routerVersion);
|
||||
buf.append("<tr><td>").append(DataHelper.stripHTML(routerVersion));
|
||||
buf.append("</td><td align=\"right\">").append(num).append("</td></tr>\n");
|
||||
}
|
||||
buf.append("</table>\n");
|
||||
}
|
||||
buf.append("</td><td valign=\"top\">");
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
|
||||
List<String> countryList = new ArrayList(countries.objects());
|
||||
if (countryList.size() > 0) {
|
||||
Collections.sort(countryList);
|
||||
buf.append("<table border=\"1\">\n");
|
||||
buf.append("<tr><th>Country</th><th>Count</th></tr>\n");
|
||||
for (String country : countryList) {
|
||||
int num = countries.count(country);
|
||||
buf.append("<tr><td><img alt=\"").append(country.toUpperCase()).append("\"");
|
||||
buf.append(" src=\"/flags.jsp?c=").append(country).append("\"> ");
|
||||
buf.append(_context.commSystem().getCountryName(country));
|
||||
buf.append("</td><td align=\"right\">").append(num).append("</td></tr>\n");
|
||||
}
|
||||
buf.append("</table>\n");
|
||||
}
|
||||
buf.append("</td></tr></table>");
|
||||
out.write(buf.toString());
|
||||
out.flush();
|
||||
}
|
||||
|
@ -435,6 +435,16 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||
return props.getProperty("host");
|
||||
}
|
||||
|
||||
/** full name for a country code, or the code if we don't know the name */
|
||||
public String getCountryName(String c) {
|
||||
if (_geoIP == null)
|
||||
return c;
|
||||
String n = _geoIP.fullName(c);
|
||||
if (n == null)
|
||||
return c;
|
||||
return n;
|
||||
}
|
||||
|
||||
/** Provide a consistent "look" for displaying router IDs in the console */
|
||||
public String renderPeerHTML(Hash peer) {
|
||||
String h = peer.toBase64().substring(0, 4);
|
||||
@ -442,11 +452,7 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||
String c = getCountry(peer);
|
||||
if (c != null) {
|
||||
buf.append("<img alt=\"").append(c.toUpperCase()).append("\" title=\"");
|
||||
String n = _geoIP.fullName(c);
|
||||
if (n != null)
|
||||
buf.append(n);
|
||||
else
|
||||
buf.append(c);
|
||||
buf.append(getCountryName(c));
|
||||
buf.append("\" src=\"/flags.jsp?c=").append(c).append("\"> ");
|
||||
}
|
||||
buf.append("<tt><font size=\"+1\">");
|
||||
|
@ -29,6 +29,7 @@ import net.i2p.router.tunnel.HopConfig;
|
||||
import net.i2p.stat.RateStat;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.ObjectCounter;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -588,15 +589,15 @@ public class TunnelPoolManager implements TunnelManagerFacade {
|
||||
|
||||
private void renderPeers(Writer out) throws IOException {
|
||||
// count up the peers in the local pools
|
||||
HashCounter lc = new HashCounter();
|
||||
ObjectCounter<Hash> lc = new ObjectCounter();
|
||||
int tunnelCount = countTunnelsPerPeer(lc);
|
||||
|
||||
// count up the peers in the participating tunnels
|
||||
HashCounter pc = new HashCounter();
|
||||
ObjectCounter<Hash> pc = new ObjectCounter();
|
||||
int partCount = countParticipatingPerPeer(pc);
|
||||
|
||||
Set<Hash> peers = new HashSet(lc.hashes());
|
||||
peers.addAll(pc.hashes());
|
||||
Set<Hash> peers = new HashSet(lc.objects());
|
||||
peers.addAll(pc.objects());
|
||||
List<Hash> peerList = new ArrayList(peers);
|
||||
Collections.sort(peerList, new HashComparator());
|
||||
|
||||
@ -625,7 +626,7 @@ public class TunnelPoolManager implements TunnelManagerFacade {
|
||||
}
|
||||
|
||||
/** @return total number of non-fallback expl. + client tunnels */
|
||||
private int countTunnelsPerPeer(HashCounter lc) {
|
||||
private int countTunnelsPerPeer(ObjectCounter<Hash> lc) {
|
||||
List<TunnelPool> pools = new ArrayList();
|
||||
listPools(pools);
|
||||
int tunnelCount = 0;
|
||||
@ -661,12 +662,12 @@ public class TunnelPoolManager implements TunnelManagerFacade {
|
||||
* @return Set of peers that should not be allowed in another tunnel
|
||||
*/
|
||||
public Set<Hash> selectPeersInTooManyTunnels() {
|
||||
HashCounter lc = new HashCounter();
|
||||
ObjectCounter<Hash> lc = new ObjectCounter();
|
||||
int tunnelCount = countTunnelsPerPeer(lc);
|
||||
Set<Hash> rv = new HashSet();
|
||||
if (tunnelCount >= 4 && _context.router().getUptime() > 10*60*1000) {
|
||||
int max = _context.getProperty("router.maxTunnelPercentage", DEFAULT_MAX_PCT_TUNNELS);
|
||||
for (Hash h : lc.hashes()) {
|
||||
for (Hash h : lc.objects()) {
|
||||
if (lc.count(h) > 0 && (lc.count(h) + 1) * 100 / (tunnelCount + 1) > max)
|
||||
rv.add(h);
|
||||
}
|
||||
@ -675,7 +676,7 @@ public class TunnelPoolManager implements TunnelManagerFacade {
|
||||
}
|
||||
|
||||
/** @return total number of part. tunnels */
|
||||
private int countParticipatingPerPeer(HashCounter pc) {
|
||||
private int countParticipatingPerPeer(ObjectCounter<Hash> pc) {
|
||||
List<HopConfig> participating = _context.tunnelDispatcher().listParticipatingTunnels();
|
||||
for (HopConfig cfg : participating) {
|
||||
Hash from = cfg.getReceiveFrom();
|
||||
@ -694,27 +695,6 @@ public class TunnelPoolManager implements TunnelManagerFacade {
|
||||
}
|
||||
}
|
||||
|
||||
private static class HashCounter {
|
||||
private ConcurrentHashMap<Hash, Integer> _map;
|
||||
public HashCounter() {
|
||||
_map = new ConcurrentHashMap();
|
||||
}
|
||||
public void increment(Hash h) {
|
||||
Integer i = _map.putIfAbsent(h, Integer.valueOf(1));
|
||||
if (i != null)
|
||||
_map.put(h, Integer.valueOf(i.intValue() + 1));
|
||||
}
|
||||
public int count(Hash h) {
|
||||
Integer i = _map.get(h);
|
||||
if (i != null)
|
||||
return i.intValue();
|
||||
return 0;
|
||||
}
|
||||
public Set<Hash> hashes() {
|
||||
return _map.keySet();
|
||||
}
|
||||
}
|
||||
|
||||
private String getCapacity(Hash peer) {
|
||||
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
|
||||
if (info != null) {
|
||||
|
Reference in New Issue
Block a user