* DataStructures:

- Remove static logs
    - Sort addresses in RouterInfo at initialization only;
      change from Set to List to save space
    - Remove unused counters in Lease to save space
    - Increase max leases to 16
This commit is contained in:
zzz
2012-02-29 18:09:16 +00:00
parent 48551f0617
commit f61183d2d8
7 changed files with 83 additions and 48 deletions

View File

@ -1299,10 +1299,20 @@ public class DataHelper {
// rv.add(struct);
//}
ArrayList<DataStructure> rv = new ArrayList(dataStructures);
Collections.sort(rv, new DataStructureComparator());
sortStructureList(rv);
return rv;
}
/**
* See above.
* DEPRECATED - Only used by RouterInfo.
*
* @since 0.9
*/
static void sortStructureList(List<? extends DataStructure> dataStructures) {
Collections.sort(dataStructures, new DataStructureComparator());
}
/**
* See sortStructures() comments.
* @since 0.8.3

View File

@ -56,7 +56,6 @@ import net.i2p.util.RandomSource;
* @author jrandom
*/
public class LeaseSet extends DatabaseEntry {
private final static Log _log = new Log(LeaseSet.class);
private Destination _destination;
private PublicKey _encryptionKey;
private SigningPublicKey _signingKey;
@ -71,11 +70,26 @@ public class LeaseSet extends DatabaseEntry {
private boolean _decrypted;
private boolean _checked;
/** This seems like plenty */
public final static int MAX_LEASES = 6;
/**
* Unlimited before 0.6.3;
* 6 as of 0.6.3;
* Increased in version 0.9.
*
* Leasesets larger than 6 should be used with caution,
* as each lease adds 44 bytes, and routers older than version 0.9
* will not be able to connect as they will throw an exception in
* readBytes(). Also, the churn will be quite rapid, leading to
* frequent netdb stores and transmission on existing connections.
*
* However we increase it now in case some hugely popular eepsite arrives.
* Strategies elsewhere in the router to efficiently handle
* large leasesets are TBD.
*/
public static final int MAX_LEASES = 16;
private static final int OLD_MAX_LEASES = 6;
public LeaseSet() {
_leases = new ArrayList(MAX_LEASES);
_leases = new ArrayList(OLD_MAX_LEASES);
_firstExpiration = Long.MAX_VALUE;
}
@ -354,14 +368,16 @@ public class LeaseSet extends DatabaseEntry {
* Must be called after all the leases are in place, but before sign().
*/
public void encrypt(SessionKey key) {
if (_log.shouldLog(Log.WARN))
_log.warn("encrypting lease: " + _destination.calculateHash());
//if (_log.shouldLog(Log.WARN))
// _log.warn("encrypting lease: " + _destination.calculateHash());
try {
encryp(key);
} catch (DataFormatException dfe) {
_log.error("Error encrypting lease: " + _destination.calculateHash());
Log log = I2PAppContext.getGlobalContext().logManager().getLog(LeaseSet.class);
log.error("Error encrypting lease: " + _destination.calculateHash());
} catch (IOException ioe) {
_log.error("Error encrypting lease: " + _destination.calculateHash());
Log log = I2PAppContext.getGlobalContext().logManager().getLog(LeaseSet.class);
log.error("Error encrypting lease: " + _destination.calculateHash());
}
}
@ -420,8 +436,8 @@ public class LeaseSet extends DatabaseEntry {
* encrypted leaseset can be sent on to others (via writeBytes())
*/
private void decrypt(SessionKey key) throws DataFormatException, IOException {
if (_log.shouldLog(Log.WARN))
_log.warn("decrypting lease: " + _destination.calculateHash());
//if (_log.shouldLog(Log.WARN))
// _log.warn("decrypting lease: " + _destination.calculateHash());
int size = _leases.size();
if (size < 2)
throw new DataFormatException("Bad number of leases for decryption");
@ -468,9 +484,11 @@ public class LeaseSet extends DatabaseEntry {
decrypt(key);
_decrypted = true;
} catch (DataFormatException dfe) {
_log.error("Error decrypting lease: " + _destination.calculateHash() + dfe);
Log log = I2PAppContext.getGlobalContext().logManager().getLog(LeaseSet.class);
log.error("Error decrypting lease: " + _destination.calculateHash() + dfe);
} catch (IOException ioe) {
_log.error("Error decrypting lease: " + _destination.calculateHash() + ioe);
Log log = I2PAppContext.getGlobalContext().logManager().getLog(LeaseSet.class);
log.error("Error decrypting lease: " + _destination.calculateHash() + ioe);
}
}
_checked = true;

View File

@ -13,6 +13,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
@ -24,6 +25,7 @@ import java.util.Properties;
import java.util.Set;
import java.util.Vector;
import net.i2p.I2PAppContext;
import net.i2p.crypto.SHA256Generator;
import net.i2p.util.Clock;
import net.i2p.util.Log;
@ -43,10 +45,14 @@ import net.i2p.util.OrderedProperties;
* @author jrandom
*/
public class RouterInfo extends DatabaseEntry {
private final static Log _log = new Log(RouterInfo.class);
private RouterIdentity _identity;
private volatile long _published;
private final Set<RouterAddress> _addresses;
/**
* Addresses must be sorted by SHA256.
* When an RI is created, they are sorted in setAddresses().
* Save addresses in the order received so we need not resort.
*/
private final List<RouterAddress> _addresses;
/** may be null to save memory, no longer final */
private Set<Hash> _peers;
private final Properties _options;
@ -71,7 +77,7 @@ public class RouterInfo extends DatabaseEntry {
public static final String BW_CAPABILITY_CHARS = "KLMNO";
public RouterInfo() {
_addresses = new HashSet(2);
_addresses = new ArrayList(2);
_options = new OrderedProperties();
}
@ -156,21 +162,33 @@ public class RouterInfo extends DatabaseEntry {
*
* @return unmodifiable view, non-null
*/
public Set<RouterAddress> getAddresses() {
return Collections.unmodifiableSet(_addresses);
public Collection<RouterAddress> getAddresses() {
return Collections.unmodifiableCollection(_addresses);
}
/**
* Specify a set of RouterAddress structures at which this router
* can be contacted.
*
* @throws IllegalStateException if RouterInfo is already signed
* Warning - Sorts the addresses here. Do not modify any address
* after calling this, as the sort order is based on the
* hash of the entire address structure.
*
* @param addresses may be null
* @throws IllegalStateException if RouterInfo is already signed or addresses previously set
*/
public void setAddresses(Set<RouterAddress> addresses) {
if (_signature != null)
public void setAddresses(Collection<RouterAddress> addresses) {
if (_signature != null || !_addresses.isEmpty())
throw new IllegalStateException();
_addresses.clear();
if (addresses != null) _addresses.addAll(addresses);
if (addresses != null) {
_addresses.addAll(addresses);
if (_addresses.size() > 1) {
// WARNING this sort algorithm cannot be changed, as it must be consistent
// network-wide. The signature is not checked at readin time, but only
// later, and the addresses are stored in a Set, not a List.
DataHelper.sortStructureList(_addresses);
}
}
}
/**
@ -270,14 +288,7 @@ public class RouterInfo extends DatabaseEntry {
DataHelper.writeLong(out, 1, 0);
} else {
DataHelper.writeLong(out, 1, sz);
Collection<RouterAddress> addresses = _addresses;
if (sz > 1) {
// WARNING this sort algorithm cannot be changed, as it must be consistent
// network-wide. The signature is not checked at readin time, but only
// later, and the addresses are stored in a Set, not a List.
addresses = (Collection<RouterAddress>) DataHelper.sortStructures(addresses);
}
for (RouterAddress addr : addresses) {
for (RouterAddress addr : _addresses) {
addr.writeBytes(out);
}
}
@ -458,16 +469,16 @@ public class RouterInfo extends DatabaseEntry {
_validated = true;
if (!_isValid) {
Log log = I2PAppContext.getGlobalContext().logManager().getLog(RouterInfo.class);
byte data[] = null;
try {
data = getBytes();
} catch (DataFormatException dfe) {
_log.error("Error validating", dfe);
log.error("Error validating", dfe);
return;
}
if (_log.shouldLog(Log.ERROR))
_log.error("Invalid [" + SHA256Generator.getInstance().calculateHash(data).toBase64()
+ (_log.shouldLog(Log.WARN) ? ("]\n" + toString()) : ""),
log.error("Invalid [" + SHA256Generator.getInstance().calculateHash(data).toBase64()
+ (log.shouldLog(Log.WARN) ? ("]\n" + toString()) : ""),
new Exception("Signature failed"));
}
}