See also main() below for additional commentary.
Currently, there is no 'ejection' strategy to get rid of the profiles for peers that are no longer active (or when the network consists of thousands of peers, to get rid of peers that are performing poorly). However, the size of each profile is fairly small, and is unrelated to how much data is collected about the peer, so that a router can keep a few thousand active peer profiles before the overhead becomes a serious concern. Once it becomes necessary, we can simply compact the poorly performing profiles (keeping only the most basic data) and maintain hundreds of thousands of profiles in memory. Beyond that size, we can simply eject the peers (e.g. keeping the best 100,000).
Field Summary
FieldsModifier and TypeFieldDescription(package private) static final longHow long a recorded first-hop RTT stays usable.(package private) static final longHalf-life of the decayed loss score: with no new transport report the score halves every 15 minutes, continuously.(package private) static final longAbsolute ceiling for the low-latency flag, in ms.(package private) static final longAbsolute floor for the low-latency flag, in ms.Constructor Summary
ConstructorsConstructorDescriptionPeerProfile(RouterContext context, Hash peer) Caller should call setLastHeardAbout() and setFirstHeardAbout().Method Summary
Modifier and TypeMethodDescriptionvoidClear the loss demotion flag after the peer has been re-admitted.(package private) voidCaller must next call updateValues().voidCoalesce all stats and update values.(package private) static floatdampLatency(float current, float sample) The one smoothing applied to every latency measurement, whatever measured it.(package private) voiddataPushed(long size) Record data pushed through this peer.(package private) voiddataPushed1m(long size) The tunnel pushed that much data in a 1 minute period.booleanvoidFor floodfills.voidWhen the given peer is performing well enough that we want to keep detailed stats on them again, call this to set up the info we dropped during shrinkProfile.intExtra factor added to the capacity ranking - set manually on the configpeers page to nudge how the algorithm ranks a peer.(package private) intThe raw capacity bonus value.floatHow many tunnels do we think this peer can handle over the next hour?(package private) RouterContextHelper for calculators.History of DB activity with the peer.How many new peers we get from dbSearchReplyMessages or dbStore messages.How long it takes to get a DB response from the peer (in milliseconds).longWhen did we first hear about this peer?intgetFirstHopRtt(long now) The direct-link RTT to this peer, or -1 when it is unknown or stale.longWhen the direct-link RTT was last refreshed.Floodfill reliability classification based on proven request-handling history.intExtra factor added to the integration ranking - this can be updated in the profile written to disk to affect how the algorithm ranks integration.floatHow well integrated into the network is this peer (as measured by how much they've told us that we didn't already know).booleanIs this peer active at the moment (sending/receiving messages within the last 10 minutes).booleangetIsActive(long now) Is this peer active at the moment (sending/receiving messages within the last 10 minutes).booleangetIsActive(long period, long now) Is this peer active at the moment (sending/receiving messages within the given period?) Also mark active if it is connected, as this will tend to encourage use of already-connected peers.booleanWhether the tunnel profile data has been allocated (RateStats, TunnelHistory).booleanWhether the DB profile data has been allocated.longWhen did we last hear about this peer?longWhen did we last hear from the peer?longWhen did we last have a problem sending to this peer?longWhen did we last send to this peer successfully?longWhen the peer last passed a tunnel test successfully.longThe timestamp of the last test start.(package private) longThe timestamp of the last throughput update.floatPacket-loss (retransmit) ratio reported by the transport, 0.0 = unknown/healthy.longWhen the loss ratio was last reported by the transport.floatgetLossScore(long now) Decayed loss score, the maximum of all loss ratios reported within the last few hours, with continuous time-based decay: 50% everyLOSS_DECAY_HALF_LIFE_MSsince the last report, capped at 16 half-lives (4 hours, effectively zero).longWhen the peer was last demoted from the fast/high-cap tiers for packet loss, or 0 if it was never demoted.getLowLatencyForFirstHopRtt(long now, long ceilingMs) Whether this peer counts as low latency, judged on its direct link.floatThe peak throughput in KBps.floatThis is the speed value.floatThe peak tunnel throughput in KBps.getPeer()What peer is being profiled.floatThe average peer test time.intRetained for backward compatibility with stored profile data.(package private) longLast update time of the speed bonus, for the 4-hour expiry.floatHow fast is the peer, taking into consideration both throughput and latency.doubleTunnel acceptance ratio from tunnel history.How long it takes to get a tunnel create response from the peer (in milliseconds).History of tunnel activity with the peer.floatEWMA average of the tunnel test response time.longTimestamp when the EWMA was last updated.(package private) intFor now, just a one-byte comparison.booleanWhether the peer has been tested (has a peer test response time average).booleanWhether this peer has non-trivial DB interaction activity.inthashCode()booleanWhether the peer has accepted or rejected at least one of our tunnel build requests.(package private) booleanIs this peer established?booleanisLossy()Whether the peer is currently in loss probation.booleanLow latency flag, set when this peer has been observed to respond quickly to tunnel build requests.(package private) booleanIs the peer in the same country as us?(package private) voidRecalculate the low-latency flag from the measured direct-link RTT.(package private) voidrecalculateLowLatency(Long calibratedFloorMs) Recompute the low-latency flag, optionally against a calibrated per-transport floor instead of the absolute one.(package private) voidrecalculateLowLatency(Long calibratedFloorMs, Long cohortFloorMs) Recompute the low-latency flag against the calibrated bounds.voidsetCapacityBonus(int bonus) Set the capacity bonus, restarting its 4-hour expiry clock.voidsetDBHistory(DBHistory hist) The DB history.(package private) voidsetFirstHeardAbout(long when) Remember when we first heard about this peer, only if older.voidsetFirstHopRtt(int rtt, long when) Record the transport's measured round trip time to this peer.voidsetFloodfillReliability(FloodfillReliability reliability) Set the floodfill reliability classification.voidsetIntegrationBonus(int bonus) The integration bonus.voidsetLastHeardAbout(long when) Remember when we last heard about this peer, only if unset or newer.voidsetLastHeardFrom(long when) When we last heard from the peer.voidsetLastSendFailed(long when) When we last had a problem sending to this peer.voidsetLastSendSuccessful(long when) When we last sent to this peer successfully.(package private) voidsetLastTestStarted(long ts) Store the timestamp of the last test start.(package private) voidsetLastThroughputUpdate(long ts) Store the timestamp of the last throughput update.voidsetLossRatio(float ratio, long now) Record the packet-loss ratio reported by the transport.voidsetLossySince(long when) Set when the peer is demoted from the fast/high-cap tiers for packet loss.voidsetLowLatency(boolean low) The low latency flag.(package private) voidsetPeakThroughputKBps(float kBps) Only for restoration from persisted profile.(package private) voidsetPeakTunnel1mThroughputKBps(float kBps) Only for restoration from persisted profile.(package private) voidsetPeakTunnelThroughputKBps(float kBps) Only for restoration from persisted profile.(package private) voidsetPeerTestTimeAverage(float testAvg) Store the average peer test time.voidsetSpeedBonus(int bonus) Retained for backward compatibility with stored profile data.(package private) voidsetSpeedBonusLastUpdate(long ts) Last update time of the speed bonus, for the 4-hour expiry.voidsetTunnelHistory(TunnelHistory history) The tunnel history.(package private) voidsetTunnelTestTimeAverage(float avg) The tunnel test time average.(package private) voidsetTunnelTestTimeAvgLastUpdate(long ts) The timestamp of the last tunnel test time average update.voidShrink the DB-specific part of the profile.voidShrink the profile by dropping the RateStat objects.toString()(package private) voidtunnelDataTransferred(long tunnelByteLifetime) The tunnel pushed that much data in its lifetime.(package private) voidupdatePeerTestTimeAverage(float ms) Update the peer test time average from a new measurement.(package private) voidupdateTunnelTestTimeAverage(float ms) Update the tunnel test time average with a new measurement.voidUpdate the speed, capacity, and integration values from the new values.booleanWas the peer previously unreachable?
Field Details
LOSS_DECAY_HALF_LIFE_MS
static final long LOSS_DECAY_HALF_LIFE_MSHalf-life of the decayed loss score: with no new transport report the score halves every 15 minutes, continuously. Chosen so a transient congestion episode (a 25-40% retransmit ratio) falls back under the 0.20 lossy threshold in roughly 20-40 minutes instead of the hour-plus an hourly-quantized decay imposed, while a peer that keeps reporting loss stays gated. Each report re-inflates the score through the max() fold insetLossRatio(float, long).- See Also:
FIRST_HOP_RTT_VALIDITY_MS
static final long FIRST_HOP_RTT_VALIDITY_MSHow long a recorded first-hop RTT stays usable.Four hours rather than the
RateConstants.ONE_HOURActive tier period thatgetLastSendSuccessful()uses. Link latency is a slow-changing property of a path, and it is now refreshed continuously byProfileOrganizer.sampleFirstHopRtts()on every reorganize, so this window no longer decides how current a measurement is -- it only decides how long a value outlives the session that produced it. An hour threw away measurements of peers we simply had not talked to lately, which is what left the profiles page 97% blank.The cost is that a peer whose session has gone away keeps its latency standing for up to four hours, and the low-latency bar is absolute, so a stale value is trusted as though current. If peer counts or the fast-tier mix look wrong after this, this constant is the first thing to lower.
- See Also:
LOW_LATENCY_CEILING_MS
static final long LOW_LATENCY_CEILING_MSAbsolute ceiling for the low-latency flag, in ms. Fixed, not derived from the network, so a rising average cannot promote genuinely slow peers.- See Also:
LOW_LATENCY_FLOOR_MS
static final long LOW_LATENCY_FLOOR_MSAbsolute floor for the low-latency flag, in ms. This is the binding criterion: a peer counts as low latency only if its direct-link RTT is at or below this value.This replaced a
0.5 * meanrelative test. The relative form was unsound for two reasons. First, the population it divided came from a decaying, self-selecting sample: an RTT is valid for one hour and refreshes only when we happen to send to that peer, so on a ~950 peer fast tier only ~37% carried a usable value and the mean tracked whoever we most recently happened to contact. A mean drawn from that set shrinks as it shrinks, so halving it ratchets the bar tighter over time. Second, the arithmetic did not discriminate. Measured against a live fast tier the mean was 86ms, so the bar sat at 43ms — below the population's own median of 60ms, which demoted two thirds of every measured peer rather than a tail.A fixed 100ms admits 69% and evicts 31% on that same population, which is the discrimination the flag was meant to provide. It also does not move as the sample decays, which was the defect that made the relative form unsafe to leave in place.
- See Also:
Constructor Details
PeerProfile
Caller should call setLastHeardAbout() and setFirstHeardAbout().- Parameters:
context- the router contextpeer- non-null
Method Details
getPeer
getIsExpanded
public boolean getIsExpanded()Whether the tunnel profile data has been allocated (RateStats, TunnelHistory). Profiles are created unexpanded and expanded lazily on first use.- Returns:
- true if expanded
getIsExpandedDB
public boolean getIsExpandedDB()Whether the DB profile data has been allocated.- Returns:
- true if expanded DB
isLowLatency
public boolean isLowLatency()Low latency flag, set when this peer has been observed to respond quickly to tunnel build requests. Persisted in profiles and used to seed fast/high-cap tiers at startup from prior session data.- Returns:
- true if low latency
setLowLatency
public void setLowLatency(boolean low) The low latency flag.- Parameters:
low- true for low latency
getLossRatio
public float getLossRatio()Packet-loss (retransmit) ratio reported by the transport, 0.0 = unknown/healthy.- Returns:
- ratio of retransmitted packets to transmitted packets
getLossRatioLastUpdate
public long getLossRatioLastUpdate()When the loss ratio was last reported by the transport.- Returns:
- time in ms
setLossRatio
public void setLossRatio(float ratio, long now) Record the packet-loss ratio reported by the transport.The reported ratio is folded into the decayed loss score (see
getLossScore(long)) so a single clean report does not erase recent loss history — the score only declines with time.- Parameters:
ratio- retransmitted / transmitted packets, 0.0 = healthynow- time in ms
getLossScore
public float getLossScore(long now) Decayed loss score, the maximum of all loss ratios reported within the last few hours, with continuous time-based decay: 50% everyLOSS_DECAY_HALF_LIFE_MSsince the last report, capped at 16 half-lives (4 hours, effectively zero). UnlikegetLossRatio()this retains loss memory when the transport stops reporting, so a demoted peer does not look clean again merely because its last sample went stale.- Parameters:
now- current time in ms- Returns:
- the decayed loss score, 0.0 if no loss was ever reported
getLossySince
public long getLossySince()When the peer was last demoted from the fast/high-cap tiers for packet loss, or 0 if it was never demoted. Persisted across restarts so loss probation survives a router reboot.- Returns:
- time of the last loss demotion in ms, or 0
setLossySince
public void setLossySince(long when) Set when the peer is demoted from the fast/high-cap tiers for packet loss. The peer must then produce fresh clean evidence before it is re-admitted (see ProfileOrganizer.shouldReadmitLossy).- Parameters:
when- demotion time in ms
clearLossy
public void clearLossy()Clear the loss demotion flag after the peer has been re-admitted.isLossy
public boolean isLossy()Whether the peer is currently in loss probation.- Returns:
- true if the peer was demoted for packet loss and not yet re-admitted
getIsActive
public boolean getIsActive()Is this peer active at the moment (sending/receiving messages within the last 10 minutes).- Returns:
- true if active
getIsActive
public boolean getIsActive(long now) Is this peer active at the moment (sending/receiving messages within the last 10 minutes).- Parameters:
now- the current clock reading in milliseconds- Returns:
- true if active
isEstablished
boolean isEstablished()Is this peer established?- Returns:
- true if established
wasUnreachable
public boolean wasUnreachable()Was the peer previously unreachable?- Returns:
- true if unreachable
isSameCountry
boolean isSameCountry()Is the peer in the same country as us?- Returns:
- true if same country
getXORDistance
int getXORDistance()For now, just a one-byte comparison.- Returns:
- -127 to +128, lower is closer
getIsActive
public boolean getIsActive(long period, long now) Is this peer active at the moment (sending/receiving messages within the given period?) Also mark active if it is connected, as this will tend to encourage use of already-connected peers.- Parameters:
period- look-back window in ms (10 minutes for the tier checks, 1 hour for the capacity calculator)now- the current clock reading in milliseconds- Returns:
- true if active
getFirstHeardAbout
public long getFirstHeardAbout()When did we first hear about this peer?- Returns:
- greater than zero, set to now in constructor
setFirstHeardAbout
void setFirstHeardAbout(long when) Remember when we first heard about this peer, only if older. Package private, only set by profile management subsystem.- Parameters:
when- the time to set
getLastHeardAbout
public long getLastHeardAbout()When did we last hear about this peer?- Returns:
- 0 if unset
setLastHeardAbout
public void setLastHeardAbout(long when) Remember when we last heard about this peer, only if unset or newer. Also sets FirstHeardAbout if earlier.- Parameters:
when- the time to set
getLastSendSuccessful
public long getLastSendSuccessful()When did we last send to this peer successfully?- Returns:
- milliseconds since the epoch, or 0 if never
setLastSendSuccessful
public void setLastSendSuccessful(long when) When we last sent to this peer successfully.- Parameters:
when- milliseconds since the epoch
dampLatency
static float dampLatency(float current, float sample) The one smoothing applied to every latency measurement, whatever measured it.Peer latency reaches the profile from three directions — a peer test's whole-tunnel round trip, the direct-link RTT a transport has measured for a live session, and an SSU/NTCP handshake. They are different quantities, but they are averaged the same way so that any one of them can be compared with any other: a value damped 25% per sample behaves the same whether the sample came from a tunnel round trip or a handshake.
An unknown or zero current value is replaced rather than averaged. A measurement is evidence; the absence of one is not, and damping toward zero would manufacture latency out of missing data.
- Parameters:
current- the stored average in ms, or 0/negative when unknownsample- the new measurement in ms- Returns:
- the new average in ms
setFirstHopRtt
public void setFirstHopRtt(int rtt, long when) Record the transport's measured round trip time to this peer.This is the direct link cost, which is what first-hop selection needs. A value of 0 means the session has not measured yet and is stored as unknown rather than as zero latency.
Damped through
dampLatency(float, float), the same smoothing the peer-test average uses, so a single session's noisy sample cannot set the value on its own. A value that has already gone stale is replaced rather than damped:getFirstHopRtt(long)has declared it unknown, so averaging toward it would let expired evidence drag a fresh measurement back.A sample older than the one already held is discarded outright. This is the single choke point every measurement passes through - the sampling pass, the pre-connect probe and the handshake recorder all land here - so the rule cannot be bypassed by a caller that forgot it. Without it a transport whose reading is old but not yet expired re-submits that same old number each cycle, which both drags the average back toward one stale sample and pushes the timestamp forward, so the staleness window never opens.
- Parameters:
rtt- measured round trip time in ms, 0 if unmeasuredwhen- timestamp of the measurement; must not predate the value held
getFirstHopRtt
public int getFirstHopRtt(long now) The direct-link RTT to this peer, or -1 when it is unknown or stale.Stale means older than
FIRST_HOP_RTT_VALIDITY_MS(4 hours), a window sized for the direct-link RTT itself rather than borrowed from the tier freshness windows.- Parameters:
now- current time in ms- Returns:
- the RTT in ms, or -1 if never measured or older than the window
getFirstHopRttTime
public long getFirstHopRttTime()When the direct-link RTT was last refreshed.- Returns:
- timestamp in ms, or 0 if never measured
getLowLatencyForFirstHopRtt
Whether this peer counts as low latency, judged on its direct link.The single low-latency decision:
recalculateLowLatency()is a thin wrapper over this, so the flag is derived one way everywhere. Two implementations of the same comparison is how the flag ends up disagreeing with itself depending on which pass happened to run last.Two drivers, both required, because either alone is misleading:
- an absolute ceiling, so a peer is never low latency merely because the whole network has slowed and every average rose with it;
- an absolute floor, so on a fast network a peer at the absolute ceiling is still not low if it sits at the typical value.
Only the direct link is consulted. Latency to this peer has nothing to do with how long a build or test involving other peers took.
- Parameters:
now- current time in msceilingMs- absolute low-latency ceiling in ms- Returns:
- TRUE or FALSE, or null when this peer has no usable first-hop RTT
getLastSendFailed
public long getLastSendFailed()When did we last have a problem sending to this peer?- Returns:
- milliseconds since the epoch, or 0 if never
setLastSendFailed
public void setLastSendFailed(long when) When we last had a problem sending to this peer.- Parameters:
when- milliseconds since the epoch
getLastHeardFrom
public long getLastHeardFrom()When did we last hear from the peer?- Returns:
- milliseconds since the epoch, or 0 if never
setLastHeardFrom
public void setLastHeardFrom(long when) When we last heard from the peer.- Parameters:
when- milliseconds since the epoch
getTunnelHistory
History of tunnel activity with the peer. Expands the profile lazily on first access.- Returns:
- TunnelHistory, non-null after first access
hasTunnelHistory
public boolean hasTunnelHistory()Whether the peer has accepted or rejected at least one of our tunnel build requests. Profiles without any tunnel history are not expanded, not persisted, and dropped from memory quickly.- Returns:
- true if the peer has participated in our tunnel building
hasDBActivity
public boolean hasDBActivity()Whether this peer has non-trivial DB interaction activity. Used to persist floodfill profiles across restarts so that lookup/store success rates survive and the peer is not misclassified as "too new" on the next startup.- Returns:
- true if the peer has any successful or failed lookups or stores
setTunnelHistory
The tunnel history.- Parameters:
history- the TunnelHistory to hold, retrieved by getTunnelHistory()
getTunnelAcceptanceRatio
public double getTunnelAcceptanceRatio()Tunnel acceptance ratio from tunnel history.- Returns:
- ratio (0.0 to 1.0), or 1.0 if no data available
getLastTestedSuccessfully
public long getLastTestedSuccessfully()When the peer last passed a tunnel test successfully.- Returns:
- timestamp, or 0 if never
getDBHistory
History of DB activity with the peer. Expands the DB profile lazily on first access.- Returns:
- DBHistory, non-null after first access
setDBHistory
The DB history.- Parameters:
hist- the DBHistory to hold, retrieved by getDBHistory()
getFloodfillReliability
Floodfill reliability classification based on proven request-handling history. Persisted across restarts.- Returns:
- reliability classification, never null
setFloodfillReliability
Set the floodfill reliability classification.- Parameters:
reliability- the classification, must not be null
getDbResponseTime
How long it takes to get a DB response from the peer (in milliseconds). Expands the DB profile lazily on first access.- Returns:
- RateStat, non-null after first access
getTunnelCreateResponseTime
How long it takes to get a tunnel create response from the peer (in milliseconds). Expands the profile lazily on first access. The profile is not expanded (and this returns null) until the peer has accepted or rejected at least one of our tunnel builds.- Returns:
- RateStat, or null if the peer has no tunnel history
getDbIntroduction
How many new peers we get from dbSearchReplyMessages or dbStore messages. Expands the DB profile lazily on first access.- Returns:
- RateStat, non-null after first access
getSpeedBonus
public int getSpeedBonus()Retained for backward compatibility with stored profile data. Returns 0 unconditionally if not set, or the stored value with a 4-hour expiry for existing profiles that still carry it.- Returns:
- the speed bonus
setSpeedBonus
public void setSpeedBonus(int bonus) Retained for backward compatibility with stored profile data.- Parameters:
bonus- the speed bonus
getSpeedBonusLastUpdate
long getSpeedBonusLastUpdate()Last update time of the speed bonus, for the 4-hour expiry. Only used by profile persistence.- Returns:
- the last update time
setSpeedBonusLastUpdate
void setSpeedBonusLastUpdate(long ts) Last update time of the speed bonus, for the 4-hour expiry. Only used by profile persistence.- Parameters:
ts- the last update time
getCapacityBonus
public int getCapacityBonus()Extra factor added to the capacity ranking - set manually on the configpeers page to nudge how the algorithm ranks a peer. Negative values are penalties. Expires 4 hours after the last manual update and is not persisted across a restart.- Returns:
- the capacity bonus
setCapacityBonus
public void setCapacityBonus(int bonus) Set the capacity bonus, restarting its 4-hour expiry clock. Live only - never written back to the profile file.- Parameters:
bonus- the capacity bonus
getCapacityBonusRaw
int getCapacityBonusRaw()The raw capacity bonus value.- Returns:
- the bonus before time-decay is applied
getIntegrationBonus
public int getIntegrationBonus()Extra factor added to the integration ranking - this can be updated in the profile written to disk to affect how the algorithm ranks integration. Negative values are penalties.- Returns:
- the integration bonus
setIntegrationBonus
public void setIntegrationBonus(int bonus) The integration bonus.- Parameters:
bonus- the integration bonus
getSpeedValue
public float getSpeedValue()How fast is the peer, taking into consideration both throughput and latency. This may even be made to take into consideration current rates vs. estimated (or measured) max rates, allowing this speed to reflect the speed /available/.- Returns:
- the speed value
getCapacityValue
public float getCapacityValue()How many tunnels do we think this peer can handle over the next hour?- Returns:
- the capacity value
getIntegrationValue
public float getIntegrationValue()How well integrated into the network is this peer (as measured by how much they've told us that we didn't already know). Higher numbers means better integrated.- Returns:
- the integration value
getTunnelTestTimeAverage
public float getTunnelTestTimeAverage()EWMA average of the tunnel test response time.Returns 0 if the data is older than 1 hour, treating the peer as untested. This ensures stale peers are re-tested rather than selected for tunnel builds based on outdated latency data.
- Returns:
- EWMA average in ms, or 0 if stale (>1 hour since last update)
getTunnelTestTimeAvgLastUpdate
public long getTunnelTestTimeAvgLastUpdate()Timestamp when the EWMA was last updated.- Returns:
- timestamp when the EWMA was last updated
setTunnelTestTimeAverage
void setTunnelTestTimeAverage(float avg) The tunnel test time average.- Parameters:
avg- the average in ms
setTunnelTestTimeAvgLastUpdate
void setTunnelTestTimeAvgLastUpdate(long ts) The timestamp of the last tunnel test time average update.- Parameters:
ts- milliseconds since the epoch of the last tunnel test time average update
updateTunnelTestTimeAverage
void updateTunnelTestTimeAverage(float ms) Update the tunnel test time average with a new measurement.- Parameters:
ms- the new measurement in ms
getPeerTestTimeAverage
public float getPeerTestTimeAverage()The average peer test time.- Returns:
- the peer test time average
setPeerTestTimeAverage
void setPeerTestTimeAverage(float testAvg) Store the average peer test time.- Parameters:
testAvg- the peer test time average
updatePeerTestTimeAverage
void updatePeerTestTimeAverage(float ms) Update the peer test time average from a new measurement.Damped through
dampLatency(float, float), the same smoothing every other latency writer uses, so a test result and a transport RTT and a handshake all accumulate into a comparable average.- Parameters:
ms- the new measurement in ms
hasBeenTested
public boolean hasBeenTested()Whether the peer has been tested (has a peer test response time average). Used by the bandwidth tier fast-track to distinguish "untested, give a chance" from "tested and known slow".- Returns:
- true if the peer has a measured peer test average
recalculateLowLatency
void recalculateLowLatency()Recalculate the low-latency flag from the measured direct-link RTT.The only low-latency decision in the codebase: both callers. The reorganize sampling pass and the recorder that runs when a measurement arrives — come through here, so the flag cannot be derived two different ways from the same field.
Judged on the direct link to this peer, not on how long a test through a multi-hop tunnel took.
getPeerTestTimeAverage()is the round trip across every hop of that tunnel, so using it here measured the latency of hops the peer was merely a member of.An unmeasured peer keeps whatever was persisted: absent evidence is not evidence of high latency.
recalculateLowLatency
Recompute the low-latency flag, optionally against a calibrated per-transport floor instead of the absolute one.This remains the single low-latency decision. The calibrated floor only supplies an alternative bar and never a separate verdict. It is deliberately one-directional: the floor is derived from measured link latencies across all peers, and nothing about this peer's tier membership feeds back into it, so no cycle can tighten the bar in response to the tiers that bar itself produces.
A null or negative
calibratedFloorMsmeans the transport has no calibrated opinion yet, and the absolute rule applies unchanged - so on a cold router the behaviour here is identical to it being absent.- Parameters:
calibratedFloorMs- the transport's calibrated floor in ms, or -1/null when unknown
recalculateLowLatency
Recompute the low-latency flag against the calibrated bounds.This remains the single low-latency decision. The calibrated values only supply alternative bars and never a separate verdict. It is deliberately one-directional: the floors are derived from measured link latencies across all peers, and nothing about this peer's tier membership feeds back into them, so no cycle can tighten a bar in response to the tiers that bar itself produces.
A null or negative value means that bound has no calibrated opinion yet and is skipped, leaving the absolute rule to decide alone. On a cold router both are null, so behaviour is identical to their absence.
Both calibrated bounds can only ever widen the absolute rule, never narrow it: the Organizer clamps the transport floor to at least
LOW_LATENCY_FLOOR_MS / multiple, and the cohort floor is applied only where the absolute rule already agreed.- Parameters:
calibratedFloorMs- the transport's calibrated floor in ms, or nullcohortFloorMs- the fast-cohort floor in ms, or null
getPeakThroughputKBps
public float getPeakThroughputKBps()The peak throughput in KBps.- Returns:
- the peak throughput in KBps
setPeakThroughputKBps
void setPeakThroughputKBps(float kBps) Only for restoration from persisted profile.- Parameters:
kBps- the peak throughput in KBps
dataPushed
void dataPushed(long size) Record data pushed through this peer.- Parameters:
size- the number of bytes pushed; long because the running total is a long and a per-period sum can exceed Integer.MAX_VALUE
tunnelDataTransferred
void tunnelDataTransferred(long tunnelByteLifetime) The tunnel pushed that much data in its lifetime.- Parameters:
tunnelByteLifetime- total bytes transferred
getPeakTunnelThroughputKBps
public float getPeakTunnelThroughputKBps()The peak tunnel throughput in KBps.- Returns:
- the peak tunnel throughput in KBps
setPeakTunnelThroughputKBps
void setPeakTunnelThroughputKBps(float kBps) Only for restoration from persisted profile.- Parameters:
kBps- the peak tunnel throughput in KBps
dataPushed1m
void dataPushed1m(long size) The tunnel pushed that much data in a 1 minute period.- Parameters:
size- the number of bytes in that minute, normalized; comparisons against the float ring widen, so the stored KBps average is unaffected
getPeakTunnel1mThroughputKBps
public float getPeakTunnel1mThroughputKBps()This is the speed value.- Returns:
- the average of the eight fastest one-minute data transfers (four on slow JVMs), on a per-tunnel basis, through this peer. Ever. Peaks are never decayed; only a higher measurement can raise them, and a lower one is ignored. Freshness is judged by the selection gates, not by eroding these values.
setPeakTunnel1mThroughputKBps
void setPeakTunnel1mThroughputKBps(float kBps) Only for restoration from persisted profile.- Parameters:
kBps- the peak 1-minute throughput in KBps
getLastThroughputUpdate
long getLastThroughputUpdate()The timestamp of the last throughput update.- Returns:
- the timestamp of the last throughput update
setLastThroughputUpdate
void setLastThroughputUpdate(long ts) Store the timestamp of the last throughput update.- Parameters:
ts- milliseconds since the epoch of the last throughput update
getLastTestStarted
public long getLastTestStarted()The timestamp of the last test start.- Returns:
- the timestamp of the last test start
setLastTestStarted
void setLastTestStarted(long ts) Store the timestamp of the last test start.- Parameters:
ts- milliseconds since the epoch of the last test start
expandProfile
public void expandProfile()When the given peer is performing well enough that we want to keep detailed stats on them again, call this to set up the info we dropped during shrinkProfile. This will not however overwrite any existing data, so it can be safely called repeatedly.expandDBProfile
public void expandDBProfile()For floodfills.shrinkProfile
public void shrinkProfile()Shrink the profile by dropping the RateStat objects. They will be re-created lazily by expandProfile() when the profile is used again.shrinkDBProfile
public void shrinkDBProfile()Shrink the DB-specific part of the profile.updateValues
public void updateValues()Update the speed, capacity, and integration values from the new values.coalesceStats
public void coalesceStats()Coalesce all stats and update values.coalesceOnly
void coalesceOnly()Caller must next call updateValues().No peak throughput value is decayed: coalescing only folds a new measurement into the peak arrays and never erases demonstrated capacity.
getContext
hashCode
equals
toString