RouterInfo: Optimize writing to avoid extra copy;

eliminate caching previously enabled for routers with high memory limits
Log tweak on sig verify fail
DataHelper.writeLong() to write(byte) conversion
DatabaseEntry: Remove deprecated, unused setRoutingKey()
This commit is contained in:
zzz
2015-12-13 16:48:04 +00:00
parent 2155347e4f
commit 3c5f9d0bc3
2 changed files with 40 additions and 41 deletions

View File

@ -98,6 +98,9 @@ public abstract class DatabaseEntry extends DataStructureImpl {
/** /**
* Returns the raw payload data, excluding the signature, to be signed by sign(). * Returns the raw payload data, excluding the signature, to be signed by sign().
*
* Most callers should use writeBytes() or toByteArray() instead.
*
* FIXME RouterInfo throws DFE and LeaseSet returns null * FIXME RouterInfo throws DFE and LeaseSet returns null
* @return null on error ??????????????????????? * @return null on error ???????????????????????
*/ */
@ -122,13 +125,6 @@ public abstract class DatabaseEntry extends DataStructureImpl {
return _currentRoutingKey; return _currentRoutingKey;
} }
/**
* @deprecated unused
*/
public void setRoutingKey(Hash key) {
_currentRoutingKey = key;
}
/** /**
* @throws IllegalStateException if not in RouterContext * @throws IllegalStateException if not in RouterContext
*/ */

View File

@ -78,8 +78,11 @@ public class RouterInfo extends DatabaseEntry {
private volatile boolean _hashCodeInitialized; private volatile boolean _hashCodeInitialized;
/** should we cache the byte and string versions _byteified ? **/ /** should we cache the byte and string versions _byteified ? **/
private boolean _shouldCache; private boolean _shouldCache;
/** maybe we should check if we are floodfill? */ /**
private static final boolean CACHE_ALL = SystemVersion.getMaxMemory() > 128*1024*1024l; * Maybe we should check if we are floodfill?
* If we do bring this back, don't do on ARM or Android
*/
private static final boolean CACHE_ALL = false; // SystemVersion.getMaxMemory() > 128*1024*1024l;
public static final String PROP_NETWORK_ID = "netId"; public static final String PROP_NETWORK_ID = "netId";
public static final String PROP_CAPABILITIES = "caps"; public static final String PROP_CAPABILITIES = "caps";
@ -308,11 +311,30 @@ public class RouterInfo extends DatabaseEntry {
*/ */
protected byte[] getBytes() throws DataFormatException { protected byte[] getBytes() throws DataFormatException {
if (_byteified != null) return _byteified; if (_byteified != null) return _byteified;
if (_identity == null) throw new DataFormatException("Router identity isn't set?!");
//long before = Clock.getInstance().now();
ByteArrayOutputStream out = new ByteArrayOutputStream(2*1024); ByteArrayOutputStream out = new ByteArrayOutputStream(2*1024);
try { try {
writeDataBytes(out);
} catch (IOException ioe) {
throw new DataFormatException("IO Error getting bytes", ioe);
}
byte data[] = out.toByteArray();
if (CACHE_ALL || _shouldCache)
_byteified = data;
return data;
}
/**
* Write out the raw payload of the routerInfo, excluding the signature. This
* caches the data in memory if possible.
*
* @throws DataFormatException if the data is somehow b0rked (missing props, etc)
* @throws IOException
* @since 0.9.24
*/
private void writeDataBytes(OutputStream out) throws DataFormatException, IOException {
if (_identity == null) throw new DataFormatException("Missing identity");
if (_published < 0) throw new DataFormatException("Invalid published date: " + _published);
_identity.writeBytes(out); _identity.writeBytes(out);
// avoid thrashing objects // avoid thrashing objects
//DataHelper.writeDate(out, new Date(_published)); //DataHelper.writeDate(out, new Date(_published));
@ -320,9 +342,9 @@ public class RouterInfo extends DatabaseEntry {
int sz = _addresses.size(); int sz = _addresses.size();
if (sz <= 0 || isHidden()) { if (sz <= 0 || isHidden()) {
// Do not send IP address to peers in hidden mode // Do not send IP address to peers in hidden mode
DataHelper.writeLong(out, 1, 0); out.write((byte) 0);
} else { } else {
DataHelper.writeLong(out, 1, sz); out.write((byte) sz);
for (RouterAddress addr : _addresses) { for (RouterAddress addr : _addresses) {
addr.writeBytes(out); addr.writeBytes(out);
} }
@ -332,7 +354,7 @@ public class RouterInfo extends DatabaseEntry {
// method of trusted links, which isn't implemented in the router // method of trusted links, which isn't implemented in the router
// at the moment, and may not be later. // at the moment, and may not be later.
int psz = _peers == null ? 0 : _peers.size(); int psz = _peers == null ? 0 : _peers.size();
DataHelper.writeLong(out, 1, psz); out.write((byte) psz);
if (psz > 0) { if (psz > 0) {
Collection<Hash> peers = _peers; Collection<Hash> peers = _peers;
if (psz > 1) if (psz > 1)
@ -345,17 +367,6 @@ public class RouterInfo extends DatabaseEntry {
} }
} }
DataHelper.writeProperties(out, _options); DataHelper.writeProperties(out, _options);
} catch (IOException ioe) {
throw new DataFormatException("IO Error getting bytes", ioe);
}
byte data[] = out.toByteArray();
//if (_log.shouldLog(Log.DEBUG)) {
// long after = Clock.getInstance().now();
// _log.debug("getBytes() took " + (after - before) + "ms");
//}
if (CACHE_ALL || _shouldCache)
_byteified = data;
return data;
} }
/** /**
@ -487,10 +498,11 @@ public class RouterInfo extends DatabaseEntry {
if (!_isValid) { if (!_isValid) {
Log log = I2PAppContext.getGlobalContext().logManager().getLog(RouterInfo.class); Log log = I2PAppContext.getGlobalContext().logManager().getLog(RouterInfo.class);
// TODO change to warn if (log.shouldWarn()) {
//if (log.shouldWarn()) { log.warn("Sig verify fail: " + toString(), new Exception("from"));
log.error("Sig verify fail: " + toString(), new Exception("from")); } else {
//} log.error("RI Sig verify fail: " + _identity.getHash());
}
} }
} }
@ -587,18 +599,9 @@ public class RouterInfo extends DatabaseEntry {
* This does NOT validate the signature * This does NOT validate the signature
*/ */
public void writeBytes(OutputStream out) throws DataFormatException, IOException { public void writeBytes(OutputStream out) throws DataFormatException, IOException {
if (_identity == null) throw new DataFormatException("Missing identity");
if (_published < 0) throw new DataFormatException("Invalid published date: " + _published);
if (_signature == null) throw new DataFormatException("Signature is null"); if (_signature == null) throw new DataFormatException("Signature is null");
//if (!isValid()) writeDataBytes(out);
// throw new DataFormatException("Data is not valid"); _signature.writeBytes(out);
ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
baos.write(getBytes());
_signature.writeBytes(baos);
byte data[] = baos.toByteArray();
//_log.debug("Writing routerInfo [len=" + data.length + "]: " + toString());
out.write(data);
} }
@Override @Override