2009-10-15 22:42:22 +00:00
package net.i2p.router.web ;
2004-09-07 07:17:02 +00:00
import java.io.IOException ;
2014-06-15 16:14:13 +00:00
import java.io.Serializable ;
2004-09-29 22:49:19 +00:00
import java.io.Writer ;
2004-09-07 07:17:02 +00:00
import java.text.DecimalFormat ;
2005-03-17 05:29:55 +00:00
import java.util.Comparator ;
2004-09-07 07:17:02 +00:00
import java.util.Set ;
2005-03-17 05:29:55 +00:00
import java.util.TreeSet ;
2004-09-07 07:17:02 +00:00
2008-03-30 21:50:35 +00:00
import net.i2p.data.DataHelper ;
2004-09-07 07:17:02 +00:00
import net.i2p.data.Hash ;
2014-08-21 17:36:06 +00:00
import net.i2p.data.router.RouterInfo ;
2004-09-07 07:17:02 +00:00
import net.i2p.router.RouterContext ;
2009-10-15 22:42:22 +00:00
import net.i2p.router.peermanager.DBHistory ;
import net.i2p.router.peermanager.PeerProfile ;
import net.i2p.router.peermanager.ProfileOrganizer ;
2008-03-30 21:50:35 +00:00
import net.i2p.stat.Rate ;
2012-11-17 18:51:28 +00:00
import net.i2p.stat.RateAverages ;
2008-03-30 21:50:35 +00:00
import net.i2p.stat.RateStat ;
2004-09-07 07:17:02 +00:00
/ * *
* Helper class to refactor the HTML rendering from out of the ProfileOrganizer
*
* /
class ProfileOrganizerRenderer {
2012-06-01 13:30:38 +00:00
private final RouterContext _context ;
private final ProfileOrganizer _organizer ;
2004-09-07 07:17:02 +00:00
public ProfileOrganizerRenderer ( ProfileOrganizer organizer , RouterContext context ) {
_context = context ;
_organizer = organizer ;
}
2012-06-01 13:30:38 +00:00
/ * *
* @param mode 0 = high cap ; 1 = all ; 2 = floodfill
* /
public void renderStatusHTML ( Writer out , int mode ) throws IOException {
boolean full = mode = = 1 ;
2010-01-24 15:34:40 +00:00
Set < Hash > peers = _organizer . selectAllPeers ( ) ;
2004-09-07 07:17:02 +00:00
2008-03-30 21:50:35 +00:00
long now = _context . clock ( ) . now ( ) ;
2009-08-19 15:26:35 +00:00
long hideBefore = now - 90 * 60 * 1000 ;
2004-09-07 07:17:02 +00:00
2013-11-21 11:31:50 +00:00
Set < PeerProfile > order = new TreeSet < PeerProfile > ( mode = = 2 ? new HashComparator ( ) : new ProfileComparator ( ) ) ;
2009-11-24 20:20:30 +00:00
int older = 0 ;
int standard = 0 ;
2013-11-28 11:56:54 +00:00
for ( Hash peer : peers ) {
2004-09-07 07:17:02 +00:00
if ( _organizer . getUs ( ) . equals ( peer ) ) continue ;
2015-12-06 16:47:34 +00:00
PeerProfile prof = _organizer . getProfileNonblocking ( peer ) ;
2015-12-04 20:35:38 +00:00
if ( prof = = null )
continue ;
2013-09-01 12:12:40 +00:00
if ( mode = = 2 ) {
2008-03-30 21:50:35 +00:00
RouterInfo info = _context . netDb ( ) . lookupRouterInfoLocally ( peer ) ;
if ( info ! = null & & info . getCapabilities ( ) . indexOf ( " f " ) > = 0 )
2013-09-01 12:12:40 +00:00
order . add ( prof ) ;
continue ;
}
2009-11-24 20:20:30 +00:00
if ( prof . getLastSendSuccessful ( ) < = hideBefore ) {
older + + ;
continue ;
}
if ( ( ! full ) & & ! _organizer . isHighCapacity ( peer ) ) {
standard + + ;
continue ;
}
2005-03-17 05:29:55 +00:00
order . add ( prof ) ;
2004-09-07 07:17:02 +00:00
}
int fast = 0 ;
int reliable = 0 ;
int integrated = 0 ;
2009-07-01 16:00:43 +00:00
StringBuilder buf = new StringBuilder ( 16 * 1024 ) ;
2012-06-01 13:30:38 +00:00
////
//// don't bother reindenting
////
if ( mode < 2 ) {
2015-09-25 19:55:36 +00:00
//buf.append("<h2>").append(_t("Peer Profiles")).append("</h2>\n<p>");
2016-04-18 04:12:15 +00:00
buf . append ( " <p id= \" profiles_overview \" class= \" infohelp \" > " ) ;
2011-03-12 21:32:29 +00:00
buf . append ( ngettext ( " Showing 1 recent profile. " , " Showing {0} recent profiles. " , order . size ( ) ) ) . append ( '\n' ) ;
2009-11-24 20:20:30 +00:00
if ( older > 0 )
2011-03-12 21:32:29 +00:00
buf . append ( ngettext ( " Hiding 1 older profile. " , " Hiding {0} older profiles. " , older ) ) . append ( '\n' ) ;
2009-11-24 20:20:30 +00:00
if ( standard > 0 )
2011-03-12 21:32:29 +00:00
buf . append ( " <a href= \" /profiles?f=1 \" > " ) . append ( ngettext ( " Hiding 1 standard profile. " , " Hiding {0} standard profiles. " , standard ) ) . append ( " </a> \ n " ) ;
2009-10-29 09:03:32 +00:00
buf . append ( " </p> " ) ;
2016-04-18 04:12:15 +00:00
buf . append ( " <table id= \" profiles \" > " ) ;
2009-10-29 09:03:32 +00:00
buf . append ( " <tr> " ) ;
2015-09-25 19:55:36 +00:00
buf . append ( " <th> " ) . append ( _t ( " Peer " ) ) . append ( " </th> " ) ;
buf . append ( " <th> " ) . append ( _t ( " Groups (Caps) " ) ) . append ( " </th> " ) ;
buf . append ( " <th> " ) . append ( _t ( " Speed " ) ) . append ( " </th> " ) ;
buf . append ( " <th> " ) . append ( _t ( " Capacity " ) ) . append ( " </th> " ) ;
buf . append ( " <th> " ) . append ( _t ( " Integration " ) ) . append ( " </th> " ) ;
buf . append ( " <th> " ) . append ( _t ( " Status " ) ) . append ( " </th> " ) ;
2009-10-29 09:03:32 +00:00
buf . append ( " <th> </th> " ) ;
buf . append ( " </tr> " ) ;
2005-03-17 05:29:55 +00:00
int prevTier = 1 ;
2013-11-28 11:56:54 +00:00
for ( PeerProfile prof : order ) {
2004-09-07 07:17:02 +00:00
Hash peer = prof . getPeer ( ) ;
int tier = 0 ;
boolean isIntegrated = false ;
if ( _organizer . isFast ( peer ) ) {
tier = 1 ;
fast + + ;
reliable + + ;
} else if ( _organizer . isHighCapacity ( peer ) ) {
tier = 2 ;
reliable + + ;
} else if ( _organizer . isFailing ( peer ) ) {
} else {
2005-03-17 05:29:55 +00:00
tier = 3 ;
2004-09-07 07:17:02 +00:00
}
if ( _organizer . isWellIntegrated ( peer ) ) {
isIntegrated = true ;
integrated + + ;
}
2005-03-17 05:29:55 +00:00
if ( tier ! = prevTier )
2009-08-17 14:35:18 +00:00
buf . append ( " <tr><td colspan= \" 7 \" ><hr></td></tr> \ n " ) ;
2005-03-17 05:29:55 +00:00
prevTier = tier ;
2009-07-28 13:06:19 +00:00
buf . append ( " <tr><td align= \" center \" nowrap> " ) ;
2009-05-19 18:07:19 +00:00
buf . append ( _context . commSystem ( ) . renderPeerHTML ( peer ) ) ;
2009-11-02 16:50:28 +00:00
// debug
//if(prof.getIsExpandedDB())
// buf.append(" ** ");
2009-07-28 13:06:19 +00:00
buf . append ( " </td><td align= \" center \" > " ) ;
2005-03-17 05:29:55 +00:00
2004-09-07 07:17:02 +00:00
switch ( tier ) {
2015-09-25 19:55:36 +00:00
case 1 : buf . append ( _t ( " Fast, High Capacity " ) ) ; break ;
case 2 : buf . append ( _t ( " High Capacity " ) ) ; break ;
case 3 : buf . append ( _t ( " Standard " ) ) ; break ;
default : buf . append ( _t ( " Failing " ) ) ; break ;
2004-09-07 07:17:02 +00:00
}
2015-09-25 19:55:36 +00:00
if ( isIntegrated ) buf . append ( " , " ) . append ( _t ( " Integrated " ) ) ;
2008-02-19 15:32:39 +00:00
RouterInfo info = _context . netDb ( ) . lookupRouterInfoLocally ( peer ) ;
2008-05-05 16:26:15 +00:00
if ( info ! = null ) {
2009-08-21 23:36:21 +00:00
// prevent HTML injection in the caps and version
buf . append ( " ( " ) . append ( DataHelper . stripHTML ( info . getCapabilities ( ) ) ) ;
2008-05-05 16:26:15 +00:00
String v = info . getOption ( " router.version " ) ;
if ( v ! = null )
2009-08-21 23:36:21 +00:00
buf . append ( ' ' ) . append ( DataHelper . stripHTML ( v ) ) ;
2008-05-05 16:26:15 +00:00
buf . append ( ')' ) ;
}
2004-09-07 07:17:02 +00:00
2005-03-15 03:47:14 +00:00
buf . append ( " <td align= \" right \" > " ) . append ( num ( prof . getSpeedValue ( ) ) ) ;
2008-07-16 15:05:07 +00:00
long bonus = prof . getSpeedBonus ( ) ;
if ( bonus ! = 0 ) {
if ( bonus > 0 )
buf . append ( " (+ " ) ;
else
buf . append ( " ( " ) ;
buf . append ( bonus ) . append ( ')' ) ;
}
buf . append ( " </td><td align= \" right \" > " ) . append ( num ( prof . getCapacityValue ( ) ) ) ;
bonus = prof . getCapacityBonus ( ) ;
if ( bonus ! = 0 ) {
if ( bonus > 0 )
buf . append ( " (+ " ) ;
else
buf . append ( " ( " ) ;
buf . append ( bonus ) . append ( ')' ) ;
}
buf . append ( " </td><td align= \" right \" > " ) . append ( num ( prof . getIntegrationValue ( ) ) ) ;
2009-07-28 13:06:19 +00:00
buf . append ( " </td><td align= \" center \" > " ) ;
2015-09-25 19:55:36 +00:00
if ( _context . banlist ( ) . isBanlisted ( peer ) ) buf . append ( _t ( " Banned " ) ) ;
if ( prof . getIsFailing ( ) ) buf . append ( ' ' ) . append ( _t ( " Failing " ) ) ;
if ( _context . commSystem ( ) . wasUnreachable ( peer ) ) buf . append ( ' ' ) . append ( _t ( " Unreachable " ) ) ;
2012-11-17 19:22:23 +00:00
RateAverages ra = RateAverages . getTemp ( ) ;
2008-05-20 12:48:41 +00:00
Rate failed = prof . getTunnelHistory ( ) . getFailedRate ( ) . getRate ( 30 * 60 * 1000 ) ;
2012-11-17 19:22:23 +00:00
long fails = failed . computeAverages ( ra , false ) . getTotalEventCount ( ) ;
2008-05-20 12:48:41 +00:00
if ( fails > 0 ) {
Rate accepted = prof . getTunnelCreateResponseTime ( ) . getRate ( 30 * 60 * 1000 ) ;
2012-11-17 19:22:23 +00:00
long total = fails + accepted . computeAverages ( ra , false ) . getTotalEventCount ( ) ;
2008-05-20 12:48:41 +00:00
if ( total / fails < = 10 ) // hide if < 10%
2015-09-25 19:55:36 +00:00
buf . append ( ' ' ) . append ( fails ) . append ( '/' ) . append ( total ) . append ( ' ' ) . append ( _t ( " Test Fails " ) ) ;
2008-05-20 12:48:41 +00:00
}
2009-08-17 13:24:08 +00:00
buf . append ( " </td> " ) ;
2011-03-19 17:19:54 +00:00
//buf.append("<td nowrap align=\"center\"><a target=\"_blank\" href=\"dumpprofile.jsp?peer=")
2015-09-25 19:55:36 +00:00
// .append(peer.toBase64().substring(0,6)).append("\">").append(_t("profile")).append("</a>");
2011-03-19 17:19:54 +00:00
buf . append ( " <td nowrap align= \" center \" ><a href= \" viewprofile?peer= " )
2015-09-25 19:55:36 +00:00
. append ( peer . toBase64 ( ) ) . append ( " \" > " ) . append ( _t ( " profile " ) ) . append ( " </a> " ) ;
2010-11-17 22:26:31 +00:00
buf . append ( " <a href= \" configpeer?peer= " ) . append ( peer . toBase64 ( ) ) . append ( " \" >+-</a></td> \ n " ) ;
2004-09-07 07:17:02 +00:00
buf . append ( " </tr> " ) ;
2009-08-21 23:36:21 +00:00
// let's not build the whole page in memory (~500 bytes per peer)
out . write ( buf . toString ( ) ) ;
buf . setLength ( 0 ) ;
2004-09-07 07:17:02 +00:00
}
buf . append ( " </table> " ) ;
2008-03-30 21:50:35 +00:00
2012-06-01 13:30:38 +00:00
////
//// don't bother reindenting
////
} else {
2015-09-25 19:55:36 +00:00
//buf.append("<h2><a name=\"flood\"></a>").append(_t("Floodfill and Integrated Peers"))
2012-06-01 13:30:38 +00:00
// .append(" (").append(integratedPeers.size()).append(")</h2>\n");
2016-04-18 04:12:15 +00:00
buf . append ( " <div class= \" widescroll \" ><table id= \" floodfills \" > " ) ;
2009-11-07 19:32:00 +00:00
buf . append ( " <tr> " ) ;
2015-09-25 19:55:36 +00:00
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " Peer " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " Caps " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " Integ. Value " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " Last Heard About " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " Last Heard From " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " Last Good Send " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " Last Bad Send " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " 10m Resp. Time " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " 1h Resp. Time " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " 1d Resp. Time " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " Last Good Lookup " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " Last Bad Lookup " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " Last Good Store " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " Last Bad Store " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " 1h Fail Rate " ) ) . append ( " </th> " ) ;
buf . append ( " <th class= \" smallhead \" > " ) . append ( _t ( " 1d Fail Rate " ) ) . append ( " </th> " ) ;
2009-11-07 19:32:00 +00:00
buf . append ( " </tr> " ) ;
2012-11-17 19:22:23 +00:00
RateAverages ra = RateAverages . getTemp ( ) ;
2013-11-28 11:56:54 +00:00
for ( PeerProfile prof : order ) {
2008-03-30 21:50:35 +00:00
Hash peer = prof . getPeer ( ) ;
2009-07-28 13:06:19 +00:00
buf . append ( " <tr><td align= \" center \" nowrap> " ) ;
2009-05-19 18:07:19 +00:00
buf . append ( _context . commSystem ( ) . renderPeerHTML ( peer ) ) ;
buf . append ( " </td> " ) ;
2008-03-30 21:50:35 +00:00
RouterInfo info = _context . netDb ( ) . lookupRouterInfoLocally ( peer ) ;
if ( info ! = null )
2009-08-21 23:36:21 +00:00
buf . append ( " <td align= \" center \" > " ) . append ( DataHelper . stripHTML ( info . getCapabilities ( ) ) ) . append ( " </td> " ) ;
2008-03-30 21:50:35 +00:00
else
buf . append ( " <td> </td> " ) ;
buf . append ( " <td align= \" right \" > " ) . append ( num ( prof . getIntegrationValue ( ) ) ) . append ( " </td> " ) ;
2015-06-03 20:45:15 +00:00
buf . append ( " <td align= \" right \" > " ) . append ( formatInterval ( now , prof . getLastHeardAbout ( ) ) ) . append ( " </td> " ) ;
buf . append ( " <td align= \" right \" > " ) . append ( formatInterval ( now , prof . getLastHeardFrom ( ) ) ) . append ( " </td> " ) ;
buf . append ( " <td align= \" right \" > " ) . append ( formatInterval ( now , prof . getLastSendSuccessful ( ) ) ) . append ( " </td> " ) ;
buf . append ( " <td align= \" right \" > " ) . append ( formatInterval ( now , prof . getLastSendFailed ( ) ) ) . append ( " </td> " ) ;
2012-11-17 18:51:28 +00:00
buf . append ( " <td align= \" right \" > " ) . append ( avg ( prof , 10 * 60 * 1000l , ra ) ) . append ( " </td> " ) ;
buf . append ( " <td align= \" right \" > " ) . append ( avg ( prof , 60 * 60 * 1000l , ra ) ) . append ( " </td> " ) ;
buf . append ( " <td align= \" right \" > " ) . append ( avg ( prof , 24 * 60 * 60 * 1000l , ra ) ) . append ( " </td> " ) ;
2008-03-30 21:50:35 +00:00
DBHistory dbh = prof . getDBHistory ( ) ;
if ( dbh ! = null ) {
2015-06-03 20:45:15 +00:00
buf . append ( " <td align= \" right \" > " ) . append ( formatInterval ( now , dbh . getLastLookupSuccessful ( ) ) ) . append ( " </td> " ) ;
buf . append ( " <td align= \" right \" > " ) . append ( formatInterval ( now , dbh . getLastLookupFailed ( ) ) ) . append ( " </td> " ) ;
buf . append ( " <td align= \" right \" > " ) . append ( formatInterval ( now , dbh . getLastStoreSuccessful ( ) ) ) . append ( " </td> " ) ;
buf . append ( " <td align= \" right \" > " ) . append ( formatInterval ( now , dbh . getLastStoreFailed ( ) ) ) . append ( " </td> " ) ;
2012-11-17 18:51:28 +00:00
buf . append ( " <td align= \" right \" > " ) . append ( davg ( dbh , 60 * 60 * 1000l , ra ) ) . append ( " </td> " ) ;
buf . append ( " <td align= \" right \" > " ) . append ( davg ( dbh , 24 * 60 * 60 * 1000l , ra ) ) . append ( " </td> " ) ;
2009-11-02 16:50:28 +00:00
} else {
2009-11-03 20:37:21 +00:00
for ( int i = 0 ; i < 6 ; i + + )
2015-09-25 19:55:36 +00:00
buf . append ( " <td align= \" right \" > " ) . append ( _t ( NA ) ) ;
2008-03-30 21:50:35 +00:00
}
2009-11-24 20:20:30 +00:00
buf . append ( " </tr> \ n " ) ;
2008-03-30 21:50:35 +00:00
}
2016-04-18 04:12:15 +00:00
buf . append ( " </table></div> " ) ;
2008-03-30 21:50:35 +00:00
2012-06-01 13:30:38 +00:00
////
//// don't bother reindenting
////
}
if ( mode < 2 ) {
2016-05-01 01:10:04 +00:00
buf . append ( " <h3 class= \" tabletitle \" > " ) . append ( _t ( " Thresholds " ) ) . append ( " </h3> \ n " )
. append ( " <table id= \" thresholds \" ><tbody><tr><td> " ) ;
2015-09-25 19:55:36 +00:00
buf . append ( " <p><b> " ) . append ( _t ( " Speed " ) ) . append ( " :</b> " ) . append ( num ( _organizer . getSpeedThreshold ( ) ) )
. append ( " ( " ) . append ( fast ) . append ( ' ' ) . append ( _t ( " fast peers " ) ) . append ( " )<br> " ) ;
buf . append ( " <b> " ) . append ( _t ( " Capacity " ) ) . append ( " :</b> " ) . append ( num ( _organizer . getCapacityThreshold ( ) ) )
. append ( " ( " ) . append ( reliable ) . append ( ' ' ) . append ( _t ( " high capacity peers " ) ) . append ( " )<br> " ) ;
buf . append ( " <b> " ) . append ( _t ( " Integration " ) ) . append ( " :</b> " ) . append ( num ( _organizer . getIntegrationThreshold ( ) ) )
2016-05-01 01:10:04 +00:00
. append ( " ( " ) . append ( integrated ) . append ( ' ' ) . append ( _t ( " well integrated peers " ) ) . append ( " ) " )
. append ( " </td></tr></tbody></table> \ n " ) ;
buf . append ( " <h3 class= \" tabletitle \" > " ) . append ( _t ( " Definitions " ) ) . append ( " </h3> \ n " )
. append ( " <table id= \" profile_defs \" ><tbody><tr><td><ul> " ) ;
2015-09-25 19:55:36 +00:00
buf . append ( " <li><b> " ) . append ( _t ( " groups " ) ) . append ( " </b>: " ) . append ( _t ( " as determined by the profile organizer " ) ) . append ( " </li> " ) ;
buf . append ( " <li><b> " ) . append ( _t ( " caps " ) ) . append ( " </b>: " ) . append ( _t ( " capabilities in the netDb, not used to determine profiles " ) ) . append ( " </li> " ) ;
buf . append ( " <li><b> " ) . append ( _t ( " speed " ) ) . append ( " </b>: " ) . append ( _t ( " peak throughput (bytes per second) over a 1 minute period that the peer has sustained in a single tunnel " ) ) . append ( " </li> " ) ;
buf . append ( " <li><b> " ) . append ( _t ( " capacity " ) ) . append ( " </b>: " ) . append ( _t ( " how many tunnels can we ask them to join in an hour? " ) ) . append ( " </li> " ) ;
buf . append ( " <li><b> " ) . append ( _t ( " integration " ) ) . append ( " </b>: " ) . append ( _t ( " how many new peers have they told us about lately? " ) ) . append ( " </li> " ) ;
buf . append ( " <li><b> " ) . append ( _t ( " status " ) ) . append ( " </b>: " ) . append ( _t ( " is the peer banned, or unreachable, or failing tunnel tests? " ) ) . append ( " </li> " ) ;
2016-05-01 01:10:04 +00:00
buf . append ( " </ul></td></tr></tbody></table> \ n " ) ;
2012-06-01 13:30:38 +00:00
////
//// don't bother reindenting
////
} // mode < 2
2004-09-29 22:49:19 +00:00
out . write ( buf . toString ( ) ) ;
2004-09-30 13:10:02 +00:00
out . flush ( ) ;
2004-09-07 07:17:02 +00:00
}
2013-09-01 12:12:40 +00:00
private class ProfileComparator extends HashComparator {
2010-01-24 15:34:40 +00:00
public int compare ( PeerProfile left , PeerProfile right ) {
2005-03-17 05:29:55 +00:00
if ( _context . profileOrganizer ( ) . isFast ( left . getPeer ( ) ) ) {
if ( _context . profileOrganizer ( ) . isFast ( right . getPeer ( ) ) ) {
2013-09-01 12:12:40 +00:00
return super . compare ( left , right ) ;
2005-03-17 05:29:55 +00:00
} else {
return - 1 ; // fast comes first
}
} else if ( _context . profileOrganizer ( ) . isHighCapacity ( left . getPeer ( ) ) ) {
if ( _context . profileOrganizer ( ) . isFast ( right . getPeer ( ) ) ) {
return 1 ;
} else if ( _context . profileOrganizer ( ) . isHighCapacity ( right . getPeer ( ) ) ) {
2013-09-01 12:12:40 +00:00
return super . compare ( left , right ) ;
2005-03-17 05:29:55 +00:00
} else {
return - 1 ;
}
} else if ( _context . profileOrganizer ( ) . isFailing ( left . getPeer ( ) ) ) {
if ( _context . profileOrganizer ( ) . isFailing ( right . getPeer ( ) ) ) {
2013-09-01 12:12:40 +00:00
return super . compare ( left , right ) ;
2005-03-17 05:29:55 +00:00
} else {
return 1 ;
}
} else {
// left is not failing
if ( _context . profileOrganizer ( ) . isFast ( right . getPeer ( ) ) ) {
return 1 ;
} else if ( _context . profileOrganizer ( ) . isHighCapacity ( right . getPeer ( ) ) ) {
return 1 ;
} else if ( _context . profileOrganizer ( ) . isFailing ( right . getPeer ( ) ) ) {
return - 1 ;
} else {
2013-09-01 12:12:40 +00:00
return super . compare ( left , right ) ;
2005-03-17 05:29:55 +00:00
}
}
}
2013-09-01 12:12:40 +00:00
}
2005-03-17 05:29:55 +00:00
2013-09-01 12:12:40 +00:00
/ * *
* Used for floodfill - only page
* @since 0 . 9 . 8
* /
2014-06-15 16:14:13 +00:00
private static class HashComparator implements Comparator < PeerProfile > , Serializable {
2013-09-01 12:12:40 +00:00
public int compare ( PeerProfile left , PeerProfile right ) {
2005-03-17 05:29:55 +00:00
return left . getPeer ( ) . toBase64 ( ) . compareTo ( right . getPeer ( ) . toBase64 ( ) ) ;
}
}
2008-10-26 18:12:36 +00:00
private final static DecimalFormat _fmt = new DecimalFormat ( " ###,##0.00 " ) ;
2004-09-07 07:17:02 +00:00
private final static String num ( double num ) { synchronized ( _fmt ) { return _fmt . format ( num ) ; } }
2009-11-03 20:37:21 +00:00
private final static String NA = HelperBase . _x ( " n/a " ) ;
2008-03-30 21:50:35 +00:00
2012-11-17 18:51:28 +00:00
private String avg ( PeerProfile prof , long rate , RateAverages ra ) {
2008-03-30 21:50:35 +00:00
RateStat rs = prof . getDbResponseTime ( ) ;
if ( rs = = null )
2015-09-25 19:55:36 +00:00
return _t ( NA ) ;
2008-03-30 21:50:35 +00:00
Rate r = rs . getRate ( rate ) ;
if ( r = = null )
2015-09-25 19:55:36 +00:00
return _t ( NA ) ;
2012-11-17 18:51:28 +00:00
r . computeAverages ( ra , false ) ;
if ( ra . getTotalEventCount ( ) = = 0 )
2015-09-25 19:55:36 +00:00
return _t ( NA ) ;
2012-11-17 18:51:28 +00:00
return DataHelper . formatDuration2 ( Math . round ( ra . getAverage ( ) ) ) ;
2008-03-30 21:50:35 +00:00
}
2012-11-17 18:51:28 +00:00
private String davg ( DBHistory dbh , long rate , RateAverages ra ) {
2008-03-30 21:50:35 +00:00
RateStat rs = dbh . getFailedLookupRate ( ) ;
if ( rs = = null )
2009-11-24 20:20:30 +00:00
return " 0% " ;
2008-03-30 21:50:35 +00:00
Rate r = rs . getRate ( rate ) ;
if ( r = = null )
2009-11-24 20:20:30 +00:00
return " 0% " ;
2012-11-17 18:51:28 +00:00
r . computeAverages ( ra , false ) ;
if ( ra . getTotalEventCount ( ) < = 0 )
2009-11-24 20:20:30 +00:00
return " 0% " ;
2012-11-17 18:51:28 +00:00
double avg = 0 . 5 + 100 * ra . getAverage ( ) ;
2009-11-24 20:20:30 +00:00
return ( ( int ) avg ) + " % " ;
2008-03-30 21:50:35 +00:00
}
2009-10-18 14:06:07 +00:00
2015-06-03 20:45:15 +00:00
/** @since 0.9.21 */
private String formatInterval ( long now , long then ) {
if ( then < = 0 )
2015-09-25 19:55:36 +00:00
return _t ( NA ) ;
2015-12-06 16:47:34 +00:00
// avoid 0 or negative
if ( now < = then )
return DataHelper . formatDuration2 ( 1 ) ;
2015-06-03 20:45:15 +00:00
return DataHelper . formatDuration2 ( now - then ) ;
}
2009-10-18 14:06:07 +00:00
/** translate a string */
2015-09-25 19:55:36 +00:00
private String _t ( String s ) {
2009-10-18 14:06:07 +00:00
return Messages . getString ( s , _context ) ;
}
2009-10-26 14:24:25 +00:00
2011-03-12 18:00:58 +00:00
/** translate (ngettext) @since 0.8.5 */
2011-03-12 21:32:29 +00:00
public String ngettext ( String s , String p , int n ) {
2011-03-12 18:00:58 +00:00
return Messages . getString ( n , s , p , _context ) ;
}
2004-09-07 07:17:02 +00:00
}