Skip to content
Snippets Groups Projects
Commit 940cf029 authored by Benedikt Wetzel's avatar Benedikt Wetzel
Browse files

add implementation for strategie related components


composite strategy,
binary search,
lower bound restriction,
some interfaces,
composite test

Co-authored-by: default avatarSimon Ehrenstein <stu200776@mail.uni-kiel.de>
parent 1525fb49
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 186 additions and 133 deletions
package theodolite
import theodolite.strategies.SearchAlgorithm
data class ExperimentConfig(
val useCase: Int,
val expId: Int,
val dimValues: Array<Int>,
val replicass: Array<Int>,
val partitions: Int,
val cpuLimit: String,
val memoryLimit: String,
val executionMinutes: Float,
val prometheusBaseUrl: String,
val reset: Boolean,
val namespace: String,
val resultPath: String,
val configurations: Any,
val restrictionStrategy: SearchAlgorithm,
val searchStrategy: SearchStrategy,
val benchmark: Any, // TODO
val sloChecker: Any // TODO
) {
}
\ No newline at end of file
package theodolite
class ExperimentExecutor(
val config: ExperimentConfig
) {
fun run() {
this.config.restrictionStrategy.restrictResource();
}
}
\ No newline at end of file
package theodolite
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.Produces
import javax.ws.rs.core.MediaType
@Path("/hello-resteasy")
class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
fun hello() = "Hello RESTEasy"
}
\ No newline at end of file
......@@ -7,28 +7,5 @@ object Main {
@JvmStatic
fun main(args: Array<String>) {
println("Starting Benchmarks")
val config: ExperimentConfig = ExperimentConfig(
exp_id = 0,
use_case = 1,
dim_values = arrayOf(1,2,3),
configurations = TODO(),
domain_restriction_strategy = TODO(),
cpu_limit = "1000m",
execution_minutes = 5f,
memory_limit = "4gb",
namespace = "default",
partitions = 10,
prometheus_base_url = "http://localhost:9090",
replicass = arrayOf(1,2,3),
reset = false,
result_path = "./results",
search_strategy = TODO(),
subexperiment_evaluator = TODO(),
subexperiment_executor = TODO()
)
val executor: ExperimentExecutor = ExperimentExecutor(config)
executor.run()
}
}
package theodolite.execution
import theodolite.util.LoadDimension
import theodolite.util.Resource
interface BenchmarkExecutor {
fun runExperiment(load: LoadDimension, res: Resource): Boolean;
}
\ No newline at end of file
package theodolite.execution
import theodolite.execution.BenchmarkExecutor
import theodolite.util.LoadDimension
import theodolite.util.Resource
class TestBenchmarkExecutor(val mockResults: Array<Array<Boolean>>): BenchmarkExecutor {
override fun runExperiment(load: LoadDimension, res: Resource): Boolean {
return this.mockResults[load.get()][res.get()]
}
}
\ No newline at end of file
package theodolite.strategies
import theodolite.strategies.searchstrategy.Benchmark
import theodolite.strategies.searchstrategy.SearchStrategy
class BinarySearch(benchmark: Benchmark) : SearchStrategy(benchmark) {
override fun findSuitableResources(load: Int, resources: List<Int>): Int {
}
}
\ No newline at end of file
package theodolite.strategies
import theodolite.strategies.restriction.CompositeRestriction
import theodolite.strategies.restriction.Restriction
class EvenResourcesRestriction(childRestriction: Restriction) : CompositeRestriction(childRestriction) {
override fun restrict(loads: List<Int>, resources: List<Int>) {
val filteredResources: List<Int> = resources.filter { x -> x % 2 == 0 };
this.childRestriction.restrict(loads, filteredResources);
}
}
\ No newline at end of file
package theodolite.strategies
import theodolite.strategies.searchstrategy.Benchmark
import theodolite.strategies.searchstrategy.SearchStrategy
class LinearSearch(benchmark: Benchmark) : SearchStrategy(benchmark) {
override fun findSuitableResources(load: Int, resources: List<Int>): Int {
for (res in resources) {
if (this.benchmark.execute(load, res)) return resources.indexOf(res);
}
return resources.size;
}
}
\ No newline at end of file
package theodolite.strategies
import theodolite.strategies.restriction.PrimitiveRestriction
import theodolite.strategies.searchstrategy.SearchStrategy
class LowerBoundRestriction(searchStrategy: SearchStrategy) : PrimitiveRestriction(searchStrategy) {
override fun restrict(loads: List<Int>, resources: List<Int>): List<Int> {
val lowerBounds: MutableList<Int> = ArrayList<Int>();
var lowerBound = 0;
for (load in loads) {
lowerBound = this.searchStrategy.findSuitableResources(load, resources.subList(lowerBound, resources.size));
lowerBounds.add(lowerBound);
}
return lowerBounds;
}
}
\ No newline at end of file
package theodolite.strategies.restriction
import theodolite.util.Results
import theodolite.strategies.searchstrategy.RestrictionStrategy
import theodolite.util.LoadDimension
import theodolite.util.Resource
class LowerBoundRestriction(results: Results, loads: List<LoadDimension>) : RestrictionStrategy(results, loads) {
override fun next(load: LoadDimension, resources: List<Resource>): List<Resource> {
var lowerBound: Resource? = this.results.getRequiredInstances(load)
if(lowerBound == null) {
lowerBound = Resource(0) // TODO handle the null case
}
return resources.filter{x -> x.get() >= lowerBound.get()}
}
}
\ No newline at end of file
package theodolite.strategies.searchstrategy
class Benchmark {
fun execute(load: Int, res: Int): Boolean {
return true;
}
}
\ No newline at end of file
package theodolite.strategies.searchstrategy
import theodolite.execution.BenchmarkExecutor
import theodolite.util.LoadDimension
import theodolite.util.Resource
import java.lang.IllegalArgumentException
class BinarySearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmarkExecutor) {
override fun findSuitableResources(load: LoadDimension, resources: List<Resource>): Resource? {
val result = search(load, resources, 0, resources.size - 1)
if( result == -1 ) {
return null;
}
return resources[result]
}
private fun search (load: LoadDimension, resources: List<Resource>, lower: Int, upper: Int): Int {
if (lower + 1 < upper ) {
throw IllegalArgumentException()
}
if (lower >= upper ) {
if (this.benchmarkExecutor.runExperiment(load, resources[upper])) return upper;
else {
if (lower + 1 == resources.size) return - 1
return lower + 1;
}
} else {
val mid = (upper + lower) / 2
if (this.benchmarkExecutor.runExperiment(load, resources[mid])) {
return search(load, resources, lower, mid - 1 );
} else {
return search(load, resources, mid + 1 , upper);
}
}
}
}
\ No newline at end of file
package theodolite.strategies.searchstrategy
import theodolite.execution.BenchmarkExecutor
import theodolite.util.LoadDimension
import theodolite.util.Resource
class CompositeStrategy(benchmarkExecutor: BenchmarkExecutor, val searchStrategy: SearchStrategy, val restrictionStrategies: List<RestrictionStrategy>) : SearchStrategy(benchmarkExecutor) {
override fun findSuitableResources(load: LoadDimension,resources: List<Resource>): Resource? {
var restrictedResources: List<Resource> = resources
for (strategy in this.restrictionStrategies) {
restrictedResources.intersect(strategy.next(load, resources))
}
return this.searchStrategy.findSuitableResources(load, restrictedResources)
}
}
\ No newline at end of file
package theodolite.strategies.searchstrategy
import theodolite.execution.BenchmarkExecutor
import theodolite.util.LoadDimension
import theodolite.util.Resource
class LinearSearch(benchmarkExecutor: BenchmarkExecutor) : SearchStrategy(benchmarkExecutor) {
override fun findSuitableResources(load: LoadDimension, resources: List<Resource>): Resource? {
for (res in resources) {
if (this.benchmarkExecutor.runExperiment(load, res)) return res;
}
return null;
}
}
\ No newline at end of file
package theodolite.strategies.searchstrategy
import theodolite.util.Results
import theodolite.util.LoadDimension
import theodolite.util.Resource
abstract class RestrictionStrategy(val results: Results, val loads: List<LoadDimension>) {
public abstract fun next(load: LoadDimension, resources: List<Resource>): List<Resource>;
}
\ No newline at end of file
package theodolite.strategies.searchstrategy
abstract class SearchStrategy(val benchmark: Benchmark) {
abstract fun findSuitableResources(load: Int, resources: List<Int>): Int;
import theodolite.execution.BenchmarkExecutor
import theodolite.util.LoadDimension
import theodolite.util.Resource
abstract class SearchStrategy(val benchmarkExecutor: BenchmarkExecutor) {
abstract fun findSuitableResources(load: LoadDimension, resources: List<Resource>): Resource?;
}
\ No newline at end of file
package theodolite.util
class LoadDimension(val number: Int) {
public fun get(): Int {
return this.number;
}
public override fun equals(other: Any?): Boolean {
if (other is LoadDimension) {
return this.get() == other.get()
}
return false
}
override fun hashCode(): Int {
return this.get().hashCode()
}
}
\ No newline at end of file
package theodolite.util
class Resource(val number: Int) {
public fun get(): Int {
return this.number;
}
public override fun equals(other: Any?): Boolean {
if (other is Resource) {
return this.get() == other.get()
}
return false
}
override fun hashCode(): Int {
return this.get().hashCode()
}
}
\ No newline at end of file
package theodolite.util
import theodolite.util.LoadDimension
import theodolite.util.Resource
import kotlin.math.exp
class Results {
// load, instances
private val results: MutableMap<Pair<LoadDimension, Resource>, Boolean> = mutableMapOf()
public fun setResult(experiment: Pair<LoadDimension, Resource>, successful: Boolean) {
this.results.put(experiment, successful)
}
public fun getResult (experiment: Pair<LoadDimension, Resource>): Boolean? {
return this.results.get(experiment)
}
public fun getRequiredInstances(load: LoadDimension): Resource? {
var requiredInstances: Resource? = null;
for(experiment in results) {
if(experiment.key.first == load && experiment.value){
if(requiredInstances == null) {
requiredInstances = experiment.key.second
}else if (experiment.key.second.get() < requiredInstances.get()) {
requiredInstances = experiment.key.second
}
}
}
return requiredInstances
}
}
\ No newline at end of file
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