forked from I2P_Developers/i2p.i2p
merge of '2f361aff8dd74139e94c6f92e575638347b28b0a'
and 'c095a7e88a112095206c8abb3db82789c620a5e4'
This commit is contained in:
@@ -857,20 +857,53 @@ public class I2PSnarkServlet extends Default {
|
||||
out.write("<td class=\"center " + rowClass + "\">");
|
||||
out.write(statusString + "</td>\n\t");
|
||||
|
||||
// (i) icon column
|
||||
out.write("<td class=\"" + rowClass + "\">");
|
||||
if (isValid && meta.getAnnounce() != null) {
|
||||
// Link to local details page - note that trailing slash on a single-file torrent
|
||||
// gets us to the details page instead of the file.
|
||||
//StringBuilder buf = new StringBuilder(128);
|
||||
//buf.append("<a href=\"").append(snark.getBaseName())
|
||||
// .append("/\" title=\"").append(_("Torrent details"))
|
||||
// .append("\"><img alt=\"").append(_("Info")).append("\" border=\"0\" src=\"")
|
||||
// .append(_imgPath).append("details.png\"></a>");
|
||||
//out.write(buf.toString());
|
||||
|
||||
// Link to tracker details page
|
||||
String trackerLink = getTrackerLink(meta.getAnnounce(), snark.getInfoHash());
|
||||
if (trackerLink != null)
|
||||
out.write(trackerLink);
|
||||
}
|
||||
|
||||
// File type icon column
|
||||
out.write("</td>\n<td class=\"" + rowClass + "\">");
|
||||
if (isValid) {
|
||||
// Link to local details page - note that trailing slash on a single-file torrent
|
||||
// gets us to the details page instead of the file.
|
||||
StringBuilder buf = new StringBuilder(128);
|
||||
buf.append("<a href=\"").append(snark.getBaseName())
|
||||
.append("/\" title=\"").append(_("Torrent details"))
|
||||
.append("\"><img alt=\"").append(_("Info")).append("\" border=\"0\" src=\"")
|
||||
.append(_imgPath).append("details.png\"></a>");
|
||||
out.write(buf.toString());
|
||||
.append("\">");
|
||||
out.write(buf.toString());
|
||||
}
|
||||
String icon;
|
||||
if (isMultiFile)
|
||||
icon = "folder";
|
||||
else if (isValid)
|
||||
icon = toIcon(meta.getName());
|
||||
else
|
||||
icon = "magnet";
|
||||
if (isValid) {
|
||||
out.write(toImg(icon, _("Info")));
|
||||
out.write("</a>");
|
||||
} else {
|
||||
out.write(toImg(icon));
|
||||
}
|
||||
|
||||
out.write("</td>\n<td class=\"" + rowClass + "\">");
|
||||
StringBuilder buf = null;
|
||||
// Torrent name column
|
||||
out.write("</td><td class=\"snarkTorrentName " + rowClass + "\">");
|
||||
if (remaining == 0 || isMultiFile) {
|
||||
buf = new StringBuilder(128);
|
||||
StringBuilder buf = new StringBuilder(128);
|
||||
buf.append("<a href=\"").append(snark.getBaseName());
|
||||
if (isMultiFile)
|
||||
buf.append('/');
|
||||
@@ -882,22 +915,6 @@ public class I2PSnarkServlet extends Default {
|
||||
buf.append("\">");
|
||||
out.write(buf.toString());
|
||||
}
|
||||
String icon;
|
||||
if (isMultiFile)
|
||||
icon = "folder";
|
||||
else if (isValid)
|
||||
icon = toIcon(meta.getName());
|
||||
else
|
||||
icon = "magnet";
|
||||
if (remaining == 0 || isMultiFile) {
|
||||
out.write(toImg(icon, _("Open")));
|
||||
out.write("</a>");
|
||||
} else {
|
||||
out.write(toImg(icon));
|
||||
}
|
||||
out.write("</td><td class=\"snarkTorrentName " + rowClass + "\">");
|
||||
if (remaining == 0 || isMultiFile)
|
||||
out.write(buf.toString());
|
||||
out.write(filename);
|
||||
if (remaining == 0 || isMultiFile)
|
||||
out.write("</a>");
|
||||
@@ -1169,7 +1186,7 @@ public class I2PSnarkServlet extends Default {
|
||||
out.write(_("From URL"));
|
||||
out.write(":<td><input type=\"text\" name=\"newURL\" size=\"85\" value=\"" + newURL + "\"");
|
||||
out.write("title=\"");
|
||||
out.write(_("Torrent file must originate from an I2P-based tracker"));
|
||||
out.write(_("Enter the torrent file download URL (I2P only), magnet link, or maggot link"));
|
||||
out.write("\"> \n");
|
||||
// not supporting from file at the moment, since the file name passed isn't always absolute (so it may not resolve)
|
||||
//out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>");
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
<cobertura-instrument todir="./build/obj_test">
|
||||
<fileset dir="./build/obj">
|
||||
<include name="**/*.class"/>
|
||||
<exclude name="**/*Test.class" />
|
||||
</fileset>
|
||||
</cobertura-instrument>
|
||||
</target>
|
||||
|
||||
@@ -179,6 +179,7 @@ public class DataHelper {
|
||||
* @param props source
|
||||
* @return new offset
|
||||
*/
|
||||
@Deprecated
|
||||
public static int toProperties(byte target[], int offset, Properties props) throws DataFormatException, IOException {
|
||||
if (props != null) {
|
||||
OrderedProperties p = new OrderedProperties();
|
||||
@@ -219,6 +220,7 @@ public class DataHelper {
|
||||
* @param target returned Properties
|
||||
* @return new offset
|
||||
*/
|
||||
@Deprecated
|
||||
public static int fromProperties(byte source[], int offset, Properties target) throws DataFormatException, IOException {
|
||||
int size = (int)fromLong(source, offset, 2);
|
||||
offset += 2;
|
||||
@@ -254,6 +256,7 @@ public class DataHelper {
|
||||
*
|
||||
* @throws RuntimeException if either is too long.
|
||||
*/
|
||||
@Deprecated
|
||||
public static byte[] toProperties(Properties opts) {
|
||||
try {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(2);
|
||||
@@ -544,6 +547,7 @@ public class DataHelper {
|
||||
}
|
||||
|
||||
/** @deprecated unused */
|
||||
@Deprecated
|
||||
public static byte[] toDate(Date date) throws IllegalArgumentException {
|
||||
if (date == null)
|
||||
return toLong(DATE_LENGTH, 0L);
|
||||
@@ -678,6 +682,7 @@ public class DataHelper {
|
||||
* @throws IOException if there is an IO error writing the boolean
|
||||
* @deprecated unused
|
||||
*/
|
||||
@Deprecated
|
||||
public static void writeBoolean(OutputStream out, Boolean bool)
|
||||
throws DataFormatException, IOException {
|
||||
if (bool == null)
|
||||
@@ -689,6 +694,7 @@ public class DataHelper {
|
||||
}
|
||||
|
||||
/** @deprecated unused */
|
||||
@Deprecated
|
||||
public static Boolean fromBoolean(byte data[], int offset) {
|
||||
if (data[offset] == BOOLEAN_TRUE)
|
||||
return Boolean.TRUE;
|
||||
@@ -699,11 +705,13 @@ public class DataHelper {
|
||||
}
|
||||
|
||||
/** @deprecated unused */
|
||||
@Deprecated
|
||||
public static void toBoolean(byte data[], int offset, boolean value) {
|
||||
data[offset] = (value ? BOOLEAN_TRUE : BOOLEAN_FALSE);
|
||||
}
|
||||
|
||||
/** @deprecated unused */
|
||||
@Deprecated
|
||||
public static void toBoolean(byte data[], int offset, Boolean value) {
|
||||
if (value == null)
|
||||
data[offset] = BOOLEAN_UNKNOWN;
|
||||
@@ -712,12 +720,16 @@ public class DataHelper {
|
||||
}
|
||||
|
||||
/** deprecated - used only in DatabaseLookupMessage */
|
||||
@Deprecated
|
||||
public static final byte BOOLEAN_TRUE = 0x1;
|
||||
/** deprecated - used only in DatabaseLookupMessage */
|
||||
@Deprecated
|
||||
public static final byte BOOLEAN_FALSE = 0x0;
|
||||
/** @deprecated unused */
|
||||
@Deprecated
|
||||
public static final byte BOOLEAN_UNKNOWN = 0x2;
|
||||
/** @deprecated unused */
|
||||
@Deprecated
|
||||
public static final int BOOLEAN_LENGTH = 1;
|
||||
|
||||
//
|
||||
@@ -780,6 +792,7 @@ public class DataHelper {
|
||||
* Compare two integers, really just for consistency.
|
||||
* @deprecated inefficient
|
||||
*/
|
||||
@Deprecated
|
||||
public final static boolean eq(int lhs, int rhs) {
|
||||
return lhs == rhs;
|
||||
}
|
||||
@@ -788,6 +801,7 @@ public class DataHelper {
|
||||
* Compare two longs, really just for consistency.
|
||||
* @deprecated inefficient
|
||||
*/
|
||||
@Deprecated
|
||||
public final static boolean eq(long lhs, long rhs) {
|
||||
return lhs == rhs;
|
||||
}
|
||||
@@ -796,6 +810,7 @@ public class DataHelper {
|
||||
* Compare two bytes, really just for consistency.
|
||||
* @deprecated inefficient
|
||||
*/
|
||||
@Deprecated
|
||||
public final static boolean eq(byte lhs, byte rhs) {
|
||||
return lhs == rhs;
|
||||
}
|
||||
@@ -974,6 +989,7 @@ public class DataHelper {
|
||||
* @return true if the line was read, false if eof was reached before a
|
||||
* newline was found
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean readLine(InputStream in, StringBuffer buf) throws IOException {
|
||||
return readLine(in, buf, null);
|
||||
}
|
||||
@@ -987,6 +1003,7 @@ public class DataHelper {
|
||||
* Warning - 8KB line length limit as of 0.7.13, @throws IOException if exceeded
|
||||
* @deprecated use StringBuilder version
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean readLine(InputStream in, StringBuffer buf, Sha256Standalone hash) throws IOException {
|
||||
int c = -1;
|
||||
int i = 0;
|
||||
|
||||
@@ -36,7 +36,7 @@ public class DateAndFlags extends DataStructureImpl {
|
||||
/**
|
||||
* @param flags 0 - 65535
|
||||
*/
|
||||
public DateAndFlags(int flags, long date) {
|
||||
public DateAndFlags(long date, int flags) {
|
||||
_flags = flags;
|
||||
_date = date;
|
||||
}
|
||||
@@ -44,7 +44,7 @@ public class DateAndFlags extends DataStructureImpl {
|
||||
/**
|
||||
* @param flags 0 - 65535
|
||||
*/
|
||||
public DateAndFlags(int flags, Date date) {
|
||||
public DateAndFlags(Date date, int flags) {
|
||||
_flags = flags;
|
||||
_date = date.getTime();
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ import java.util.List;
|
||||
import net.i2p.I2PAppContext;
|
||||
|
||||
class Executor implements Runnable {
|
||||
private I2PAppContext _context;
|
||||
private final I2PAppContext _context;
|
||||
private Log _log;
|
||||
private final List _readyEvents;
|
||||
private SimpleStore runn;
|
||||
private final SimpleStore runn;
|
||||
|
||||
public Executor(I2PAppContext ctx, Log log, List events, SimpleStore x) {
|
||||
_context = ctx;
|
||||
@@ -31,9 +31,10 @@ class Executor implements Runnable {
|
||||
try {
|
||||
evt.timeReached();
|
||||
} catch (Throwable t) {
|
||||
log("wtf, event borked: " + evt, t);
|
||||
log("Executing task " + evt + " exited unexpectedly, please report", t);
|
||||
}
|
||||
long time = _context.clock().now() - before;
|
||||
// FIXME _log won't be non-null unless we already had a CRIT
|
||||
if ( (time > 1000) && (_log != null) && (_log.shouldLog(Log.WARN)) )
|
||||
_log.warn("wtf, event execution took " + time + ": " + evt);
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@ public class SimpleScheduler {
|
||||
public static SimpleScheduler getInstance() { return _instance; }
|
||||
private static final int MIN_THREADS = 2;
|
||||
private static final int MAX_THREADS = 4;
|
||||
private I2PAppContext _context;
|
||||
private Log _log;
|
||||
private ScheduledThreadPoolExecutor _executor;
|
||||
private String _name;
|
||||
private final I2PAppContext _context;
|
||||
private final Log _log;
|
||||
private final ScheduledThreadPoolExecutor _executor;
|
||||
private final String _name;
|
||||
private int _count;
|
||||
private final int _threads;
|
||||
|
||||
@@ -42,7 +42,6 @@ public class SimpleScheduler {
|
||||
_context = I2PAppContext.getGlobalContext();
|
||||
_log = _context.logManager().getLog(SimpleScheduler.class);
|
||||
_name = name;
|
||||
_count = 0;
|
||||
long maxMemory = Runtime.getRuntime().maxMemory();
|
||||
_threads = (int) Math.max(MIN_THREADS, Math.min(MAX_THREADS, 1 + (maxMemory / (32*1024*1024))));
|
||||
_executor = new ScheduledThreadPoolExecutor(_threads, new CustomThreadFactory());
|
||||
@@ -139,7 +138,7 @@ public class SimpleScheduler {
|
||||
try {
|
||||
_timedEvent.timeReached();
|
||||
} catch (Throwable t) {
|
||||
_log.log(Log.CRIT, _name + " wtf, event borked: " + _timedEvent, t);
|
||||
_log.log(Log.CRIT, _name + ": Scheduled task " + _timedEvent + " exited unexpectedly, please report", t);
|
||||
}
|
||||
long time = System.currentTimeMillis() - before;
|
||||
if (time > 1000 && _log.shouldLog(Log.WARN))
|
||||
|
||||
@@ -14,6 +14,8 @@ import net.i2p.I2PAppContext;
|
||||
* appropriate time. The method that is fired however should NOT block (otherwise
|
||||
* they b0rk the timer).
|
||||
*
|
||||
* WARNING - Deprecated.
|
||||
* This is an inefficient mess. Use SimpleScheduler or SimpleTimer2 if possible.
|
||||
*/
|
||||
public class SimpleTimer {
|
||||
private static final SimpleTimer _instance = new SimpleTimer();
|
||||
|
||||
@@ -29,10 +29,10 @@ public class SimpleTimer2 {
|
||||
public static SimpleTimer2 getInstance() { return _instance; }
|
||||
private static final int MIN_THREADS = 2;
|
||||
private static final int MAX_THREADS = 4;
|
||||
private I2PAppContext _context;
|
||||
private final I2PAppContext _context;
|
||||
private static Log _log; // static so TimedEvent can use it
|
||||
private ScheduledThreadPoolExecutor _executor;
|
||||
private String _name;
|
||||
private final ScheduledThreadPoolExecutor _executor;
|
||||
private final String _name;
|
||||
private int _count;
|
||||
private final int _threads;
|
||||
|
||||
@@ -223,7 +223,7 @@ public class SimpleTimer2 {
|
||||
try {
|
||||
timeReached();
|
||||
} catch (Throwable t) {
|
||||
_log.log(Log.CRIT, _pool + " wtf, event borked: " + this, t);
|
||||
_log.log(Log.CRIT, _pool + ": Timed task " + this + " exited unexpectedly, please report", t);
|
||||
}
|
||||
long time = System.currentTimeMillis() - before;
|
||||
if (time > 500 && _log.shouldLog(Log.WARN))
|
||||
|
||||
@@ -25,4 +25,50 @@ public class LeaseSetTest extends StructureTest {
|
||||
return leaseSet;
|
||||
}
|
||||
public DataStructure createStructureToRead() { return new LeaseSet(); }
|
||||
|
||||
public void testGetLeaseInvalid() {
|
||||
// create test subject
|
||||
LeaseSet subj = new LeaseSet();
|
||||
|
||||
// should contain no leases now..
|
||||
try {
|
||||
assertNull(subj.getLease(0));
|
||||
} catch(RuntimeException exc) {
|
||||
// all good
|
||||
}
|
||||
|
||||
// this shouldn't work either
|
||||
try {
|
||||
assertNull(subj.getLease(-1));
|
||||
} catch(RuntimeException exc) {
|
||||
// all good
|
||||
}
|
||||
}
|
||||
|
||||
public void testAddLeaseNull() {
|
||||
// create test subject
|
||||
LeaseSet subj = new LeaseSet();
|
||||
|
||||
// now add an null lease
|
||||
try {
|
||||
subj.addLease(null);
|
||||
fail("Failed at failing.");
|
||||
} catch(IllegalArgumentException exc) {
|
||||
// all good
|
||||
}
|
||||
}
|
||||
|
||||
public void testAddLeaseInvalid() {
|
||||
// create test subject
|
||||
LeaseSet subj = new LeaseSet();
|
||||
|
||||
// try to add completely invalid lease(ie. no data)
|
||||
try {
|
||||
subj.addLease(new Lease());
|
||||
fail("Failed at failing.");
|
||||
} catch(IllegalArgumentException exc) {
|
||||
// all good
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ public class RouterAddressTest extends StructureTest {
|
||||
addr.setOptions(options);
|
||||
addr.setTransportStyle("Blah");
|
||||
assertFalse(addr.equals(null));
|
||||
assertFalse(addr.equals(""));
|
||||
}
|
||||
|
||||
public void testToString(){
|
||||
@@ -73,5 +74,7 @@ public class RouterAddressTest extends StructureTest {
|
||||
addr.setOptions(options);
|
||||
addr.setTransportStyle("Blah");
|
||||
addr.toString();
|
||||
addr.setOptions(null);
|
||||
addr.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
2011-02-15 zzz
|
||||
* i2psnark: Details link shuffle, mostly restore 0.8.3 behavior
|
||||
* Profiles: Punish rejections more, in an attempt to spread the
|
||||
load more through the network
|
||||
* Timers: Log cleanup
|
||||
|
||||
2011-02-14 Mathiasdm
|
||||
* Fix headless issue without reboot
|
||||
|
||||
2011-02-13 zzz
|
||||
* Connect Client: Minor NPE fix cleanup
|
||||
* JobQueue: Prevet NPE at shutdown (thanks liberty)
|
||||
* JobQueue: Prevent NPE at shutdown (thanks liberty)
|
||||
* GeoIP: Prevent startup NPE (ticket #413, thanks RN)
|
||||
* NetDB: Prevent ExpireLeaseJob NPE (thanks sponge)
|
||||
|
||||
@@ -21,6 +27,7 @@
|
||||
* I2CP: Correctly close internal connections on the router side
|
||||
when closed by the client, was causing massive memory leak
|
||||
for internal clients using lots of sessions (thanks sponge)
|
||||
(ticket #397)
|
||||
* i2psnark:
|
||||
- Improved magnet link parsing, use tr parameter if present
|
||||
* i2ptunnel: Change shared clients default for new clients to false
|
||||
|
||||
@@ -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 = 11;
|
||||
public final static long BUILD = 12;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
||||
@@ -11,7 +11,7 @@ class CapacityCalculator {
|
||||
private static final I2PAppContext _context = I2PAppContext.getGlobalContext();
|
||||
|
||||
/** used to adjust each period so that we keep trying to expand the peer's capacity */
|
||||
static long GROWTH_FACTOR = 5;
|
||||
static final long GROWTH_FACTOR = 5;
|
||||
|
||||
/** the calculator estimates over a 1 hour period */
|
||||
private static long ESTIMATE_PERIOD = 60*60*1000;
|
||||
@@ -83,37 +83,42 @@ class CapacityCalculator {
|
||||
*
|
||||
* Let A = accects, R = rejects, F = fails
|
||||
* @return estimated and adjusted accepts per hour, for the given period
|
||||
* which is, more or less, max(0, 5 + (A * (A / (A + R))) - (4 * F))
|
||||
* which is, more or less, max(0, 5 + (A * (A / (A + 2R))) - (4 * F))
|
||||
*/
|
||||
private static double estimateCapacity(RateStat acceptStat, RateStat rejectStat, RateStat failedStat, int period) {
|
||||
Rate curAccepted = acceptStat.getRate(period);
|
||||
Rate curRejected = rejectStat.getRate(period);
|
||||
Rate curFailed = failedStat.getRate(period);
|
||||
|
||||
long eventCount = 0;
|
||||
if (curAccepted != null)
|
||||
double eventCount = 0;
|
||||
if (curAccepted != null) {
|
||||
eventCount = curAccepted.getCurrentEventCount() + curAccepted.getLastEventCount();
|
||||
// Punish for rejections.
|
||||
// We don't want to simply do eventCount -= rejected or we get to zero with 50% rejection,
|
||||
// and we don't want everybody to be at zero during times of congestion.
|
||||
if (eventCount > 0) {
|
||||
long rejected = curRejected.getCurrentEventCount() + curRejected.getLastEventCount();
|
||||
eventCount = eventCount * eventCount / (eventCount + rejected);
|
||||
// Punish for rejections.
|
||||
// We don't want to simply do eventCount -= rejected or we get to zero with 50% rejection,
|
||||
// and we don't want everybody to be at zero during times of congestion.
|
||||
if (eventCount > 0 && curRejected != null) {
|
||||
long rejected = curRejected.getCurrentEventCount() + curRejected.getLastEventCount();
|
||||
if (rejected > 0)
|
||||
eventCount *= eventCount / (eventCount + (2 * rejected));
|
||||
}
|
||||
}
|
||||
|
||||
double stretch = ((double)ESTIMATE_PERIOD) / period;
|
||||
double val = eventCount * stretch;
|
||||
long failed = 0;
|
||||
|
||||
// Let's say a failure is 4 times worse than a rejection.
|
||||
// It's actually much worse than that, but with 2-hop tunnels and a 8-peer
|
||||
// fast pool, for example, you have a 1/7 chance of being falsely blamed.
|
||||
// We also don't want to drive everybody's capacity to zero, that isn't helpful.
|
||||
if (curFailed != null)
|
||||
failed = (long) (0.5 + (4.0 * (curFailed.getCurrentTotalValue() + curFailed.getLastTotalValue()) / 100.0));
|
||||
if (failed > 0) {
|
||||
//if ( (period <= 10*60*1000) && (curFailed.getCurrentEventCount() > 0) )
|
||||
// return 0.0d; // their tunnels have failed in the last 0-10 minutes
|
||||
//else
|
||||
val -= failed * stretch;
|
||||
if (curFailed != null) {
|
||||
double failed = curFailed.getCurrentTotalValue() + curFailed.getLastTotalValue();
|
||||
if (failed > 0) {
|
||||
//if ( (period <= 10*60*1000) && (curFailed.getCurrentEventCount() > 0) )
|
||||
// return 0.0d; // their tunnels have failed in the last 0-10 minutes
|
||||
//else
|
||||
// .04 = 4.0 / 100.0 adjustment to failed
|
||||
val -= 0.04 * failed * stretch;
|
||||
}
|
||||
}
|
||||
|
||||
val += GROWTH_FACTOR;
|
||||
|
||||
Reference in New Issue
Block a user