Skip to content
Snippets Groups Projects
Commit 727e62b4 authored by Simon Ehrenstein's avatar Simon Ehrenstein
Browse files

Make use of the result object

parent 0fafc90d
No related branches found
No related tags found
4 merge requests!159Re-implementation of Theodolite with Kotlin/Quarkus,!157Update Graal Image in CI pipeline,!83WIP: Re-implementation of Theodolite with Kotlin/Quarkus,!78Resolve "Implement Quarkus/Kotlin protype"
Showing
with 139 additions and 33 deletions
package theodolite package theodolite
import io.quarkus.runtime.annotations.QuarkusMain import io.quarkus.runtime.annotations.QuarkusMain
import theodolite.execution.TheodoliteExecutor
@QuarkusMain @QuarkusMain
object Main { object Main {
@JvmStatic @JvmStatic
fun main(args: Array<String>) { fun main(args: Array<String>) {
println("Starting Benchmarks") val theodolite = TheodoliteExecutor();
theodolite.run()
} }
} }
package theodolite.execution package theodolite.execution
import theodolite.util.Benchmark
import theodolite.util.LoadDimension import theodolite.util.LoadDimension
import theodolite.util.Resource import theodolite.util.Resource
import theodolite.util.Results
interface BenchmarkExecutor { abstract class BenchmarkExecutor(val benchmark: Benchmark, val results: Results) {
fun runExperiment(load: LoadDimension, res: Resource): Boolean; abstract fun runExperiment(load: LoadDimension, res: Resource): Boolean;
} }
\ No newline at end of file
package theodolite.execution
import theodolite.util.Benchmark
import theodolite.util.LoadDimension
import theodolite.util.Resource
import theodolite.util.Results
class KafkaBenchmarkExecutor(benchmark: Benchmark, results: Results) : BenchmarkExecutor(benchmark, results) {
override fun runExperiment(load: LoadDimension, res: Resource): Boolean {
benchmark.start()
// wait
benchmark.stop();
// evaluate
val result = false // if success else false
this.results.setResult(Pair(load, res), result)
return result;
}
}
\ No newline at end of file
package theodolite.execution package theodolite.execution
import theodolite.execution.BenchmarkExecutor import theodolite.execution.BenchmarkExecutor
import theodolite.util.Benchmark
import theodolite.util.LoadDimension import theodolite.util.LoadDimension
import theodolite.util.Resource import theodolite.util.Resource
import theodolite.util.Results
class TestBenchmarkExecutor(val mockResults: Array<Array<Boolean>>): BenchmarkExecutor { class TestBenchmarkExecutor(private val mockResults: Array<Array<Boolean>>, benchmark: Benchmark, results: Results):
BenchmarkExecutor(benchmark, results) {
override fun runExperiment(load: LoadDimension, res: Resource): Boolean { override fun runExperiment(load: LoadDimension, res: Resource): Boolean {
System.out.println("load :" + load.get().toString() + ", res: " + res.get().toString()) val result = this.mockResults[load.get()][res.get()]
return this.mockResults[load.get()][res.get()]
System.out.println("load :" + load.get().toString() + ", res: " + res.get().toString() + ", res: " + result)
this.results.setResult(Pair(load, res), result)
return result;
} }
} }
\ No newline at end of file
package theodolite.execution
import theodolite.strategies.restriction.LowerBoundRestriction
import theodolite.strategies.searchstrategy.CompositeStrategy
import theodolite.strategies.searchstrategy.LinearSearch
import theodolite.util.*
class TheodoliteExecutor() {
private fun loadConfig(): Config {
val benchmark: Benchmark = KafkaBenchmark()
val results: Results = Results()
val executor: BenchmarkExecutor = KafkaBenchmarkExecutor(benchmark, results)
val restrictionStrategy = LowerBoundRestriction(results)
val searchStrategy = LinearSearch(executor, results)
return Config(
loads = (0..6).map{ number -> LoadDimension(number) },
resources = (0..6).map{ number -> Resource(number) },
compositeStrategy = CompositeStrategy(executor, searchStrategy, restrictionStrategies = setOf(restrictionStrategy), results = results)
)
}
fun run() {
// read or get benchmark config
val config = this.loadConfig()
// execute benchmarks for each load
for(load in config.loads) {
config.compositeStrategy.findSuitableResources(load, config.resources)
}
}
}
\ No newline at end of file
...@@ -3,14 +3,13 @@ package theodolite.strategies.restriction ...@@ -3,14 +3,13 @@ package theodolite.strategies.restriction
import theodolite.util.Results import theodolite.util.Results
import theodolite.util.LoadDimension import theodolite.util.LoadDimension
import theodolite.util.Resource import theodolite.util.Resource
import kotlin.math.max
class LowerBoundRestriction(results: Results) : RestrictionStrategy(results) { class LowerBoundRestriction(results: Results) : RestrictionStrategy(results) {
override fun next(load: LoadDimension, resources: List<Resource>): List<Resource> { override fun next(load: LoadDimension, resources: List<Resource>): List<Resource> {
val maxLoad: LoadDimension? = this.results.getMaxBenchmarkedLoad(load) val maxLoad: LoadDimension? = this.results.getMaxBenchmarkedLoad(load)
var lowerBound: Resource? = this.results.getRequiredInstances(maxLoad) var lowerBound: Resource? = this.results.getMinRequiredInstances(maxLoad)
if(lowerBound == null) { if(lowerBound == null) {
lowerBound = Resource(0) // TODO handle the null case lowerBound = resources.get(0)
} }
return resources.filter{x -> x.get() >= lowerBound.get()} return resources.filter{x -> x.get() >= lowerBound.get()}
} }
......
...@@ -26,10 +26,11 @@ class BinarySearch(benchmarkExecutor: BenchmarkExecutor, results: Results) : Sea ...@@ -26,10 +26,11 @@ class BinarySearch(benchmarkExecutor: BenchmarkExecutor, results: Results) : Sea
return lower + 1; return lower + 1;
} }
} else { } else {
// (true, true), (false, true), (false, false) // (false, false, false, true, false, true, false, true)
val mid = (upper + lower) / 2 val mid = (upper + lower) / 2
if (this.benchmarkExecutor.runExperiment(load, resources[mid])) { if (this.benchmarkExecutor.runExperiment(load, resources[mid])) {
if (mid == lower) { if (mid == lower) {
return search(load, resources, lower, lower ); return lower
} }
return search(load, resources, lower, mid - 1 ); return search(load, resources, lower, mid - 1 );
} else { } else {
......
...@@ -6,13 +6,13 @@ import theodolite.util.LoadDimension ...@@ -6,13 +6,13 @@ import theodolite.util.LoadDimension
import theodolite.util.Resource import theodolite.util.Resource
import theodolite.util.Results import theodolite.util.Results
class CompositeStrategy(benchmarkExecutor: BenchmarkExecutor, val searchStrategy: SearchStrategy, val restrictionStrategies: List<RestrictionStrategy>, results: Results) : SearchStrategy(benchmarkExecutor, results) { class CompositeStrategy(benchmarkExecutor: BenchmarkExecutor, val searchStrategy: SearchStrategy, val restrictionStrategies: Set<RestrictionStrategy>, results: Results) : SearchStrategy(benchmarkExecutor, results) {
override fun findSuitableResources(load: LoadDimension,resources: List<Resource>): Resource? { override fun findSuitableResources(load: LoadDimension, resources: List<Resource>): Resource? {
var restricted = resources var restrictedResources = resources.toList()
for (strategy in this.restrictionStrategies) { for (strategy in this.restrictionStrategies) {
restricted = restricted.intersect(strategy.next(load, resources)).toList() // erstellt das eine liste oder verändert das die liste? restrictedResources = restrictedResources.intersect(strategy.next(load, resources)).toList()
} }
return this.searchStrategy.findSuitableResources(load, restricted) return this.searchStrategy.findSuitableResources(load, restrictedResources)
} }
} }
\ No newline at end of file
...@@ -9,12 +9,7 @@ class LinearSearch(benchmarkExecutor: BenchmarkExecutor, results: Results) : Sea ...@@ -9,12 +9,7 @@ class LinearSearch(benchmarkExecutor: BenchmarkExecutor, results: Results) : Sea
override fun findSuitableResources(load: LoadDimension, resources: List<Resource>): Resource? { override fun findSuitableResources(load: LoadDimension, resources: List<Resource>): Resource? {
for (res in resources) { for (res in resources) {
if (this.benchmarkExecutor.runExperiment(load, res)) { if (this.benchmarkExecutor.runExperiment(load, res)) return res
this.results.setResult(Pair(load, res), true)
return res
} else {
this.results.setResult(Pair(load, res), false)
}
} }
return null; return null;
} }
......
package theodolite.util
// todo: needs cluster and resource config
interface Benchmark {
fun start();
fun stop();
}
\ No newline at end of file
package theodolite.util
import theodolite.strategies.restriction.RestrictionStrategy
import theodolite.strategies.searchstrategy.CompositeStrategy
import theodolite.strategies.searchstrategy.SearchStrategy
data class Config(
val loads: List<LoadDimension>,
val resources: List<Resource>,
val compositeStrategy: CompositeStrategy
) {
}
\ No newline at end of file
package theodolite.util
class KafkaBenchmark: Benchmark {
override fun start() {
TODO("Not yet implemented")
}
override fun stop() {
TODO("Not yet implemented")
}
}
\ No newline at end of file
...@@ -16,8 +16,10 @@ class Results { ...@@ -16,8 +16,10 @@ class Results {
return this.results.get(experiment) return this.results.get(experiment)
} }
public fun getRequiredInstances(load: LoadDimension?): Resource? { public fun getMinRequiredInstances(load: LoadDimension?): Resource? {
var requiredInstances: Resource? = null; if (this.results.isEmpty()) return Resource(Int.MIN_VALUE)
var requiredInstances: Resource? = Resource(Int.MAX_VALUE)
for(experiment in results) { for(experiment in results) {
if(experiment.key.first == load && experiment.value){ if(experiment.key.first == load && experiment.value){
if(requiredInstances == null) { if(requiredInstances == null) {
...@@ -31,13 +33,13 @@ class Results { ...@@ -31,13 +33,13 @@ class Results {
} }
public fun getMaxBenchmarkedLoad(load: LoadDimension): LoadDimension? { public fun getMaxBenchmarkedLoad(load: LoadDimension): LoadDimension? {
var maxBenchmarkedLoad: LoadDimension = LoadDimension(0) var maxBenchmarkedLoad: LoadDimension? = null;
for(experiment in results) { for(experiment in results) {
if (experiment.value) { if (experiment.value) {
if(experiment.key.first.get() <= load.get()) { if(experiment.key.first.get() <= load.get()) {
if (experiment.value && maxBenchmarkedLoad == null) { if (maxBenchmarkedLoad == null) {
maxBenchmarkedLoad = experiment.key.first maxBenchmarkedLoad = experiment.key.first
} else if (experiment.value && maxBenchmarkedLoad.get() < experiment.key.first.get()) { } else if (maxBenchmarkedLoad.get() < experiment.key.first.get()) {
maxBenchmarkedLoad = experiment.key.first maxBenchmarkedLoad = experiment.key.first
} }
} }
......
package theodolite.util
class TestBenchmark: Benchmark {
override fun start() {
TODO("Not yet implemented")
}
override fun stop() {
TODO("Not yet implemented")
}
}
\ No newline at end of file
...@@ -8,9 +8,7 @@ import theodolite.strategies.searchstrategy.BinarySearch ...@@ -8,9 +8,7 @@ import theodolite.strategies.searchstrategy.BinarySearch
import theodolite.strategies.restriction.LowerBoundRestriction import theodolite.strategies.restriction.LowerBoundRestriction
import theodolite.strategies.searchstrategy.CompositeStrategy import theodolite.strategies.searchstrategy.CompositeStrategy
import theodolite.execution.TestBenchmarkExecutor import theodolite.execution.TestBenchmarkExecutor
import theodolite.util.LoadDimension import theodolite.util.*
import theodolite.util.Resource
import theodolite.util.Results
@QuarkusTest @QuarkusTest
class CompositeStrategyTest { class CompositeStrategyTest {
...@@ -28,11 +26,12 @@ class CompositeStrategyTest { ...@@ -28,11 +26,12 @@ class CompositeStrategyTest {
) )
val mockLoads: List<LoadDimension> = (0..6).map{number -> LoadDimension(number)} val mockLoads: List<LoadDimension> = (0..6).map{number -> LoadDimension(number)}
val mockResources: List<Resource> = (0..6).map{number -> Resource(number)} val mockResources: List<Resource> = (0..6).map{number -> Resource(number)}
val benchmarkExecutor: TestBenchmarkExecutor = TestBenchmarkExecutor(mockResults)
val results: Results = Results(); val results: Results = Results();
val benchmark = TestBenchmark()
val benchmarkExecutor: TestBenchmarkExecutor = TestBenchmarkExecutor(mockResults, benchmark, results)
val linearSearch: LinearSearch = LinearSearch(benchmarkExecutor, results); val linearSearch: LinearSearch = LinearSearch(benchmarkExecutor, results);
val lowerBoundRestriction: LowerBoundRestriction = LowerBoundRestriction(results); val lowerBoundRestriction: LowerBoundRestriction = LowerBoundRestriction(results);
val strategy: CompositeStrategy = CompositeStrategy(benchmarkExecutor, linearSearch, listOf(lowerBoundRestriction), results) val strategy: CompositeStrategy = CompositeStrategy(benchmarkExecutor, linearSearch, setOf(lowerBoundRestriction), results)
val actual: ArrayList<Resource?> = ArrayList<Resource?>() val actual: ArrayList<Resource?> = ArrayList<Resource?>()
val expected: ArrayList<Resource?> = ArrayList(listOf(0,2,2,3,4,6).map{ x -> Resource(x)}) val expected: ArrayList<Resource?> = ArrayList(listOf(0,2,2,3,4,6).map{ x -> Resource(x)})
...@@ -58,11 +57,12 @@ class CompositeStrategyTest { ...@@ -58,11 +57,12 @@ class CompositeStrategyTest {
) )
val mockLoads: List<LoadDimension> = (0..6).map{number -> LoadDimension(number)} val mockLoads: List<LoadDimension> = (0..6).map{number -> LoadDimension(number)}
val mockResources: List<Resource> = (0..6).map{number -> Resource(number)} val mockResources: List<Resource> = (0..6).map{number -> Resource(number)}
val benchmarkExecutor: TestBenchmarkExecutor = TestBenchmarkExecutor(mockResults)
val results: Results = Results(); val results: Results = Results();
val benchmark = TestBenchmark()
val benchmarkExecutor: TestBenchmarkExecutor = TestBenchmarkExecutor(mockResults, benchmark, results)
val binarySearch: BinarySearch = BinarySearch(benchmarkExecutor, results); val binarySearch: BinarySearch = BinarySearch(benchmarkExecutor, results);
val lowerBoundRestriction: LowerBoundRestriction = LowerBoundRestriction(results); val lowerBoundRestriction: LowerBoundRestriction = LowerBoundRestriction(results);
val strategy: CompositeStrategy = CompositeStrategy(benchmarkExecutor, binarySearch, listOf(lowerBoundRestriction), results) // sets instead of lists val strategy: CompositeStrategy = CompositeStrategy(benchmarkExecutor, binarySearch, setOf(lowerBoundRestriction), results) // sets instead of lists
val actual: ArrayList<Resource?> = ArrayList<Resource?>() val actual: ArrayList<Resource?> = ArrayList<Resource?>()
val expected: ArrayList<Resource?> = ArrayList(listOf(0,2,2,3,4,6).map{ x -> Resource(x)}) val expected: ArrayList<Resource?> = ArrayList(listOf(0,2,2,3,4,6).map{ x -> Resource(x)})
......
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