cache the hashCode and getBytes data, significantly reducing the contention on these objects

This commit is contained in:
jrandom
2004-04-27 08:28:16 +00:00
committed by zzz
parent d0f6d47b14
commit ea03637ec1

View File

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