I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 82f3f750 authored by zzz's avatar zzz
Browse files

* NetDB:

      - Handle old and duplicate stores more efficiently
      - Have DataStore put() return success
parent e26df1c2
No related branches found
No related tags found
No related merge requests found
...@@ -18,11 +18,11 @@ public interface DataStore { ...@@ -18,11 +18,11 @@ public interface DataStore {
public boolean isKnown(Hash key); public boolean isKnown(Hash key);
public DataStructure get(Hash key); public DataStructure get(Hash key);
public DataStructure get(Hash key, boolean persist); public DataStructure get(Hash key, boolean persist);
public void put(Hash key, DataStructure data); public boolean put(Hash key, DataStructure data);
public void put(Hash key, DataStructure data, boolean persist); public boolean put(Hash key, DataStructure data, boolean persist);
public DataStructure remove(Hash key); public DataStructure remove(Hash key);
public DataStructure remove(Hash key, boolean persist); public DataStructure remove(Hash key, boolean persist);
public Set getKeys(); public Set<Hash> getKeys();
public void stop(); public void stop();
public void restart(); public void restart();
public void rescan(); public void rescan();
......
...@@ -128,20 +128,22 @@ class PersistentDataStore extends TransientDataStore { ...@@ -128,20 +128,22 @@ class PersistentDataStore extends TransientDataStore {
} }
@Override @Override
public void put(Hash key, DataStructure data) { public boolean put(Hash key, DataStructure data) {
put(key, data, true); return put(key, data, true);
} }
/* /*
* @param persist if false, call super only, don't access disk * @param persist if false, call super only, don't access disk
* @return success
*/ */
@Override @Override
public void put(Hash key, DataStructure data, boolean persist) { public boolean put(Hash key, DataStructure data, boolean persist) {
if ( (data == null) || (key == null) ) return; if ( (data == null) || (key == null) ) return false;
super.put(key, data); boolean rv = super.put(key, data);
// Don't bother writing LeaseSets to disk // Don't bother writing LeaseSets to disk
if (persist && data instanceof RouterInfo) if (rv && persist && data instanceof RouterInfo)
_writer.queue(key, data); _writer.queue(key, data);
return rv;
} }
private class RemoveJob extends JobImpl { private class RemoveJob extends JobImpl {
......
...@@ -24,7 +24,7 @@ import net.i2p.util.Log; ...@@ -24,7 +24,7 @@ import net.i2p.util.Log;
class TransientDataStore implements DataStore { class TransientDataStore implements DataStore {
private Log _log; private Log _log;
private Map<Hash, DataStructure> _data; private ConcurrentHashMap<Hash, DataStructure> _data;
protected RouterContext _context; protected RouterContext _context;
public TransientDataStore(RouterContext ctx) { public TransientDataStore(RouterContext ctx) {
...@@ -47,11 +47,11 @@ class TransientDataStore implements DataStore { ...@@ -47,11 +47,11 @@ class TransientDataStore implements DataStore {
public void rescan() {} public void rescan() {}
public Set getKeys() { public Set<Hash> getKeys() {
return new HashSet(_data.keySet()); return new HashSet(_data.keySet());
} }
/** for PersistentDataStore only - don't use here */ /** for PersistentDataStore only - don't use here @throws IAE always */
public DataStructure get(Hash key, boolean persist) { public DataStructure get(Hash key, boolean persist) {
throw new IllegalArgumentException("no"); throw new IllegalArgumentException("no");
} }
...@@ -73,22 +73,22 @@ class TransientDataStore implements DataStore { ...@@ -73,22 +73,22 @@ class TransientDataStore implements DataStore {
return count; return count;
} }
/** nothing published more than 5 minutes in the future */ /** for PersistentDataStore only - don't use here @throws IAE always */
private final static long MAX_FUTURE_PUBLISH_DATE = 5*60*1000; public boolean put(Hash key, DataStructure data, boolean persist) {
/** don't accept tunnels set to expire more than 3 hours in the future, which is insane */
private final static long MAX_FUTURE_EXPIRATION_DATE = KademliaNetworkDatabaseFacade.MAX_LEASE_FUTURE;
/** for PersistentDataStore only - don't use here */
public void put(Hash key, DataStructure data, boolean persist) {
throw new IllegalArgumentException("no"); throw new IllegalArgumentException("no");
} }
public void put(Hash key, DataStructure data) { /**
if (data == null) return; * @param data must be validated before here
* @return success
*/
public boolean put(Hash key, DataStructure data) {
if (data == null) return false;
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Storing key " + key); _log.debug("Storing key " + key);
DataStructure old = null; DataStructure old = null;
old = _data.put(key, data); old = _data.putIfAbsent(key, data);
boolean rv = false;
if (data instanceof RouterInfo) { if (data instanceof RouterInfo) {
// Don't do this here so we don't reset it at router startup; // Don't do this here so we don't reset it at router startup;
// the StoreMessageJob calls this // the StoreMessageJob calls this
...@@ -99,26 +99,19 @@ class TransientDataStore implements DataStore { ...@@ -99,26 +99,19 @@ class TransientDataStore implements DataStore {
if (ri.getPublished() < ori.getPublished()) { if (ri.getPublished() < ori.getPublished()) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Almost clobbered an old router! " + key + ": [old published on " + new Date(ori.getPublished()) + " new on " + new Date(ri.getPublished()) + "]"); _log.info("Almost clobbered an old router! " + key + ": [old published on " + new Date(ori.getPublished()) + " new on " + new Date(ri.getPublished()) + "]");
if (_log.shouldLog(Log.DEBUG)) } else if (ri.getPublished() == ori.getPublished()) {
_log.debug("Number of router options for " + key + ": " + ri.getOptions().size() + " (old one had: " + ori.getOptions().size() + ")", new Exception("Updated routerInfo"));
_data.put(key, old);
} else if (ri.getPublished() > _context.clock().now() + MAX_FUTURE_PUBLISH_DATE) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Hmm, someone tried to give us something with the publication date really far in the future (" + new Date(ri.getPublished()) + "), dropping it"); _log.info("Duplicate " + key);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Number of router options for " + key + ": " + ri.getOptions().size() + " (old one had: " + ori.getOptions().size() + ")", new Exception("Updated routerInfo"));
_data.put(key, old);
} else { } else {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Updated the old router for " + key + ": [old published on " + new Date(ori.getPublished()) + " new on " + new Date(ri.getPublished()) + "]"); _log.info("Updated the old router for " + key + ": [old published on " + new Date(ori.getPublished()) + " new on " + new Date(ri.getPublished()) + "]");
if (_log.shouldLog(Log.DEBUG)) _data.put(key, data);
_log.debug("Number of router options for " + key + ": " + ri.getOptions().size() + " (old one had: " + ori.getOptions().size() + ")", new Exception("Updated routerInfo")); rv = true;
} }
} else { } else {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Brand new router for " + key + ": published on " + new Date(ri.getPublished())); _log.info("New router for " + key + ": published on " + new Date(ri.getPublished()));
if (_log.shouldLog(Log.DEBUG)) rv = true;
_log.debug("Number of router options for " + key + ": " + ri.getOptions().size(), new Exception("Updated routerInfo"));
} }
} else if (data instanceof LeaseSet) { } else if (data instanceof LeaseSet) {
LeaseSet ls = (LeaseSet)data; LeaseSet ls = (LeaseSet)data;
...@@ -127,14 +120,28 @@ class TransientDataStore implements DataStore { ...@@ -127,14 +120,28 @@ class TransientDataStore implements DataStore {
if (ls.getEarliestLeaseDate() < ols.getEarliestLeaseDate()) { if (ls.getEarliestLeaseDate() < ols.getEarliestLeaseDate()) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Almost clobbered an old leaseSet! " + key + ": [old published on " + new Date(ols.getEarliestLeaseDate()) + " new on " + new Date(ls.getEarliestLeaseDate()) + "]"); _log.info("Almost clobbered an old leaseSet! " + key + ": [old published on " + new Date(ols.getEarliestLeaseDate()) + " new on " + new Date(ls.getEarliestLeaseDate()) + "]");
_data.put(key, old); } else if (ls.getEarliestLeaseDate() == ols.getEarliestLeaseDate()) {
} else if (ls.getEarliestLeaseDate() > _context.clock().now() + MAX_FUTURE_EXPIRATION_DATE) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Hmm, someone tried to give us something with the expiration date really far in the future (" + new Date(ls.getEarliestLeaseDate()) + "), dropping it"); _log.info("Duplicate " + key);
_data.put(key, old); } else {
if (_log.shouldLog(Log.INFO)) {
_log.info("Updated old leaseSet " + key + ": [old published on " + new Date(ols.getEarliestLeaseDate()) + " new on " + new Date(ls.getEarliestLeaseDate()) + "]");
if (_log.shouldLog(Log.DEBUG))
_log.debug("RAP? " + ls.getReceivedAsPublished() + " RAR? " + ls.getReceivedAsReply());
}
_data.put(key, data);
rv = true;
}
} else {
if (_log.shouldLog(Log.INFO)) {
_log.info("New leaseset for " + key + ": published on " + new Date(ls.getEarliestLeaseDate()));
if (_log.shouldLog(Log.DEBUG))
_log.debug("RAP? " + ls.getReceivedAsPublished() + " RAR? " + ls.getReceivedAsReply());
} }
rv = true;
} }
} }
return rv;
} }
@Override @Override
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment