java.lang.Object
net.i2p.router.peermanager.PeerManager

class PeerManagerextends Object
Tracks peer capabilities and manages the periodic profile reorganization cycle.

Responsibilities: - Maintains `_peersByCapability` index (character → Set of Hash) for quick capability lookups - Runs Reorg on SimpleTimer2 which calls ProfileOrganizer.reorganize() at adaptive intervals (30s early uptime → 90s medium → 250s steady state) - Periodically stores profiles to disk via ProfilePersistenceHelper (every 15 min) - Loads stored profiles from disk on startup in a background thread - Selects peers for PeerTestJob via selectPeers(criteria) — PURPOSE_TEST only

Profile persistence: - Only Tier 1 (Active) and Tier 2 (Passive) profiles are written to disk - Gossip-only (Tier 3) profiles are kept in memory but never persisted - Profiles older than EXPIRE_AGE (7 days) are deleted after store.

  • Field Details

    • _log

      private final Log _log
      Logger for the peer manager.
    • _context

      private final RouterContext _context
      The router context.
    • _organizer

      private final ProfileOrganizer _organizer
      The organizer holding the peer profiles.
    • _persistenceHelper

      private final ProfilePersistenceHelper _persistenceHelper
      Helper reading and writing the profiles.
    • _peersByCapability

      private final Map<Character, Set<Hash>> _peersByCapability
      Peer hashes, by capability flag.
    • _capabilitiesByPeer

      private final Map<Hash,String> _capabilitiesByPeer
      Value strings are lower case.
    • _storeLock

      private final AtomicBoolean _storeLock
      True while the profiles are being stored.
    • _lastStore

      private volatile long _lastStore
      When the profiles were last stored.
    • _evictToggle

      private boolean _evictToggle
      Alternates the half of the peers evicted.
    • REORGANIZE_TIME

      private static final long REORGANIZE_TIME
      Interval between profile reorganizations.
      See Also:
    • REORGANIZE_TIME_MEDIUM

      private static final long REORGANIZE_TIME_MEDIUM
      Reorganization interval on slow routers.
      See Also:
    • REORGANIZE_TIME_LONG

      static final long REORGANIZE_TIME_LONG
      We don't want this much longer than the average connect time, as the CapacityCalculator now includes connection as a factor. This must also be less than 10 minutes, which is the shortest Rate contained in the profile, as the Rates must be coalesced.
      See Also:
    • REORGANIZES_PER_DAY

      static final int REORGANIZES_PER_DAY
      After first two hours of uptime ~= 246.
      See Also:
    • STORE_TIME

      private static final long STORE_TIME
      Interval between profile stores.
      See Also:
    • EXPIRE_AGE

      private static final long EXPIRE_AGE
      Age after which a profile is dropped.
      See Also:
    • ADDRESS_REFRESH_TIMEOUT_MS

      private static final long ADDRESS_REFRESH_TIMEOUT_MS
      Timeout for a RouterInfo lookup issued on behalf of a stored profile whose peer the netdb cannot resolve, in ms.
      See Also:
    • TRACKED_CAPS

      public static final String TRACKED_CAPS
      Capability letters the manager indexes its per-capability peer sets by.
      See Also:
  • Constructor Details

    • PeerManager

      public PeerManager(RouterContext context)
      Profiles are now loaded in a separate thread, so this should return quickly.
      Parameters:
      context - the router context, whose profile organizer and log manager seed the peer indexes
  • Method Details

    • storeProfiles

      void storeProfiles()
      Write active profiles to disk.
    • clearProfiles

      void clearProfiles()
      Drops every tracked peer profile and the capability index built from them, for a router that is not going to reuse this state.
    • selectPeers

      Set<Hash> selectPeers()
      All tracked peers from the organizer.
      Returns:
      the peer hashes, never null, empty if none are tracked
    • storeProfile

      private boolean storeProfile(Hash peer, long cutoff)
      Save a peer's profile to disk if it is still usable.
      Parameters:
      peer - the peer whose profile may be written to disk
      cutoff - only store if most recent activity is newer than this (absolute time)
      Returns:
      true if the profile was written to disk, false if it was skipped
    • isLowBandwidthPeer

      private boolean isLowBandwidthPeer(Hash peer)
      Is this peer in a bandwidth tier too low to be worth remembering across a restart?

      K, L, M and Unknown are the tiers a peer advertises when it cannot or will not commit bandwidth. Their profiles are still tracked in memory, where they matter to selection and to the fast/high-cap tiers; what is not worth the disk is the persisted history of a peer whose RouterInfo already tells us it will not host a tunnel usefully.

      A missing or unreadable RouterInfo is not treated as low bandwidth: absence of evidence is not evidence, and refusing to persist a peer we simply have not looked up yet would discard the very profiles a floodfill lookup would then have to rebuild.

      Parameters:
      peer - hash of the peer to classify
      Returns:
      true if the peer advertises K, L, M or Unknown bandwidth
    • loadProfilesInBackground

      private void loadProfilesInBackground()
      Load the profiles in a separate thread, so we don't spend forever in the constructor (slowing down the Router constructor via RouterContext.initAll()). This also instantiates Reorg, so only call this once.
    • loadProfiles

      void loadProfiles()
      This may take a long time - 30 seconds or more.
    • selectPeers

      List<Hash> selectPeers(PeerSelectionCriteria criteria)
      Find some peers that meet the criteria and we have the netDb info for locally. Returned list will not include ourselves.

      Only supports PURPOSE_TEST — used exclusively by PeerTestJob. Other purpose constants were removed; add new purposes as needed.

      Parameters:
      criteria - supplies the selection purpose and the minimum number of peers to gather before falling back
      Returns:
      up to the requested number of peer hashes, excluding ourselves; the list may be shorter or empty if too few peers are known
    • selectTestPeersNonBlocking

      List<Hash> selectTestPeersNonBlocking(int needed)
      Non-blocking test peer selection. Returns null if the read lock cannot be acquired (reorganize in progress). Used exclusively by PeerTestJob to avoid blocking the job queue thread.
      Parameters:
      needed - how many peers to gather at most
      Returns:
      selected peers, or null if lock not acquired
    • setCapabilities

      public void setCapabilities(Hash peer, String caps)
      Records the capability string a peer advertised and reindexes it in the per-capability lookup, dropping any capability it no longer holds.
      Parameters:
      peer - the router whose capabilities are being recorded
      caps - non-null, case is ignored
    • locked_getPeers

      private Set<Hash> locked_getPeers(char c)
      Locking no longer required.
      Parameters:
      c - the capability character, any case, lower-cased before the lookup
      Returns:
      the peers with that capability, null if none are tracked for it
    • removeCapabilities

      public void removeCapabilities(Hash peer)
      Remove all capabilities for the peer from the index.
      Parameters:
      peer - the router to drop from every capability bucket
    • getPeersByCapability

      public Set<Hash> getPeersByCapability(char capability)
      Every tracked peer advertising a capability.
      Parameters:
      capability - the advertised capability letter, matched case-insensitively
      Returns:
      an unmodifiable set, empty if no peer advertises it
    • countPeersByCapability

      public int countPeersByCapability(char capability)
      How many tracked peers advertise a capability.
      Parameters:
      capability - the advertised capability letter, matched case-insensitively
      Returns:
      the number of tracked peers advertising it, 0 if none