in spectator-api/src/main/java/com/netflix/spectator/api/patterns/CardinalityLimiters.java [255:318]
private void updateCutoff() {
long now = clock.wallTime();
if (now - limiterTimestamp > REFRESH_INTERVAL && values.size() > n) {
lock.lock();
try {
if (now - limiterTimestamp > REFRESH_INTERVAL) {
limiterTimestamp = clock.wallTime();
List<Map.Entry<String, AtomicLong>> sorted = values.entrySet()
.stream()
.sorted(FREQUENT_ENTRY_COMPARATOR)
.collect(Collectors.toList());
final long maxCount = sorted.get(0).getValue().get();
Map.Entry<String, AtomicLong> min = sorted.get(Math.min(n - 1, sorted.size() - 1));
final String minKey = min.getKey();
final long minCount = min.getValue().get();
final long delta = Math.max(minCount / 2L, 1L);
final int numCloseToMin = (int) sorted.stream()
.map(e -> e.getValue().get())
.filter(v -> Math.abs(v - minCount) <= delta)
.count();
// Check for high churn
long previousCutoff = cutoff;
if (numCloseToMin > n) {
if (maxCount - minCount <= maxCount / 2L) {
// Max is close to min indicating more likelihood for churn with all values
cutoff = Math.max(previousCutoff, maxCount + delta);
updatesWithHighChurn = MAX_UPDATES;
} else {
// Try to cutoff the noisy tail without impacting higher frequency values
cutoff = Math.max(previousCutoff, minCount + delta);
updatesWithHighChurn += updatesWithHighChurn >= MAX_UPDATES ? 0 : 1;
}
sorted.stream().skip(10L * n).forEach(e -> values.remove(e.getKey()));
// Update the limiter and ensure highest frequency values are preserved
Function<String, String> newLimiter = first(n);
sorted.stream().limit(n).forEach(e -> newLimiter.apply(e.getKey()));
limiter = newLimiter;
} else {
cutoff = minCount - minCount / 10L;
values
.entrySet()
.removeIf(e -> e.getValue().get() <= minCount && e.getKey().compareTo(minKey) > 0);
// Decay the counts so new items will have a chance to catch up
values.values().forEach(v -> v.set(v.get() - v.get() / 10L));
// Replace the fallback limiter instance so new values will be allowed
updatesWithHighChurn -= updatesWithHighChurn > 0 ? 1 : 0;
if (updatesWithHighChurn == 0) {
limiter = first(n);
}
}
}
} finally {
lock.unlock();
}
}
}