/* * Copyright 2016 Naver Corp. * * 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.navercorp.pinpoint.common.server.bo.codec.stat; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * @author HyunGil Jeong */ public interface TestAgentStatDataPointFactory<T extends Number> { int MAX_NUM_TEST_VALUES = 20; Random RANDOM = new Random(); List<T> createConstantValues(T minValue, T maxValue); List<T> createConstantValues(T minValue, T maxValue, int numValues); List<T> createRandomValues(T minValue, T maxValue); List<T> createRandomValues(T minValue, T maxValue, int numValues); List<T> createIncreasingValues(T minValue, T maxValue, T minIncrement, T maxIncrement); List<T> createIncreasingValues(T minValue, T maxValue, T minIncrement, T maxIncrement, int numValues); List<T> createDecreasingValues(T minValue, T maxValue, T minDecrement, T maxDecrement); List<T> createDecreasingValues(T minValue, T maxValue, T minDecrement, T maxDecrement, int numValues); List<T> createFluctuatingValues(T minValue, T maxValue, T minFluctuation, T maxFluctuation); List<T> createFluctuatingValues(T minValue, T maxValue, T minFluctuation, T maxFluctuation, int numValues); TestAgentStatDataPointFactory<Short> SHORT = new TestAgentStatDataPointFactoryImpl<Short>() { @Override protected Short add(Short a, Short b) { return (short) (a.shortValue() + b.shortValue()); } @Override protected Short diff(Short a, Short b) { return (short) (a.shortValue() - b.shortValue()); } @Override protected Short createValue(Short minValue, Short maxValue) { short min = minValue; short max = maxValue; if (min > max) { throw new IllegalArgumentException("min is larger than max"); } else if (min == max) { return min; } else if (min < 0 && max > 0) { short positiveRandom = (short) RANDOM.nextInt(max); short negativeRandom = (short) RANDOM.nextInt(Math.abs(min)); if (RANDOM.nextInt(positiveRandom) > RANDOM.nextInt(negativeRandom)) { return positiveRandom; } else { return (short) (negativeRandom * -1); } } else { int value = RANDOM.nextInt(max - min); value -= min; return (short) value; } } }; TestAgentStatDataPointFactory<Integer> INTEGER = new TestAgentStatDataPointFactoryImpl<Integer>() { @Override protected Integer add(Integer a, Integer b) { return a.intValue() + b.intValue(); } @Override protected Integer diff(Integer a, Integer b) { return a.intValue() - b.intValue(); } @Override protected Integer createValue(Integer minValue, Integer maxValue) { int min = minValue; int max = maxValue; if (min > max) { throw new IllegalArgumentException("min is larger than max"); } else if (min == max) { return min; } else if (min < 0 && max > 0) { int positiveRandom = RANDOM.nextInt(max); int negativeRandom = RANDOM.nextInt(Math.abs(min)); if (RANDOM.nextInt(positiveRandom) > RANDOM.nextInt(negativeRandom)) { return positiveRandom; } else { return negativeRandom; } } else { int value = RANDOM.nextInt(max - min); value -= min; return value; } } }; TestAgentStatDataPointFactory<Long> LONG = new TestAgentStatDataPointFactoryImpl<Long>() { @Override protected Long add(Long a, Long b) { return a.longValue() + b.longValue(); } @Override protected Long diff(Long a, Long b) { return a.longValue() - b.longValue(); } @Override protected Long createValue(Long minValue, Long maxValue) { long min = minValue; long max = maxValue; if (min > max) { throw new IllegalArgumentException("min is larger than max"); } else if (min == max) { return min; } else if (min < 0 && max > 0) { long positiveRandom = getUnsignedRandom() % max; long negativeRandom = getUnsignedRandom() % Math.abs(min); if (getUnsignedRandom() % positiveRandom > getUnsignedRandom() % negativeRandom) { return positiveRandom; } else { return negativeRandom * -1; } } else { long value = getUnsignedRandom(); value %= max - min; value += min; return value; } } private long getUnsignedRandom() { return Math.abs(RANDOM.nextLong()); } }; abstract class TestAgentStatDataPointFactoryImpl<T extends Number> implements TestAgentStatDataPointFactory<T> { protected abstract T add(T a, T b); protected abstract T diff(T a, T b); protected abstract T createValue(T minValue, T maxValue); @Override public List<T> createConstantValues(T minValue, T maxValue) { final int numValues = RANDOM.nextInt(MAX_NUM_TEST_VALUES) + 1; return this.createConstantValues(minValue, maxValue, numValues); } @Override public List<T> createConstantValues(T minValue, T maxValue, int numValues) { T value = this.createValue(minValue, maxValue); List<T> values = new ArrayList<T>(numValues); for (int i = 0; i < numValues; ++i) { values.add(value); } return values; } @Override public List<T> createRandomValues(T minValue, T maxValue) { final int numValues = RANDOM.nextInt(MAX_NUM_TEST_VALUES) + 1; return this.createRandomValues(minValue, maxValue, numValues); } @Override public List<T> createRandomValues(T minValue, T maxValue, int numValues) { List<T> values = new ArrayList<T>(numValues); for (int i = 0; i < numValues; ++i) { T value = this.createValue(minValue, maxValue); values.add(value); } return values; } @Override public List<T> createIncreasingValues(T minValue, T maxValue, T minIncrement, T maxIncrement) { final int numValues = RANDOM.nextInt(MAX_NUM_TEST_VALUES) + 1; return this.createIncreasingValues(minValue, maxValue, minIncrement, maxIncrement, numValues); } @Override public List<T> createIncreasingValues(T minValue, T maxValue, T minIncrement, T maxIncrement, int numValues) { List<T> values = new ArrayList<T>(numValues); T value = this.createValue(minValue, maxValue); values.add(value); for (int i = 0; i < numValues - 1; ++i) { T increment = this.createValue(minIncrement, maxIncrement); value = add(value, increment); values.add(value); } return values; } @Override public List<T> createDecreasingValues(T minValue, T maxValue, T minDecrement, T maxDecrement) { final int numValues = RANDOM.nextInt(MAX_NUM_TEST_VALUES) + 1; return this.createDecreasingValues(minValue, maxValue, minDecrement, maxDecrement, numValues); } @Override public List<T> createDecreasingValues(T minValue, T maxValue, T minDecrement, T maxDecrement, int numValues) { List<T> values = new ArrayList<T>(numValues); T value = this.createValue(minValue, maxValue); values.add(value); for (int i = 0; i < numValues - 1; ++i) { T decrement = this.createValue(minDecrement, maxDecrement); value = diff(value, decrement); values.add(value); } return values; } @Override public List<T> createFluctuatingValues(T minValue, T maxValue, T minFluctuation, T maxFluctuation) { final int numValues = RANDOM.nextInt(MAX_NUM_TEST_VALUES) + 1; return this.createFluctuatingValues(minValue, maxValue, minFluctuation, maxFluctuation, numValues); } @Override public List<T> createFluctuatingValues(T minValue, T maxValue, T minFluctuation, T maxFluctuation, int numValues) { List<T> values = new ArrayList<T>(numValues); T value = this.createValue(minValue, maxValue); values.add(value); int sign = RANDOM.nextInt(2); for (int i = 0; i < numValues - 1; ++i) { T fluctuation = this.createValue(minFluctuation, maxFluctuation); // randomly add or substract fluctuation if (i % 2 == sign) { value = add(value, fluctuation); } else { value = diff(value, fluctuation); } values.add(value); } return values; } } }