Skip to content
Snippets Groups Projects
Commit dd3b6173 authored by Marcel Samir Becker's avatar Marcel Samir Becker Committed by Sören Henning
Browse files

Added GuessStrategy Interface Implementation

parent bb97f1f4
No related branches found
No related tags found
1 merge request!210Add "Initial Guess" Search Strategy
package theodolite.strategies.searchstrategy
import io.quarkus.runtime.annotations.RegisterForReflection
import theodolite.util.Resource
/**
* Base class for the implementation of Guess strategies. Guess strategies are strategies to determine the resource
* demand we start with in our initial guess search strategy.
*/
@RegisterForReflection
abstract class GuessStrategy {
/**
* Computing the resource demand for the initial guess search strategy to start with.
*
* @param resources List of all possible [Resource]s.
* @param lastLowestResource Previous resource demand needed for the given load.
*
* @return Returns the resource demand to start the initial guess search strategy with or null
*/
abstract fun firstGuess(resources: List<Resource>, lastLowestResource: Resource?): Resource?
}
\ No newline at end of file
...@@ -8,23 +8,23 @@ import theodolite.util.Resource ...@@ -8,23 +8,23 @@ import theodolite.util.Resource
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
/** /**
* Search strategy implementation for determining the smallest suitable number of instances, which takes the * Search strategy implementation for determining the smallest suitable resource demand.
* resource demand of the previous load into account as a starting point for the search. * Starting with a resource amount provided by a guess strategy.
* *
* @param benchmarkExecutor Benchmark executor which runs the individual benchmarks. * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks.
* @param guessStrategy Strategy that provides us with a guess for the first resource amount.
*/ */
class InitialGuessSearchStrategy(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmarkExecutor) { class InitialGuessSearchStrategy(benchmarkExecutor: BenchmarkExecutor, guessStrategy: GuessStrategy) : SearchStrategy(benchmarkExecutor, guessStrategy) {
override fun findSuitableResource(load: LoadDimension, resources: List<Resource>, lastLowestResource: Resource?): Resource? { override fun findSuitableResource(load: LoadDimension, resources: List<Resource>, lastLowestResource: Resource?): Resource? {
var lastLowestResourceToUse = lastLowestResource if(guessStrategy == null){
logger.info { "Your InitialGuessSearchStrategy doesn't have a GuessStrategy. This is not supported." }
// This Search strategy needs a resource demand to start the search with, return null
// if this is not provided it will be set to the first resource of the given resource-list
if(lastLowestResource == null && resources.isNotEmpty()){
lastLowestResourceToUse = resources[0]
} }
var lastLowestResourceToUse = this.guessStrategy.firstGuess(resources, lastLowestResource)
if (lastLowestResourceToUse != null) { if (lastLowestResourceToUse != null) {
val resourcesToCheck: List<Resource> val resourcesToCheck: List<Resource>
val startIndex: Int = resources.indexOf(lastLowestResourceToUse) val startIndex: Int = resources.indexOf(lastLowestResourceToUse)
......
package theodolite.strategies.searchstrategy
import theodolite.util.Resource
/**
* This Guess strategy takes the minimal resource demand of the previous load, which is given as an argument for the
* firstGuess function.
*/
class PrevResourceMinGuess() : GuessStrategy(){
/**
* @param resources List of all possible [Resource]s.
* @param lastLowestResource Previous resource demand needed for the given load.
*
* @return the value of lastLowestResource if given otherwise the first element of the resource list or null
*/
override fun firstGuess(resources: List<Resource>, lastLowestResource: Resource?): Resource? {
if (lastLowestResource != null) return lastLowestResource
else if(resources.isNotEmpty()) return resources[0]
else return null
}
}
\ No newline at end of file
...@@ -9,14 +9,16 @@ import theodolite.util.Resource ...@@ -9,14 +9,16 @@ import theodolite.util.Resource
* Base class for the implementation for SearchStrategies. SearchStrategies determine the smallest suitable number of instances. * Base class for the implementation for SearchStrategies. SearchStrategies determine the smallest suitable number of instances.
* *
* @param benchmarkExecutor Benchmark executor which runs the individual benchmarks. * @param benchmarkExecutor Benchmark executor which runs the individual benchmarks.
* @param guessStrategy Guess strategy for the initial resource amount in case the InitialGuessStrategy is selected.
*/ */
@RegisterForReflection @RegisterForReflection
abstract class SearchStrategy(val benchmarkExecutor: BenchmarkExecutor) { abstract class SearchStrategy(val benchmarkExecutor: BenchmarkExecutor, val guessStrategy: GuessStrategy? = null) {
/** /**
* Find smallest suitable resource from the specified resource list for the given load. * Find smallest suitable resource from the specified resource list for the given load.
* *
* @param load the [LoadDimension] to be tested. * @param load the [LoadDimension] to be tested.
* @param resources List of all possible [Resource]s. * @param resources List of all possible [Resource]s.
* @param lastLowestResource Previous resource demand needed for the given load.
* *
* @return suitable resource for the specified load, or null if no suitable resource exists. * @return suitable resource for the specified load, or null if no suitable resource exists.
*/ */
......
...@@ -9,6 +9,7 @@ import theodolite.util.LoadDimension ...@@ -9,6 +9,7 @@ import theodolite.util.LoadDimension
import theodolite.util.Resource import theodolite.util.Resource
import theodolite.util.Results import theodolite.util.Results
import mu.KotlinLogging import mu.KotlinLogging
import theodolite.strategies.searchstrategy.PrevResourceMinGuess
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
...@@ -16,7 +17,7 @@ private val logger = KotlinLogging.logger {} ...@@ -16,7 +17,7 @@ private val logger = KotlinLogging.logger {}
class InitialGuessSearchStrategyTest { class InitialGuessSearchStrategyTest {
@Test @Test
fun testEnd2EndInitialGuessSearch() { fun testInitialGuessSearch() {
val mockResults = arrayOf( val mockResults = arrayOf(
arrayOf(true, true, true, true, true, true, true), arrayOf(true, true, true, true, true, true, true),
arrayOf(false, false, true, true, true, true, true), arrayOf(false, false, true, true, true, true, true),
...@@ -30,9 +31,10 @@ class InitialGuessSearchStrategyTest { ...@@ -30,9 +31,10 @@ class InitialGuessSearchStrategyTest {
val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) } val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) }
val results = Results() val results = Results()
val benchmark = TestBenchmark() val benchmark = TestBenchmark()
val guessStrategy = PrevResourceMinGuess()
val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo() val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5) val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
val strategy = InitialGuessSearchStrategy(benchmarkExecutor) val strategy = InitialGuessSearchStrategy(benchmarkExecutor,guessStrategy)
val actual: ArrayList<Resource?> = ArrayList() val actual: ArrayList<Resource?> = ArrayList()
val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 3, 4, 6).map { x -> Resource(x, emptyList()) }) val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 3, 4, 6).map { x -> Resource(x, emptyList()) })
...@@ -56,7 +58,7 @@ class InitialGuessSearchStrategyTest { ...@@ -56,7 +58,7 @@ class InitialGuessSearchStrategyTest {
} }
@Test @Test
fun testEnd2EndInitialGuessSearchLowerResourceDemandHigherLoad() { fun testInitialGuessSearchLowerResourceDemandHigherLoad() {
val mockResults = arrayOf( val mockResults = arrayOf(
arrayOf(true, true, true, true, true, true, true), arrayOf(true, true, true, true, true, true, true),
arrayOf(false, false, true, true, true, true, true), arrayOf(false, false, true, true, true, true, true),
...@@ -70,9 +72,10 @@ class InitialGuessSearchStrategyTest { ...@@ -70,9 +72,10 @@ class InitialGuessSearchStrategyTest {
val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) } val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) }
val results = Results() val results = Results()
val benchmark = TestBenchmark() val benchmark = TestBenchmark()
val guessStrategy = PrevResourceMinGuess()
val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo() val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5) val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
val strategy = InitialGuessSearchStrategy(benchmarkExecutor) val strategy = InitialGuessSearchStrategy(benchmarkExecutor,guessStrategy)
val actual: ArrayList<Resource?> = ArrayList() val actual: ArrayList<Resource?> = ArrayList()
val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 1, 4, 6).map { x -> Resource(x, emptyList()) }) val expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 1, 4, 6).map { x -> Resource(x, emptyList()) })
...@@ -96,7 +99,7 @@ class InitialGuessSearchStrategyTest { ...@@ -96,7 +99,7 @@ class InitialGuessSearchStrategyTest {
} }
@Test @Test
fun testEnd2EndInitialGuessSearchFirstNotDoable() { fun testInitialGuessSearchFirstNotDoable() {
val mockResults = arrayOf( val mockResults = arrayOf(
arrayOf(false, false, false, false, false, false, false), arrayOf(false, false, false, false, false, false, false),
arrayOf(false, false, true, true, true, true, true), arrayOf(false, false, true, true, true, true, true),
...@@ -110,9 +113,10 @@ class InitialGuessSearchStrategyTest { ...@@ -110,9 +113,10 @@ class InitialGuessSearchStrategyTest {
val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) } val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) }
val results = Results() val results = Results()
val benchmark = TestBenchmark() val benchmark = TestBenchmark()
val guessStrategy = PrevResourceMinGuess()
val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo() val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5) val benchmarkExecutor = TestBenchmarkExecutorImpl(mockResults, benchmark, results, listOf(sloChecker), 0, 0, 5)
val strategy = InitialGuessSearchStrategy(benchmarkExecutor) val strategy = InitialGuessSearchStrategy(benchmarkExecutor, guessStrategy)
val actual: ArrayList<Resource?> = ArrayList() val actual: ArrayList<Resource?> = ArrayList()
var expected: ArrayList<Resource?> = ArrayList(listOf(2, 3, 0, 4, 6).map { x -> Resource(x, emptyList()) }) var expected: ArrayList<Resource?> = ArrayList(listOf(2, 3, 0, 4, 6).map { x -> Resource(x, emptyList()) })
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment