From 82f3f7506ccd1c02c0c9540197bc862bb8548cba Mon Sep 17 00:00:00 2001 From: zzz <zzz@mail.i2p> Date: Mon, 10 May 2010 15:00:13 +0000 Subject: [PATCH] * NetDB: - Handle old and duplicate stores more efficiently - Have DataStore put() return success --- .../router/networkdb/kademlia/DataStore.java | 6 +- .../kademlia/PersistentDataStore.java | 14 ++-- .../kademlia/TransientDataStore.java | 67 ++++++++++--------- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/DataStore.java b/router/java/src/net/i2p/router/networkdb/kademlia/DataStore.java index ae41326782..b4b55f3f8e 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/DataStore.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/DataStore.java @@ -18,11 +18,11 @@ public interface DataStore { public boolean isKnown(Hash key); public DataStructure get(Hash key); public DataStructure get(Hash key, boolean persist); - public void put(Hash key, DataStructure data); - public void put(Hash key, DataStructure data, boolean persist); + public boolean put(Hash key, DataStructure data); + public boolean put(Hash key, DataStructure data, boolean persist); public DataStructure remove(Hash key); public DataStructure remove(Hash key, boolean persist); - public Set getKeys(); + public Set<Hash> getKeys(); public void stop(); public void restart(); public void rescan(); diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java index c94ad7a76f..77ea8c4573 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java @@ -128,20 +128,22 @@ class PersistentDataStore extends TransientDataStore { } @Override - public void put(Hash key, DataStructure data) { - put(key, data, true); + public boolean put(Hash key, DataStructure data) { + return put(key, data, true); } /* * @param persist if false, call super only, don't access disk + * @return success */ @Override - public void put(Hash key, DataStructure data, boolean persist) { - if ( (data == null) || (key == null) ) return; - super.put(key, data); + public boolean put(Hash key, DataStructure data, boolean persist) { + if ( (data == null) || (key == null) ) return false; + boolean rv = super.put(key, data); // Don't bother writing LeaseSets to disk - if (persist && data instanceof RouterInfo) + if (rv && persist && data instanceof RouterInfo) _writer.queue(key, data); + return rv; } private class RemoveJob extends JobImpl { diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/TransientDataStore.java b/router/java/src/net/i2p/router/networkdb/kademlia/TransientDataStore.java index 38efb714fb..d5e10738c2 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/TransientDataStore.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/TransientDataStore.java @@ -24,7 +24,7 @@ import net.i2p.util.Log; class TransientDataStore implements DataStore { private Log _log; - private Map<Hash, DataStructure> _data; + private ConcurrentHashMap<Hash, DataStructure> _data; protected RouterContext _context; public TransientDataStore(RouterContext ctx) { @@ -47,11 +47,11 @@ class TransientDataStore implements DataStore { public void rescan() {} - public Set getKeys() { + public Set<Hash> getKeys() { 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) { throw new IllegalArgumentException("no"); } @@ -73,22 +73,22 @@ class TransientDataStore implements DataStore { return count; } - /** nothing published more than 5 minutes in the future */ - private final static long MAX_FUTURE_PUBLISH_DATE = 5*60*1000; - /** 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) { + /** for PersistentDataStore only - don't use here @throws IAE always */ + public boolean put(Hash key, DataStructure data, boolean persist) { 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)) _log.debug("Storing key " + key); DataStructure old = null; - old = _data.put(key, data); + old = _data.putIfAbsent(key, data); + boolean rv = false; if (data instanceof RouterInfo) { // Don't do this here so we don't reset it at router startup; // the StoreMessageJob calls this @@ -99,26 +99,19 @@ class TransientDataStore implements DataStore { if (ri.getPublished() < ori.getPublished()) { 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()) + "]"); - 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 if (ri.getPublished() > _context.clock().now() + MAX_FUTURE_PUBLISH_DATE) { + } else if (ri.getPublished() == ori.getPublished()) { 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"); - 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); + _log.info("Duplicate " + key); } else { 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()) + "]"); - 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, data); + rv = true; } } else { if (_log.shouldLog(Log.INFO)) - _log.info("Brand new router for " + key + ": published on " + new Date(ri.getPublished())); - if (_log.shouldLog(Log.DEBUG)) - _log.debug("Number of router options for " + key + ": " + ri.getOptions().size(), new Exception("Updated routerInfo")); + _log.info("New router for " + key + ": published on " + new Date(ri.getPublished())); + rv = true; } } else if (data instanceof LeaseSet) { LeaseSet ls = (LeaseSet)data; @@ -127,14 +120,28 @@ class TransientDataStore implements DataStore { if (ls.getEarliestLeaseDate() < ols.getEarliestLeaseDate()) { 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()) + "]"); - _data.put(key, old); - } else if (ls.getEarliestLeaseDate() > _context.clock().now() + MAX_FUTURE_EXPIRATION_DATE) { + } else if (ls.getEarliestLeaseDate() == ols.getEarliestLeaseDate()) { 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"); - _data.put(key, old); + _log.info("Duplicate " + key); + } 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 -- GitLab