/* * Copyright 2011 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.ipc.invalidation.util; import com.google.common.base.Preconditions; import java.util.Random; /** * An abstraction to "smear" values by a given percent. Useful for randomizing delays a little bit * so that (say) processes do not get synchronized on time inadvertently, e.g., a heartbeat task * that sends a message every few minutes is smeared so that all clients do not end up sending a * message at the same time. In particular, given a {@code delay}, returns a value that is randomly * distributed between [delay - smearPercent * delay, delay + smearPercent * delay] * */ public class Smearer { private final Random random; /** The percentage (0, 1.0] for smearing the delay. */ private double smearFraction; /** * Creates a smearer with the given random number generator. If {@code smearPercent} is 0, uses an * internal default for smearing. * <p> * REQUIRES: 0 < smearPercent <= 100 */ public Smearer(Random random, final int smearPercent) { Preconditions.checkState((smearPercent >= 0) && (smearPercent <= 100)); this.random = random; this.smearFraction = smearPercent / 100.0; } /** * Given a {@code delay}, returns a value that is randomly distributed between * [delay - smearPercent * delay, delay + smearPercent * delay] */ public int getSmearedDelay(int delay) { // Get a random number between -1 and 1 and then multiply that by the smear // fraction. double smearFactor = (2 * random.nextDouble() - 1.0) * smearFraction; return (int) Math.ceil(delay + delay * smearFactor); } /** Changes the smear percent of this object to be {@code smearPercent}. */ public void changeSmearPercent(int smearPercent) { } }