package net.i2p.router.networkdb.kademlia;
import net.i2p.data.Hash;
import net.i2p.data.i2np.DatabaseSearchReplyMessage;
import net.i2p.data.i2np.DatabaseStoreMessage;
import net.i2p.data.i2np.I2NPMessage;
import net.i2p.router.MessageSelector;
import net.i2p.router.RouterContext;
import net.i2p.util.Log;
/**
* Slightly modified version of FloodOnlyLookupSelector.
* Always follows the DSRM entries.
*
* @since 0.8.9
*/
class IterativeLookupSelector implements MessageSelector {
private final RouterContext _context;
private final IterativeSearchJob _search;
private boolean _matchFound;
private final Log _log;
public IterativeLookupSelector(RouterContext ctx, IterativeSearchJob search) {
_context = ctx;
_search = search;
_log = ctx.logManager().getLog(getClass());
}
public boolean continueMatching() {
// don't use remaining searches count
return (!_matchFound) && _context.clock().now() < getExpiration();
}
public long getExpiration() { return (_matchFound ? -1 : _search.getExpiration()); }
/**
* This only returns true for DSMs, not for DSRMs.
*/
public boolean isMatch(I2NPMessage message) {
if (message == null) return false;
if (message instanceof DatabaseStoreMessage) {
DatabaseStoreMessage dsm = (DatabaseStoreMessage)message;
// is it worth making sure the reply came in on the right tunnel?
if (_search.getKey().equals(dsm.getKey())) {
_matchFound = true;
return true;
}
} else if (message instanceof DatabaseSearchReplyMessage) {
DatabaseSearchReplyMessage dsrm = (DatabaseSearchReplyMessage)message;
if (_search.getKey().equals(dsrm.getSearchKey())) {
// Got a netDb reply pointing us at other floodfills...
if (_log.shouldLog(Log.INFO)) {
Hash from = dsrm.getFromHash();
_log.info(_search.getJobId() + ": Processing DSRM via IterativeLookupJob, apparently from " + from);
}
// was inline, now in IterativeLookupJob due to deadlocks
_context.jobQueue().addJob(new IterativeLookupJob(_context, dsrm, _search));
// fall through, always return false, we do not wish the match job to be called
}
}
return false;
}
/** @since 0.9.12 */
public String toString() {
return "IL Selector for " + _search.getKey();
}
}