## net.i2p.router.networkdb.kademlia
Class SearchJob

    java.lang.Object
      net.i2p.router.JobImpl
          net.i2p.router.networkdb.kademlia.SearchJob

All Implemented Interfaces:
  Job

Direct Known Subclasses:
  ExploreJob

     class SearchJob

extends JobImpl

Search for a particular key iteratively until we either find a value or we run out of peers Note that this is rarely if ever used directly, and is primary used by the ExploreJob extension. FloodOnlySearchJob and FloodSearchJob do not extend this. It also does not update peer profile stats.

Nested Class Summary
`protected class` `SearchJob.FailedJob` Called when a particular peer failed to respond before the timeout was reached, or if the peer could not be contacted at all.

Field Summary
`protected KademliaNetworkDatabaseFacade` `_facade`
`protected Log` `_log`
`(package private) static int` `MAX_CLOSEST` only send the 10 closest "dont tell me about" refs
`(package private) static long` `MIN_TIMEOUT`

`(package private) static int`

`PER_FLOODFILL_PEER_TIMEOUT`
static boolean isCongested(RouterContext ctx) { float availableSend = ctx.bandwidthLimiter().getOutboundKBytesPerSecond()*1024 - ctx.bandwidthLimiter().getSendBps(); float availableRecv = ctx.bandwidthLimiter().getInboundKBytesPerSecond()*1024 - ctx.bandwidthLimiter().getReceiveBps(); // 6KBps is an arbitrary limit, but a wider search should be able to operate // in that range without a problem return ( (availableSend < 6*1024) || (availableRecv < 6*1024) ); }

Constructor Summary
`SearchJob(RouterContext context, KademliaNetworkDatabaseFacade facade, Hash key, Job onSuccess, Job onFailure, long timeoutMs, boolean keepStats, boolean isLease)` Create a new search for the routingKey specified

Method Summary
`(package private) boolean` `add(Hash peer)`
`int` `addDeferred(Job onFind, Job onFail, long expiration, boolean isLease)`
`protected DatabaseLookupMessage` `buildMessage(TunnelId replyTunnelId, Hash replyGateway, long expiration)` Build the database search message
`protected void` `continueSearch()` Send a series of searches to the next available peers as selected by the routing table, but making sure no more than SEARCH_BREDTH are outstanding at any time
`(package private) void` `decrementOutstandingFloodfillSearches()`
`protected void` `fail()` Search totally failed
`protected int` `getBredth()` max # of concurrent searches
`long` `getExpiration()`
`protected KademliaNetworkDatabaseFacade` `getFacade()`
`String` `getName()` Descriptive name of the task
`protected int` `getPerPeerTimeoutMs()` Let each peer take up to the average successful search RTT
`protected int` `getPerPeerTimeoutMs(Hash peer)`
`protected SearchState` `getState()`
`long` `getTimeoutMs()`
`protected void` `newPeersFound(int numNewPeers)` We've gotten a search reply that contained the specified number of peers that we didn't know about before.
`(package private) static boolean` `onlyQueryFloodfillPeers(RouterContext ctx)` this is now misnamed, as it is only used to determine whether to return floodfill peers only

`(package private) void`

`replyFound(DatabaseSearchReplyMessage message, Hash peer)`
always send through the lease protected DatabaseLookupMessage buildMessage(long expiration) { DatabaseLookupMessage msg = new DatabaseLookupMessage(getContext(), true); msg.setSearchKey(_state.getTarget()); msg.setFrom(getContext().routerHash()); msg.setDontIncludePeers(_state.getClosestAttempted(MAX_CLOSEST)); msg.setMessageExpiration(expiration); msg.setReplyTunnel(null); return msg; }

`void` `runJob()` Actually perform the task.
`protected void` `searchNext()` Send the next search, or stop if its completed
`protected void` `sendLeaseSearch(RouterInfo router)` we're (probably) searching for a LeaseSet, so to be (overly) cautious, we're sending the request out through a tunnel w/ reply back through another tunnel.
`protected void` `sendSearch(RouterInfo router)` Send a search to the given peer
`(package private) long` `timeoutMs()`
`String` `toString()`
`(package private) boolean` `wasAttempted(Hash peer)`

Methods inherited from class net.i2p.router.JobImpl
`dropped, getAddedBy, getContext, getJobId, getMadeReadyOn, getTiming, madeReady, requeue`

Methods inherited from class java.lang.Object
`clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

Field Detail

### _log

    protected Log _log

### _facade

    protected KademliaNetworkDatabaseFacade _facade

### MAX_CLOSEST

    static final int MAX_CLOSEST

  only send the 10 closest "dont tell me about" refs

  See Also:
    Constant Field Values

### PER_FLOODFILL_PEER_TIMEOUT

    static final int PER_FLOODFILL_PEER_TIMEOUT

  static boolean isCongested(RouterContext ctx) { float availableSend = ctx.bandwidthLimiter().getOutboundKBytesPerSecond()*1024 - ctx.bandwidthLimiter().getSendBps(); float availableRecv = ctx.bandwidthLimiter().getInboundKBytesPerSecond()*1024 - ctx.bandwidthLimiter().getReceiveBps(); // 6KBps is an arbitrary limit, but a wider search should be able to operate // in that range without a problem return ( (availableSend < 6*1024) || (availableRecv < 6*1024) ); }

  See Also:
    Constant Field Values

### MIN_TIMEOUT

    static final long MIN_TIMEOUT

See Also:
  Constant Field Values

Constructor Detail

### SearchJob

    public SearchJob(RouterContext context,
                     KademliaNetworkDatabaseFacade facade,
                     Hash key,
                     Job onSuccess,
                     Job onFailure,
                     long timeoutMs,
                     boolean keepStats,
                     boolean isLease)

  Create a new search for the routingKey specified

Method Detail

### runJob

    public void runJob()

  Description copied from interface: `Job`
  Actually perform the task. This call blocks until the Job is complete.

### getState

    protected SearchState getState()

### getFacade

    protected KademliaNetworkDatabaseFacade getFacade()

### getExpiration

    public long getExpiration()

### getTimeoutMs

    public long getTimeoutMs()

### onlyQueryFloodfillPeers

    static boolean onlyQueryFloodfillPeers(RouterContext ctx)

  this is now misnamed, as it is only used to determine whether to return floodfill peers only

### getPerPeerTimeoutMs

    protected int getPerPeerTimeoutMs(Hash peer)

### getPerPeerTimeoutMs

    protected int getPerPeerTimeoutMs()

  Let each peer take up to the average successful search RTT

### searchNext

    protected void searchNext()

  Send the next search, or stop if its completed

### getBredth

    protected int getBredth()

  max # of concurrent searches

### continueSearch

    protected void continueSearch()

  Send a series of searches to the next available peers as selected by the routing table, but making sure no more than SEARCH_BREDTH are outstanding at any time

### sendSearch

    protected void sendSearch(RouterInfo router)

  Send a search to the given peer

### sendLeaseSearch

    protected void sendLeaseSearch(RouterInfo router)

  we're (probably) searching for a LeaseSet, so to be (overly) cautious, we're sending the request out through a tunnel w/ reply back through another tunnel.

### buildMessage

    protected DatabaseLookupMessage buildMessage(TunnelId replyTunnelId,
                                                 Hash replyGateway,
                                                 long expiration)

  Build the database search message

  Parameters:
    `replyTunnelId` - tunnel to receive replies through
    `replyGateway` - gateway for the reply tunnel
    `expiration` - when the search should stop

### replyFound

    void replyFound(DatabaseSearchReplyMessage message,
                    Hash peer)

  always send through the lease protected DatabaseLookupMessage buildMessage(long expiration) { DatabaseLookupMessage msg = new DatabaseLookupMessage(getContext(), true); msg.setSearchKey(_state.getTarget()); msg.setFrom(getContext().routerHash()); msg.setDontIncludePeers(_state.getClosestAttempted(MAX_CLOSEST)); msg.setMessageExpiration(expiration); msg.setReplyTunnel(null); return msg; }

### newPeersFound

    protected void newPeersFound(int numNewPeers)

  We've gotten a search reply that contained the specified number of peers that we didn't know about before.

### fail

    protected void fail()

  Search totally failed

### addDeferred

    public int addDeferred(Job onFind,
                           Job onFail,
                           long expiration,
                           boolean isLease)

### getName

    public String getName()

  Description copied from interface: `Job`
  Descriptive name of the task

### toString

    public String toString()

  Overrides:
    `toString` in class `JobImpl`

### wasAttempted

    boolean wasAttempted(Hash peer)

### timeoutMs

    long timeoutMs()

### add

    boolean add(Hash peer)

  Returns:
    true if peer was new

### decrementOutstandingFloodfillSearches

    void decrementOutstandingFloodfillSearches()