* 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"));
}
}

View File

@ -479,15 +479,9 @@ public class Blocklist {
List<byte[]> rv = new ArrayList(1);
RouterInfo pinfo = _context.netDb().lookupRouterInfoLocally(peer);
if (pinfo == null) return rv;
Set<RouterAddress> paddr = pinfo.getAddresses();
if (paddr == null || paddr.isEmpty())
return rv;
String oldphost = null;
List<RouterAddress> pladdr = new ArrayList(paddr);
// for each peer address
for (int j = 0; j < paddr.size(); j++) {
RouterAddress pa = (RouterAddress) pladdr.get(j);
if (pa == null) continue;
for (RouterAddress pa : pinfo.getAddresses()) {
String phost = pa.getOption("host");
if (phost == null) continue;
if (oldphost != null && oldphost.equals(phost)) continue;

View File

@ -216,7 +216,7 @@ public class FloodfillVerifyStoreJob extends JobImpl {
if (_log.shouldLog(Log.WARN))
_log.warn("Verify failed (older) for " + _key);
if (_log.shouldLog(Log.INFO))
_log.info("Rcvd older lease: " + dsm.getEntry());
_log.info("Rcvd older data: " + dsm.getEntry());
} else if (_message instanceof DatabaseSearchReplyMessage) {
// assume 0 old, all new, 0 invalid, 0 dup
getContext().profileManager().dbLookupReply(_target, 0,

View File

@ -8,12 +8,13 @@ package net.i2p.router.networkdb.kademlia;
*
*/
import java.util.Collection;
import java.util.Date;
import java.util.Set;
import net.i2p.data.DatabaseEntry;
import net.i2p.data.Hash;
import net.i2p.data.LeaseSet;
import net.i2p.data.RouterAddress;
import net.i2p.data.RouterIdentity;
import net.i2p.data.RouterInfo;
import net.i2p.data.i2np.DatabaseStoreMessage;
@ -145,9 +146,9 @@ public class HandleFloodfillDatabaseStoreMessageJob extends JobImpl {
_log.shouldLog(Log.WARN))
_log.warn("Blocklisting new peer " + key + ' ' + ri);
} else {
Set oldAddr = prevNetDb.getAddresses();
Set newAddr = ri.getAddresses();
if (newAddr != null && (!newAddr.equals(oldAddr)) &&
Collection<RouterAddress> oldAddr = prevNetDb.getAddresses();
Collection<RouterAddress> newAddr = ri.getAddresses();
if ((!newAddr.equals(oldAddr)) &&
(!getContext().shitlist().isShitlistedForever(key)) &&
getContext().blocklist().isBlocklisted(key) &&
_log.shouldLog(Log.WARN))

View File

@ -7,6 +7,7 @@ import java.net.UnknownHostException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@ -1258,7 +1259,7 @@ public class ProfileOrganizer {
RouterInfo pinfo = _context.netDb().lookupRouterInfoLocally(peer);
if (pinfo == null)
return rv;
Set<RouterAddress> paddr = pinfo.getAddresses();
Collection<RouterAddress> paddr = pinfo.getAddresses();
if (paddr == null)
return rv;
for (RouterAddress pa : paddr) {