• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ben-manes / caffeine / #5683

26 Jul 2026 05:59AM UTC coverage: 99.907% (-0.05%) from 99.953%
#5683

push

github

ben-manes
Adapt the window by hit density with starvation-guarded probes

Large caches size the admission window by the within-sample hit density
of the two regions, ln(windowDensity / mainDensity), taking proportional
steps that are immune to the cross-sample hit rate swings of a phasey
workload. The signal is resident-only, so a region earning ~nothing is
its blind state: it cannot see what a different split would earn, and
holding such a position can pin the window at an extreme (constructible
steady-state workloads pinned it ~28pp below LRU at any scale).

Starved samples at a blind corner therefore probe by hit rate. Walks
are bounded by a sample budget, by a reversal that crosses back through
the probe's start, and by an absolute hit rate veto that undoes damage;
the density signal adjudicates each endpoint under strict confirmation.
A crash re-arms the refractory without doubling, since an exogenous
workload shift is indistinguishable from probe damage and mispricing it
would starve the re-exploration the shift calls for. Escalating
commitment resolves the stray-exit dilemma: first-round probes exit
cheaply when the watched region earns without density confirmation
(stray and transferred hits scale with a region's size, and thin-signal
workloads correctly at the floor must not pay deep-walk displacement),
while each adjudicated failure lengthens the refractory ladder and its
deeper rungs commit the walk past the stray zone, converting a deep
silent reuse band from an absorbing pin into a bounded, temporary dip.
Deep rungs also stride at 2x and 4x (capped at the 30% max step): the
ladder previously bought a committed walk permission to pass the stray
zone but not speed, so deep reuse bands were reached only by outlasting
the budget, and stray walls calibrated wider than a flat stride's reach
were absorbing. Failed walks still undo in full, which is what
distinguishes this from the rejected travel-budget exits. The sample
period is capped by the sketch's e... (continued)

4285 of 4315 branches covered (99.3%)

186 of 191 new or added lines in 5 files covered. (97.38%)

8590 of 8598 relevant lines covered (99.91%)

1.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.77
/caffeine/src/main/java/com/github/benmanes/caffeine/cache/WindowClimber.java
1
/*
2
 * Copyright 2026 Ben Manes. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package com.github.benmanes.caffeine.cache;
17

18
import com.google.errorprone.annotations.Var;
19

20
/**
21
 * A hill climber that adapts the size of the admission window to balance the cache's recency and
22
 * frequency regions.
23
 *
24
 * @author ben.manes@gmail.com (Ben Manes)
25
 */
