forked from I2P_Developers/i2p.i2p
cache the hashCode and getBytes data, significantly reducing the contention on these objects
This commit is contained in:
@ -46,6 +46,8 @@ public class RouterInfo extends DataStructureImpl {
|
|||||||
private volatile boolean _isValid;
|
private volatile boolean _isValid;
|
||||||
private volatile String _stringified;
|
private volatile String _stringified;
|
||||||
private volatile byte _byteified[];
|
private volatile byte _byteified[];
|
||||||
|
private volatile int _hashCode;
|
||||||
|
private volatile boolean _hashCodeInitialized;
|
||||||
|
|
||||||
public RouterInfo() {
|
public RouterInfo() {
|
||||||
setIdentity(null);
|
setIdentity(null);
|
||||||
@ -59,6 +61,7 @@ public class RouterInfo extends DataStructureImpl {
|
|||||||
_currentRoutingKey = null;
|
_currentRoutingKey = null;
|
||||||
_stringified = null;
|
_stringified = null;
|
||||||
_byteified = null;
|
_byteified = null;
|
||||||
|
_hashCodeInitialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RouterInfo(RouterInfo old) {
|
public RouterInfo(RouterInfo old) {
|
||||||
@ -74,6 +77,7 @@ public class RouterInfo extends DataStructureImpl {
|
|||||||
private void resetCache() {
|
private void resetCache() {
|
||||||
_stringified = null;
|
_stringified = null;
|
||||||
_byteified = null;
|
_byteified = null;
|
||||||
|
_hashCodeInitialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -111,6 +115,7 @@ public class RouterInfo extends DataStructureImpl {
|
|||||||
*/
|
*/
|
||||||
public void setPublished(long published) {
|
public void setPublished(long published) {
|
||||||
_published = published;
|
_published = published;
|
||||||
|
resetCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -221,16 +226,20 @@ public class RouterInfo extends DataStructureImpl {
|
|||||||
//_log.debug("verify ok? " + DSAEngine.getInstance().verifySignature(sig, bytes, getIdentity().getSigningPublicKey()));
|
//_log.debug("verify ok? " + DSAEngine.getInstance().verifySignature(sig, bytes, getIdentity().getSigningPublicKey()));
|
||||||
//_log.debug("Signed data: \n" + Base64.encode(bytes));
|
//_log.debug("Signed data: \n" + Base64.encode(bytes));
|
||||||
//_log.debug("Signature: " + getSignature());
|
//_log.debug("Signature: " + getSignature());
|
||||||
|
|
||||||
resetCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
*/
|
||||||
private byte[] getBytes() throws DataFormatException {
|
private byte[] getBytes() throws DataFormatException {
|
||||||
if (_byteified != null) return _byteified;
|
if (_byteified != null) return _byteified;
|
||||||
if (_identity == null) throw new IllegalStateException("Router identity isn't set? wtf!");
|
if (_identity == null) throw new DataFormatException("Router identity isn't set? wtf!");
|
||||||
if (_addresses == null) throw new IllegalStateException("Router addressess isn't set? wtf!");
|
if (_addresses == null) throw new DataFormatException("Router addressess isn't set? wtf!");
|
||||||
if (_peers == null) throw new IllegalStateException("Router peers isn't set? wtf!");
|
if (_peers == null) throw new DataFormatException("Router peers isn't set? wtf!");
|
||||||
if (_options == null) throw new IllegalStateException("Router options isn't set? wtf!");
|
if (_options == null) throw new DataFormatException("Router options isn't set? wtf!");
|
||||||
|
|
||||||
long before = Clock.getInstance().now();
|
long before = Clock.getInstance().now();
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
@ -339,10 +348,14 @@ public class RouterInfo extends DataStructureImpl {
|
|||||||
}
|
}
|
||||||
_isValid = DSAEngine.getInstance().verifySignature(_signature, data, _identity.getSigningPublicKey());
|
_isValid = DSAEngine.getInstance().verifySignature(_signature, data, _identity.getSigningPublicKey());
|
||||||
if (!_isValid) {
|
if (!_isValid) {
|
||||||
_log.error("Invalid [" + SHA256Generator.getInstance().calculateHash(data).toBase64()
|
if (_log.shouldLog(Log.ERROR))
|
||||||
+ "] w/ signing key: " + _identity.getSigningPublicKey(), new Exception("Signature failed"));
|
_log.error("Invalid [" + SHA256Generator.getInstance().calculateHash(data).toBase64()
|
||||||
_log.debug("Failed data: \n" + Base64.encode(data));
|
+ "] w/ signing key: " + _identity.getSigningPublicKey(),
|
||||||
_log.debug("Signature: " + getSignature());
|
new Exception("Signature failed"));
|
||||||
|
if (_log.shouldLog(Log.DEBUG)) {
|
||||||
|
_log.debug("Failed data: \n" + Base64.encode(data));
|
||||||
|
_log.debug("Signature: " + getSignature());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,19 +391,7 @@ public class RouterInfo extends DataStructureImpl {
|
|||||||
//if (!isValid())
|
//if (!isValid())
|
||||||
// throw new DataFormatException("Data is not valid");
|
// throw new DataFormatException("Data is not valid");
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
|
||||||
_identity.writeBytes(baos);
|
baos.write(getBytes());
|
||||||
DataHelper.writeDate(baos, new Date(_published));
|
|
||||||
DataHelper.writeLong(baos, 1, _addresses.size());
|
|
||||||
for (Iterator iter = _addresses.iterator(); iter.hasNext();) {
|
|
||||||
RouterAddress addr = (RouterAddress) iter.next();
|
|
||||||
addr.writeBytes(baos);
|
|
||||||
}
|
|
||||||
DataHelper.writeLong(baos, 1, _peers.size());
|
|
||||||
for (Iterator iter = _peers.iterator(); iter.hasNext();) {
|
|
||||||
Hash peerHash = (Hash) iter.next();
|
|
||||||
peerHash.writeBytes(baos);
|
|
||||||
}
|
|
||||||
DataHelper.writeProperties(baos, _options);
|
|
||||||
_signature.writeBytes(baos);
|
_signature.writeBytes(baos);
|
||||||
|
|
||||||
byte data[] = baos.toByteArray();
|
byte data[] = baos.toByteArray();
|
||||||
@ -401,16 +402,22 @@ public class RouterInfo extends DataStructureImpl {
|
|||||||
public boolean equals(Object object) {
|
public boolean equals(Object object) {
|
||||||
if ((object == null) || !(object instanceof RouterInfo)) return false;
|
if ((object == null) || !(object instanceof RouterInfo)) return false;
|
||||||
RouterInfo info = (RouterInfo) object;
|
RouterInfo info = (RouterInfo) object;
|
||||||
return DataHelper.eq(getAddresses(), info.getAddresses()) && DataHelper.eq(getIdentity(), info.getIdentity())
|
return DataHelper.eq(_addresses, info.getAddresses())
|
||||||
&& DataHelper.eq(getOptions(), info.getOptions()) && DataHelper.eq(getPeers(), info.getPeers())
|
&& DataHelper.eq(_identity, info.getIdentity())
|
||||||
&& DataHelper.eq(getSignature(), info.getSignature())
|
&& DataHelper.eq(_options, info.getOptions())
|
||||||
|
&& DataHelper.eq(_peers, info.getPeers())
|
||||||
|
&& DataHelper.eq(_signature, info.getSignature())
|
||||||
&& DataHelper.eq(getPublished(), info.getPublished());
|
&& DataHelper.eq(getPublished(), info.getPublished());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return DataHelper.hashCode(getAddresses()) + DataHelper.hashCode(getIdentity())
|
if (!_hashCodeInitialized) {
|
||||||
+ DataHelper.hashCode(getOptions()) + DataHelper.hashCode(getPeers())
|
_hashCode = DataHelper.hashCode(_addresses) + DataHelper.hashCode(_identity)
|
||||||
+ DataHelper.hashCode(getSignature()) + (int) getPublished();
|
+ DataHelper.hashCode(_options) + DataHelper.hashCode(_peers)
|
||||||
|
+ DataHelper.hashCode(_signature) + (int) getPublished();
|
||||||
|
_hashCodeInitialized = true;
|
||||||
|
}
|
||||||
|
return _hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
@ -420,17 +427,19 @@ public class RouterInfo extends DataStructureImpl {
|
|||||||
buf.append("\n\tIdentity: ").append(getIdentity());
|
buf.append("\n\tIdentity: ").append(getIdentity());
|
||||||
buf.append("\n\tSignature: ").append(getSignature());
|
buf.append("\n\tSignature: ").append(getSignature());
|
||||||
buf.append("\n\tPublished on: ").append(new Date(getPublished()));
|
buf.append("\n\tPublished on: ").append(new Date(getPublished()));
|
||||||
buf.append("\n\tAddresses: #: ").append(getAddresses().size());
|
Set addresses = _addresses; // getAddresses()
|
||||||
for (Iterator iter = getAddresses().iterator(); iter.hasNext();) {
|
buf.append("\n\tAddresses: #: ").append(addresses.size());
|
||||||
|
for (Iterator iter = addresses.iterator(); iter.hasNext();) {
|
||||||
RouterAddress addr = (RouterAddress) iter.next();
|
RouterAddress addr = (RouterAddress) iter.next();
|
||||||
buf.append("\n\t\tAddress: ").append(addr);
|
buf.append("\n\t\tAddress: ").append(addr);
|
||||||
}
|
}
|
||||||
buf.append("\n\tPeers: #: ").append(getPeers().size());
|
Set peers = _peers; // getPeers()
|
||||||
for (Iterator iter = getPeers().iterator(); iter.hasNext();) {
|
buf.append("\n\tPeers: #: ").append(peers.size());
|
||||||
|
for (Iterator iter = peers.iterator(); iter.hasNext();) {
|
||||||
Hash hash = (Hash) iter.next();
|
Hash hash = (Hash) iter.next();
|
||||||
buf.append("\n\t\tPeer hash: ").append(hash);
|
buf.append("\n\t\tPeer hash: ").append(hash);
|
||||||
}
|
}
|
||||||
Properties options = getOptions();
|
Properties options = _options; // getOptions();
|
||||||
buf.append("\n\tOptions: #: ").append(options.size());
|
buf.append("\n\tOptions: #: ").append(options.size());
|
||||||
for (Iterator iter = options.keySet().iterator(); iter.hasNext();) {
|
for (Iterator iter = options.keySet().iterator(); iter.hasNext();) {
|
||||||
String key = (String) iter.next();
|
String key = (String) iter.next();
|
||||||
|
Reference in New Issue
Block a user