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
private val logger = KotlinLogging.logger {}
/**
* Search strategy implementation for determining the smallest suitable number of instances, which takes the
* resource demand of the previous load into account as a starting point for the search.
* Search strategy implementation for determining the smallest suitable resource demand.
* Starting with a resource amount provided by a guess strategy.
*
* @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? {
var lastLowestResourceToUse = lastLowestResource
// This Search strategy needs a resource demand to start the search with,
// 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]
if(guessStrategy == null){
logger.info { "Your InitialGuessSearchStrategy doesn't have a GuessStrategy. This is not supported." }
return null
}
var lastLowestResourceToUse = this.guessStrategy.firstGuess(resources, lastLowestResource)
if (lastLowestResourceToUse != null) {
val resourcesToCheck: List<Resource>
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
* 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 guessStrategy Guess strategy for the initial resource amount in case the InitialGuessStrategy is selected.
*/
@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.
*
* @param load the [LoadDimension] to be tested.
* @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.
*/
......
......@@ -9,6 +9,7 @@ import theodolite.util.LoadDimension
import theodolite.util.Resource
import theodolite.util.Results
import mu.KotlinLogging
import theodolite.strategies.searchstrategy.PrevResourceMinGuess
private val logger = KotlinLogging.logger {}
......@@ -16,7 +17,7 @@ private val logger = KotlinLogging.logger {}
class InitialGuessSearchStrategyTest {
@Test
fun testEnd2EndInitialGuessSearch() {
fun testInitialGuessSearch() {
val mockResults = arrayOf(
arrayOf(true, true, true, true, true, true, true),
arrayOf(false, false, true, true, true, true, true),
......@@ -30,9 +31,10 @@ class InitialGuessSearchStrategyTest {
val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) }
val results = Results()
val benchmark = TestBenchmark()
val guessStrategy = PrevResourceMinGuess()
val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
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 expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 3, 4, 6).map { x -> Resource(x, emptyList()) })
......@@ -56,7 +58,7 @@ class InitialGuessSearchStrategyTest {
}
@Test
fun testEnd2EndInitialGuessSearchLowerResourceDemandHigherLoad() {
fun testInitialGuessSearchLowerResourceDemandHigherLoad() {
val mockResults = arrayOf(
arrayOf(true, true, true, true, true, true, true),
arrayOf(false, false, true, true, true, true, true),
......@@ -70,9 +72,10 @@ class InitialGuessSearchStrategyTest {
val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) }
val results = Results()
val benchmark = TestBenchmark()
val guessStrategy = PrevResourceMinGuess()
val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
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 expected: ArrayList<Resource?> = ArrayList(listOf(0, 2, 2, 1, 4, 6).map { x -> Resource(x, emptyList()) })
......@@ -96,7 +99,7 @@ class InitialGuessSearchStrategyTest {
}
@Test
fun testEnd2EndInitialGuessSearchFirstNotDoable() {
fun testInitialGuessSearchFirstNotDoable() {
val mockResults = arrayOf(
arrayOf(false, false, false, false, false, false, false),
arrayOf(false, false, true, true, true, true, true),
......@@ -110,9 +113,10 @@ class InitialGuessSearchStrategyTest {
val mockResources: List<Resource> = (0..6).map { number -> Resource(number, emptyList()) }
val results = Results()
val benchmark = TestBenchmark()
val guessStrategy = PrevResourceMinGuess()
val sloChecker: BenchmarkExecution.Slo = BenchmarkExecution.Slo()
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()
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 register or to comment