merge of '2f361aff8dd74139e94c6f92e575638347b28b0a'

and 'c095a7e88a112095206c8abb3db82789c620a5e4'
This commit is contained in:
hiddenz
2011-02-15 17:23:02 +00:00
13 changed files with 156 additions and 58 deletions

View File

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

View File

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

View File

@@ -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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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
}
}
}

View File

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

View File

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

View File

@@ -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 = "";

View File

@@ -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;