Skip to content
Snippets Groups Projects
Commit d053d5c5 authored by Marcel Samir Becker's avatar Marcel Samir Becker
Browse files

Added GuessStrategy Interface Implementation

parent fca67aa6
Branches
Tags
1 merge request!215Redesign Strategy, Load, and Resources data types
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.
Please to comment