diff --git a/concurrency-limits-core/src/main/java/com/netflix/concurrency/limits/limit/functions/SquareRootFunction.java b/concurrency-limits-core/src/main/java/com/netflix/concurrency/limits/limit/functions/SquareRootFunction.java new file mode 100644 index 00000000..dbd5fc5c --- /dev/null +++ b/concurrency-limits-core/src/main/java/com/netflix/concurrency/limits/limit/functions/SquareRootFunction.java @@ -0,0 +1,34 @@ +package com.netflix.concurrency.limits.limit.functions; + +import java.util.function.Function; +import java.util.stream.IntStream; + +/** + * Specialized utility function used by limiters to calculate thredsholds using square root + * of the current limit. Here we pre-compute the square root of numbers up to 1000 because + * the square root operation can be slow. + */ +public final class SquareRootFunction implements Function { + static final int[] lookup = new int[1000]; + + static { + IntStream.range(0, 1000).forEach(i -> lookup[i] = (int)Math.sqrt(i)); + } + + private static final SquareRootFunction INSTANCE = new SquareRootFunction(); + + /** + * Create an instance of a function that returns : baseline + sqrt(limit) + * + * @param baseline + * @return + */ + public static Function create(int baseline) { + return INSTANCE.andThen(t -> t + baseline); + } + + @Override + public Integer apply(Integer t) { + return t < 1000 ? lookup[t] : (int)Math.sqrt(t); + } +} diff --git a/concurrency-limits-core/src/test/java/com/netflix/concurrency/limits/limit/functions/SquareRootFunctionTest.java b/concurrency-limits-core/src/test/java/com/netflix/concurrency/limits/limit/functions/SquareRootFunctionTest.java new file mode 100644 index 00000000..a1d3b5a2 --- /dev/null +++ b/concurrency-limits-core/src/test/java/com/netflix/concurrency/limits/limit/functions/SquareRootFunctionTest.java @@ -0,0 +1,26 @@ +package com.netflix.concurrency.limits.limit.functions; + +import java.util.function.Function; + +import org.junit.Assert; +import org.junit.Test; + +public class SquareRootFunctionTest { + @Test + public void confirm0Index() { + Function func = SquareRootFunction.create(4); + Assert.assertEquals(4, func.apply(0).intValue()); + } + + @Test + public void confirmMaxIndex() { + Function func = SquareRootFunction.create(4); + Assert.assertEquals(35, func.apply(999).intValue()); + } + + @Test + public void confirmOutofLookupRange() { + Function func = SquareRootFunction.create(4); + Assert.assertEquals(35, func.apply(1005).intValue()); + } +}