26
final class WindowClimber {
1✔
27

28
  /*
29
   * This class determines how to adapt the size of W-TinyLfu's admission window, which balances
30
   * the cache between recency (the window, admitting every new arrival) and frequency (the main
31
   * space, guarded by the TinyLfu filter). The best split is workload dependent, so it is climbed
32
   * online using the cache's own behavior as feedback. Small and medium caches climb reactively
33
   * on the hit rate: continue in the same direction while a sample's hit rate improves over the
34
   * previous sample's, reverse otherwise, and decay the step towards convergence. Large caches
35
   * instead compare the hit density (hits per slot) of the two regions within a single sample and
36
   * step proportionally, shifting capacity towards the region earning more per slot. That signal
37
   * is immune to workload phases but blind when a region is too starved to measure, so at those
38
   * corners the climber probes: it temporarily walks the window by the hit rate and keeps the new
39
   * position only if the density signal validates it, retreating and backing off otherwise.
40
   *
41
   * [1] The Density Climber, From First Principles
42
   * https://github.com/ben-manes/caffeine/.claude/docs/hill-climber-design.html
43
   */
44

45
  /** The difference in hit rates that restarts the climber. */
46
  static final double HILL_CLIMBER_RESTART_THRESHOLD = 0.05d;
47
  /** The percent of the total size to adapt the window by. */
48
  static final double HILL_CLIMBER_STEP_PERCENT = 0.0625d;
49
  /** The rate to decrease the step size to adapt by. */
50
  static final double HILL_CLIMBER_STEP_DECAY_RATE = 0.98d;
51
  /** Lower bound on the initial step size so that small caches have an opportunity to adapt. */
52
  static final double HILL_CLIMBER_MIN_INITIAL_STEP = 2.0d;
53
  /**
54
   * The size at/below which the hit-rate climber adapts slowly and deliberately: the window is only
55
   * a few integer entries (a 1%-of-512 window is ~5) and a single sample is too noisy to trust, so
56
   * it grows the window first, stretches its sample period as the step decays, and decays the step
57
   * slowly.
58
   */
59
  static final long HILL_CLIMBER_SLOW_ADAPT_THRESHOLD = 512L;
60
  /**
61
   * The size above which the window is sized by the density climber rather than the hit-rate
62
   * climber. The density signal, being resident-only, is both unreliable and prone to pinning at an
63
   * extreme when a region is small, and its within-sample gains only exceed the hit-rate climber's
64
   * above this size (they are ~neutral below it) — so it is scoped here to keep the hit-rate
65
   * climber's robustness at smaller sizes while adding density's wins for large caches.
66
   */
67
  static final long HILL_CLIMBER_DENSITY_THRESHOLD = 4096L;
68
  /** Maximum factor by which the sample period may grow in the slow-adapt regime. */
69
  static final double HILL_CLIMBER_SLOW_ADAPT_RATIO_CAP = 4.0d;
70
  /**
71
   * The step decay rate in the slow-adapt regime, slower to keep the step large enough for
72
   * restarts.
73
   */
74
  static final double HILL_CLIMBER_SLOW_ADAPT_DECAY_RATE = 0.995d;
75
  /**
76
   * The density climber's step per unit of log density-ratio error, as a fraction of the maximum.
77
   */
78
  static final double HILL_CLIMBER_DENSITY_GAIN = 0.03d;
79
  /** The density climber's largest single step, as a fraction of the maximum. */
80
  static final double HILL_CLIMBER_MAX_STEP_FRACTION = 0.30d;
81
  /**
82
   * The density climber's lower bound on the window as a fraction of the maximum. It is a
83
   * signal-capable floor, not merely off the zero cliff: below it a starved window catches too few
84
   * hits to estimate its own density, so the climber can pin there and never recover when the
85
   * workload turns recency-heavy. 2% keeps the window measurable at negligible cost to workloads
86
   * whose true optimum is smaller.
87
   */
88
  static final double HILL_CLIMBER_WINDOW_FLOOR_FRACTION = 0.02d;
89
  /**
90
   * The density climber's sample period, as a multiple of the maximum size. It is far shorter than
91
   * the sketch's 10x reset period so a large cache takes enough steps over a finite trace to reach
92
   * a large optimal window; kept at 4x (not lower) so brief, noisy density estimates near a small
93
   * converged window do not jitter it off a frequency-friendly optimum.
94
   */
95
  static final long HILL_CLIMBER_SAMPLE_MULTIPLIER = 4L;
96
  /**
97
   * The density climber's signal-capability bar: a region is starved when its hits in the sample
98
   * fall below requestCount >> shift (0.1%). A starved region cannot estimate its own density —
99
   * trapped regions measure ~2 orders of magnitude below this bar, while regions correctly at the
100
   * floor on frequency-biased workloads measure well above it.
101
   */
102
  static final int HILL_CLIMBER_MIN_SIGNAL_SHIFT = 10;
103
  /**
104
   * The initial refractory period after a failed probe, in samples; doubles per failure so that
105
   * workloads whose floor is genuinely correct pay a single bounded exploration cost.
106
   */
107
  static final int HILL_CLIMBER_PROBE_BACKOFF_INITIAL = 16;
108
  /** The longest refractory period between probes after repeated failures. */
109
  static final int HILL_CLIMBER_PROBE_BACKOFF_MAX = 64;
110
  /**
111
   * The number of samples a probe may walk without confirmation before it is judged a failed
112
   * experiment. Bounds every walk (stray hits scale with the region size and must not end one
113
   * early; a hit-rate veto cannot fire when the base rate is smaller than its threshold), while
114
   * comfortably exceeding the longest confirmed escape (a corner-to-corner traverse needs ~13
115
   * decaying steps). While probing, the refractory countdown field carries this budget — the two
116
   * uses cannot overlap.
117
   */
118
  static final int HILL_CLIMBER_PROBE_WALK_BUDGET = 16;
119

120
  double stepSize;
121
  long adjustment;
122
  long hitsInSample;
123
  long missesInSample;
124
  long windowHitsInSample;
125

126
  boolean probing;
127
  boolean probeDown;
128
  long probeBaseWindow;
129
  int probeBackoffLeft;
130
  int probeBackoffLength;
131
  double probeBaseHitRate;
132
  double previousSampleHitRate;
133

134
  /** Resets the state and seeds the step size when the cache's maximum size is changed. */
135
  void resized(long maximum) {
136
    resetSample();
1✔
137
    adjustment = 0;
1✔
138
    probing = false;
1✔
139
    probeBackoffLeft = 0;
1✔
140
    probeBackoffLength = HILL_CLIMBER_PROBE_BACKOFF_INITIAL;
1✔
141
    double stepSize = Math.max(HILL_CLIMBER_STEP_PERCENT * maximum,
1✔
142
        HILL_CLIMBER_MIN_INITIAL_STEP);
143
    this.stepSize = (maximum <= HILL_CLIMBER_SLOW_ADAPT_THRESHOLD) ? stepSize : -stepSize;
1✔
144
  }
1✔
145

146
  void resetSample() {
147
    previousSampleHitRate = 0.0;
1✔
148
    windowHitsInSample = 0;
1✔
149
    missesInSample = 0;
1✔
150
    hitsInSample = 0;
1✔
151
  }
1✔
152

153
  /** Records a cache hit on an entry residing in the window or main space. */
154
  void recordHit(boolean inWindow) {
155
    hitsInSample++;
1✔
156
    if (inWindow) {
1✔
157
      windowHitsInSample++;
1✔
158
    }
159
  }
1✔
160

161
  /** Records a cache miss. */
162
  void recordMiss() {
163
    missesInSample++;
1✔
164
  }
1✔
165

166
  /** Calculates the amount to adapt the window by and sets {@link #adjustment} accordingly. */
167
  void determineAdjustment(long maximum, long windowMaximum, int sketchSampleSize) {
168
    long requestCount = hitsInSample + missesInSample;
1✔
169
    if (requestCount < samplePeriod(maximum, sketchSampleSize)) {
1✔
170
      return;
1✔
171
    }
172

173
    double hitRate = (double) hitsInSample / requestCount;
1✔
174
    double amount = (maximum <= HILL_CLIMBER_DENSITY_THRESHOLD)
1✔
175
        ? reactiveStep(hitRate, maximum)
1✔
176
        : densityClimb(hitRate, requestCount, maximum, windowMaximum);
1✔
177
    previousSampleHitRate = hitRate;
1✔
178
    adjustment = (long) amount;
1✔
179
    windowHitsInSample = 0;
1✔
180
    missesInSample = 0;
1✔
181
    hitsInSample = 0;
1✔
182
  }
1✔
183

184
  /** The number of requests in an adaptation sample, by the size tier. */
185
  @SuppressWarnings("MathClampDouble")
186
  private long samplePeriod(long maximum, int sketchSampleSize) {
187
    if (maximum > HILL_CLIMBER_DENSITY_THRESHOLD) {
1✔
188
      // The density climber adapts far more often than the sketch ages: its within-sample hit
189
      // density needs only enough requests to estimate each region's hits-per-entry, so a period
190
      // well below the sketch's 10x reset lets a large cache take many steps over a finite trace
191
      // and reach a large optimal window. The sketch's own sample is the ceiling: it is entry
192
      // denominated, whereas a weighted maximum is in weight units, multiplying it against a
193
      // request counter would inflate the period by the mean entry weight and freeze adaptation,
194
      // and the multiplication of a near-Long.MAX_VALUE maximum overflows.
195
      @Var long period = HILL_CLIMBER_SAMPLE_MULTIPLIER * maximum;
1✔
196
      if ((period / HILL_CLIMBER_SAMPLE_MULTIPLIER) != maximum) {
1✔
197
        period = Long.MAX_VALUE;
1✔
198
      }
199
      return Math.min(period, sketchSampleSize);
1✔
200
    } else if (maximum <= HILL_CLIMBER_SLOW_ADAPT_THRESHOLD) {
1✔
201
      // Grows the sample period as the step size decays to avoid converging near the initial ratio
202
      double initialStep = HILL_CLIMBER_STEP_PERCENT * maximum;
1✔
203
      double magnitude = Math.max(Math.abs(stepSize),
1✔
204
          initialStep / HILL_CLIMBER_SLOW_ADAPT_RATIO_CAP);
205
      double ratio = (magnitude == 0.0)
1✔
206
          ? 1.0
1✔
207
          : Math.max(1.0, Math.min(HILL_CLIMBER_SLOW_ADAPT_RATIO_CAP, initialStep / magnitude));
1✔
208
      return (long) (sketchSampleSize * ratio);
1✔
209
    }
210

211
    // Between the thresholds, the hit-rate climber uses the sketch's standard period
212
    return sketchSampleSize;
1✔
213
  }
214

215
  /** The step decay rate, slower in the slow-adapt regime to keep restarts reachable. */
216
  private static double stepDecayRate(long maximum) {
217
    return (maximum <= HILL_CLIMBER_SLOW_ADAPT_THRESHOLD)
1✔
218
        ? HILL_CLIMBER_SLOW_ADAPT_DECAY_RATE
1✔
219
        : HILL_CLIMBER_STEP_DECAY_RATE;
1✔
220
  }
221

222
  /**
223
   * The hit-rate-comparison climber for small and medium caches: walk in the direction that
224
   * improved the hit rate, decaying the step and restarting on a workload shift.
225
   */
226
  private double reactiveStep(double hitRate, long maximum) {
227
    double hitRateChange = hitRate - previousSampleHitRate;
1✔
228
    double amount = (hitRateChange >= 0) ? stepSize : -stepSize;
1✔
229
    stepSize = (Math.abs(hitRateChange) >= HILL_CLIMBER_RESTART_THRESHOLD)
1✔
230
        ? Math.copySign(
1✔
231
            Math.max(HILL_CLIMBER_STEP_PERCENT * maximum, HILL_CLIMBER_MIN_INITIAL_STEP), amount)
1✔
232
        : (stepDecayRate(maximum) * amount);
1✔
233
    return amount;
1✔
234
  }
235

236
  /**
237
   * The density climber for large caches directs and sizes the window step from the within-sample
238
   * hit density of the two regions. The signed error is ln(windowDensity / mainDensity): positive
239
   * when the admission window earns more hits per entry than the main space, so capacity is more
240
   * valuable in the window and it should grow; negative otherwise. The step is that error scaled
241
   * by a gain, so a tiny window on a recency-heavy workload takes a large step and reaches its
242
   * optimum in a few samples, while near the balance point the step shrinks to zero and the window
243
   * settles. Being computed inside one sample it is immune to the cross-sample hit-rate swings
244
   * that phasey workloads impose, which otherwise bury the window's shallow gradient and leave the
245
   * climber stuck. A signal-capable floor keeps the window large enough to estimate its own
246
   * density, so it cannot collapse to a starved size and pin there when the workload turns
247
   * recency-heavy.
248
   * <p>
249
   * The density signal is resident-only, so a region earning ~nothing is its blind state: it
250
   * cannot see what a different split WOULD earn, and trusting such a sample can pin the window at
251
   * an extreme forever. Starved samples therefore fall back to a goal-driven probe: a bold-driver
252
   * walk out of the blind corner that reverses only on a crash-scale hit-rate drop (so plateau
253
   * crossings persist through workload jitter). The probe ends when its own damage aborts it, or
254
   * when the watched region earns enough for the density signal to adjudicate: a validated
255
   * position is kept (a reuse band was found), while a rejected one is undone with exponentially
256
   * longer refractory periods between attempts — so workloads whose small window is genuinely
257
   * correct pay one bounded exploration cost and then hold still.
258
   */
259
  private double densityClimb(double hitRate, long requestCount, long maximum, long windowMax) {
260
    long windowHits = windowHitsInSample;
1✔
261
    long mainHits = (hitsInSample - windowHits);
1✔
262
    double floor = HILL_CLIMBER_WINDOW_FLOOR_FRACTION * maximum;
1✔
263
    double windowDensity = (windowHits / (double) Math.max(1L, windowMax));
1✔
264
    double mainDensity = (mainHits / (double) Math.max(1L, maximum - windowMax));
1✔
265
    double error = Math.log((windowDensity + 1e-9) / (mainDensity + 1e-9));
1✔
266
    long bar = Math.max(4, requestCount >> HILL_CLIMBER_MIN_SIGNAL_SHIFT);
1✔
267
    boolean windowStarved = (windowHits < bar);
1✔
268
    boolean mainStarved = (mainHits < bar);
1✔
269
    if (probing) {
1✔
270
      switch (probeEnding(hitRate, error, windowHits, mainHits, bar)) {
1✔
271
        case CRASHED:
272
          return undoProbe(/* failed= */ false, windowMax);
1✔
273
        case FAILED:
274
          return undoProbe(/* failed= */ true, windowMax);
1✔
275
        case WALKING:
276
          return walkStep(/* entry= */ false, hitRate, maximum, windowMax, floor);
1✔
277
        case CONFIRMED:
278
          break;  // the validated position is held by the density step below
1✔
279
      }
280
    } else if (armProbe(hitRate, maximum, windowMax, windowStarved, mainStarved)) {
1✔
281
      return walkStep(/* entry= */ true, hitRate, maximum, windowMax, floor);
1✔
282
    }
283
    return densityStep(error, maximum, windowMax, floor);
1✔
284
  }
285

286
  /** How the probe's walk ends, judged once the sample completes. */
287
  private ProbeEnding probeEnding(double hitRate, double error,
288
      long windowHits, long mainHits, long bar) {
289
    double probeDirection = probeDown ? -1.0 : 1.0;
1✔
290
    long watched = probeDown ? mainHits : windowHits;
1✔
291
    if (hitRate <= (probeBaseHitRate - HILL_CLIMBER_RESTART_THRESHOLD)) {
1✔
292
      // The hit rate collapsed below the probe's start, so the movement is undone. The
293
      // collapse may be the probe's own damage or an exogenous workload shift which are
294
      // indistinguishable here, so the refractory re-arms at its current length instead of
295
      // doubling: mispricing a workload phase as a failed experiment would starve the very
296
      // re-exploration the shift calls for.
297
      probing = false;
1✔
298
      return ProbeEnding.CRASHED;
1✔
299
    } else if ((watched >= (4 * bar))
1✔
300
        && ((HILL_CLIMBER_PROBE_WALK_BUDGET - probeBackoffLeft) >= probeCommitment())) {
1✔
301
      // The watched region earns enough to judge. Density confirming the probed direction is
302
      // a reuse band: keep the position, let density take over, and make probes cheap again.
303
      // Anything else is a completed, failed experiment: stray and transferred hits reach
304
      // this bar on workloads whose small window is genuinely correct, so first probes must
305
      // exit cheaply on them, but the same physics ends a deep walk a stride short of a denser
306
      // reuse band, which would make that trap absorbing. Escalating commitment breaks the tie:
307
      // each adjudicated failure lengthens the refractory ladder, and the deeper rungs commit
308
      // the next walk past the stray zone before this exit may fire, so a steady trap is
309
      // escaped within a few rounds while short-lived probing on a healthy workload never
310
      // escalates far enough to pay the deep-walk cost.
311
      probing = false;
1✔
312
      if ((error * probeDirection) > 0.0) {
1✔
313
        probeBackoffLength = 1;
1✔
314
        probeBackoffLeft = 0;
1✔
315
        return ProbeEnding.CONFIRMED;
1✔
316
      }
317
      return ProbeEnding.FAILED;
1✔
318
    } else if (probeBackoffLeft == 0) {
1!
319
      // the walk budget is spent without any signal: undo and double the refractory
NEW
320
      probing = false;
×
NEW
321
      return ProbeEnding.FAILED;
×
322
    }
323
    return ProbeEnding.WALKING;
1✔
324
  }
325

326
  /**
327
   * A probe is justified only at a blind corner: the starved region is the small one (it cannot
328
   * measure itself), or the whole sample is dead. A large region earning nothing is visible to
329
   * density (the other region's share dominates) and needs no probe, e.g. a scan-filled main
330
   * earning zero next to a small window earning everything must NOT trigger a shrink probe of the
331
   * one region that is working.
332
   *
333
   * @return whether a probe was armed, making this sample the walk's entry stride
334
   */
335
  private boolean armProbe(double hitRate, long maximum, long windowMax,
336
      boolean windowStarved, boolean mainStarved) {
337
    boolean deadSample = windowStarved && mainStarved;
1!
338
    boolean windowBlind = windowStarved && (windowMax <= (maximum >>> 2));
1✔
339
    boolean mainBlind = mainStarved && (windowMax >= (maximum - (maximum >>> 2)));
1!
340
    if (deadSample || windowBlind || mainBlind) {
1!
341
      if (probeBackoffLeft > 0) {
1✔
342
        probeBackoffLeft = probeBackoffLeft - 1;  // refractory: act as if not starved
1✔
343
      } else {
344
        probing = true;
1✔
345
        probeBaseHitRate = hitRate;
1✔
346
        probeBaseWindow = windowMax;
1✔
347
        probeBackoffLeft = HILL_CLIMBER_PROBE_WALK_BUDGET;
1✔
348
        probeDown = mainBlind || (deadSample && (windowMax >= (maximum >>> 1)));
1!
349
        return true;
1✔
350
      }
351
    }
352
    return false;
1✔
353
  }
354

355
  /** Returns to where the probe started; only a completed failure escalates the ladder. */
356
  private double undoProbe(boolean failed, long windowMax) {
357
    if (failed) {
1✔
358
      probeBackoffLength = Math.min(HILL_CLIMBER_PROBE_BACKOFF_MAX, 2 * probeBackoffLength);
1✔
359
    }
360
    double amount = (probeBaseWindow - windowMax);
1✔
361
    probeBackoffLeft = probeBackoffLength;
1✔
362
    stepSize = amount;
1✔
363
    return amount;
1✔
364
  }
365

366
  /**
367
   * A bold-driver stride of the probe's walk: seeded at the restart magnitude in the probe
368
   * direction and scaled by the refractory rung (deep rungs bought a committed walk permission to
369
   * pass the stray zone but not speed, so stray walls calibrated wider than a flat stride's reach
370
   * were absorbing), reversing only on a crash-scale hit-rate drop so that plateau crossings
371
   * persist through workload jitter, and finishing as a failed experiment if a reversal would
372
   * cross back through the probe's own start rather than walking out the other side of the base.
373
   */
374
  private double walkStep(boolean entry, double hitRate,
375
      long maximum, long windowMax, double floor) {
376
    int rung = probeBackoffLength;
1✔
377
    double probeDirection = probeDown ? -1.0 : 1.0;
1!
378
    double strideScale = (rung >= HILL_CLIMBER_PROBE_BACKOFF_MAX) ? 4 : (rung >= 32) ? 2 : 1;
1!
379
    double restartMagnitude = Math.min(HILL_CLIMBER_MAX_STEP_FRACTION * maximum,
1✔
380
        strideScale * Math.max(
1✔
381
            HILL_CLIMBER_STEP_PERCENT * maximum, HILL_CLIMBER_MIN_INITIAL_STEP));
382

383
    @Var double step;
384
    if (entry) {
1✔
385
      step = probeDirection * restartMagnitude;
1✔
386
    } else {
387
      double hitRateChange = hitRate - previousSampleHitRate;
1✔
388
      step = (hitRateChange > -HILL_CLIMBER_RESTART_THRESHOLD) ? stepSize : -stepSize;
1✔
389
      step = (Math.abs(hitRateChange) >= HILL_CLIMBER_RESTART_THRESHOLD)
1✔
390
          ? Math.copySign(restartMagnitude, step)
1✔
391
          : (HILL_CLIMBER_STEP_DECAY_RATE * step);
1✔
392
      if (Math.abs(step) < HILL_CLIMBER_MIN_INITIAL_STEP) {
1!
NEW
393
        step = probeDirection * restartMagnitude;
×
394
      }
395
    }
396

397
    boolean completed = (probeDirection > 0.0)
1!
398
        ? ((windowMax + step) < probeBaseWindow)
1✔
399
        : ((windowMax + step) > probeBaseWindow);
1!
400
    if (completed) {
1✔
401
      // a reversal that crosses the probe's own start found nothing: finish as a completed,
402
      // failed experiment rather than walking out the other side of the base
403
      probeBackoffLength = Math.min(HILL_CLIMBER_PROBE_BACKOFF_MAX, 2 * probeBackoffLength);
1✔
404
      probeBackoffLeft = probeBackoffLength;
1✔
405
      step = probeBaseWindow - windowMax;
1✔
406
      probing = false;
1✔
407
    } else if ((step < 0) && ((windowMax + step) < floor)) {
1!
408
      // walks honor the signal-capable floor
NEW
409
      step = Math.min(0.0, floor - windowMax);
×
NEW
410
      probeBackoffLeft--;
×
411
    } else {
412
      probeBackoffLeft--;
1✔
413
    }
414
    stepSize = step;
1✔
415
    return step;
1✔
416
  }
417

418
  /** A proportional step by the density error, clamped to the signal-capable floor. */
419
  @SuppressWarnings("MathClampDouble")
420
  private double densityStep(double error, long maximum, long windowMax, double floor) {
421
    double magnitude = Math.min(HILL_CLIMBER_MAX_STEP_FRACTION * maximum,
1✔
422
        Math.abs(error) * HILL_CLIMBER_DENSITY_GAIN * maximum);
1✔
423
    double step = (error >= 0) ? magnitude : -magnitude;
1✔
424
    @Var double clamped = ((step < 0) && ((windowMax + step) < floor))
1✔
425
        ? Math.min(0.0, floor - windowMax)
1✔
426
        : step;
1✔
427
    if (windowMax < floor) {
1✔
428
      // keep the floor signal-capable: lift a below-floor window up to it
429
      clamped = Math.max(clamped, floor - windowMax);
1✔
430
    }
431
    stepSize = clamped;
1✔
432
    return clamped;
1✔
433
  }
434

435
  /** The walk samples a probe must take before stray hits may end it, from the ladder's rung. */
436
  private int probeCommitment() {
437
    int length = probeBackoffLength;
1✔
438
    return (length >= HILL_CLIMBER_PROBE_BACKOFF_MAX) ? 10 : (length >= 32) ? 2 : 0;
1!
439
  }
440

441
  /** How a probe's walk ends. */
442
  private enum ProbeEnding {
1✔
443
    /** The hit rate collapsed below the probe's start: undo without escalating the ladder. */
444
    CRASHED,
1✔
445
    /** Density validated the probed direction: keep the position and make probes cheap again. */
446
    CONFIRMED,
1✔
447
    /** A completed, failed experiment: undo and double the refractory ladder. */
448
    FAILED,
1✔
449
    /** No ending fired: take the next bold-driver stride. */
450
    WALKING
1✔
451
  }
452
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc