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:
zzz
2009-06-21 00:03:59 +00:00
parent 306b3017e4
commit bc38ca4f91
5 changed files with 102 additions and 62 deletions

View 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();
}
}

View File

@ -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; }
/**

View File

@ -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();
}

View File

@ -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\">");

View File

@ -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) {