@Override public void onSample(long startTime, long rtt, int inflight, boolean didDrop) { long endTime = startTime + rtt; if (rtt < MIN_RTT_THRESHOLD) { return; } final ImmutableSampleWindow currentSample; if (didDrop) { currentSample = sample.updateAndGet(current -> current.addDroppedSample(inflight)); } else { currentSample = sample.updateAndGet(window -> window.addSample(rtt, inflight)); } if (endTime > nextUpdateTime || currentSample.didDrop()) { synchronized (lock) { // Double check under the lock if (endTime > nextUpdateTime || sample.get().didDrop()) { ImmutableSampleWindow current = sample.get(); if (isWindowReady(current)) { sample.set(new ImmutableSampleWindow()); nextUpdateTime = endTime + Math.min( Math.max(current.getCandidateRttNanos() * 2, MIN_WINDOW_TIME), MAX_WINDOW_TIME); // +1 ensures that average rtt in nanos is never 0, which has a precond check in VegasLimit. delegate.onSample( startTime, current.getAverageRttNanos() + 1, current.getMaxInFlight(), didDrop); } } } } }
@Override public void onSample(long startTime, long rtt, int inflight, boolean didDrop) { long endTime = startTime + rtt; if (rtt < MIN_RTT_THRESHOLD) { return; } final ImmutableSampleWindow currentSample; if (didDrop) { currentSample = sample.updateAndGet(current -> current.addDroppedSample(inflight)); } else { currentSample = sample.updateAndGet(window -> window.addSample(rtt, inflight)); } if (endTime > nextUpdateTime || currentSample.didDrop()) { synchronized (lock) { // Double check under the lock if (endTime > nextUpdateTime || sample.get().didDrop()) { ImmutableSampleWindow current = sample.get(); if (isWindowReady(current)) { sample.set(new ImmutableSampleWindow()); nextUpdateTime = endTime + Math.min( Math.max(current.getCandidateRttNanos() * 2, MIN_WINDOW_TIME), MAX_WINDOW_TIME); // +1 ensures that average rtt in nanos is never 0, which has a precond check in VegasLimit. delegate.onSample( startTime, current.getAverageRttNanos() + 1, current.getMaxInFlight(), didDrop); } } } } }