summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Experiment.kt4
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/ExperimentRunner.kt7
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Scheduler.kt5
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/User.kt7
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Channel.kt55
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Port.kt34
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pullable.kt47
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pushable.kt18
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Receivable.kt44
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/AbstractSimulator.kt52
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Context.kt67
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulates.kt35
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulator.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/simulator/Simulator.kt)31
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/impl/MachineSimulator.kt44
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/sampler/Sampler.kt3
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Edge.kt80
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Entity.kt7
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Graph.kt12
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/GraphBuilder.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Node.kt)22
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Label.kt (renamed from opendc-core/src/main/kotlin/nl/atlarge/opendc/simulator/SimulatorContext.kt)15
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Rack.kt3
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Slot.kt5
-rw-r--r--opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt2
23 files changed, 518 insertions, 81 deletions
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Experiment.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Experiment.kt
index 7638b2c8..a4f947c8 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Experiment.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Experiment.kt
@@ -27,6 +27,8 @@ package nl.atlarge.opendc.experiment
/**
* A simulation of multiple simultaneous workloads running on top of a topology.
*
+ * @param id The unique identifier of the experiment.
+ * @param name The name of the experiment.
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-class Experiment {}
+data class Experiment(val id: Int, val name: String)
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/ExperimentRunner.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/ExperimentRunner.kt
index bb38de99..e53c6e08 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/ExperimentRunner.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/ExperimentRunner.kt
@@ -25,8 +25,15 @@
package nl.atlarge.opendc.experiment
/**
+ * An [ExperimentRunner] is responsible for executing an [Experiment].
*
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
interface ExperimentRunner {
+ /**
+ * Run the given [Experiment] using this runner.
+ *
+ * @param experiment The experiment to run.
+ */
+ fun run(experiment: Experiment)
}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Scheduler.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Scheduler.kt
index 713605e4..b2845963 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Scheduler.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/Scheduler.kt
@@ -25,7 +25,6 @@
package nl.atlarge.opendc.experiment
import nl.atlarge.opendc.topology.Entity
-import nl.atlarge.opendc.topology.Node
/**
* A task scheduler that is coupled to an [Entity] in the topology of the cloud network.
@@ -36,8 +35,8 @@ interface Scheduler<in E: Entity> {
/**
* Schedule the given jobs for the given entity.
*
- * @param node The node in the cloud network topology representing the entity.
+ * @param entity The entity in the cloud network topology representing the entity.
* @param jobs The jobs that have been submitted to the cloud network.
*/
- fun schedule(node: Node<E>, jobs: Set<Job>)
+ fun schedule(entity: E, jobs: Set<Job>)
}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/User.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/User.kt
index d97b980b..8bfba407 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/User.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/User.kt
@@ -24,7 +24,7 @@
package nl.atlarge.opendc.experiment
-import nl.atlarge.opendc.topology.Node
+import nl.atlarge.opendc.topology.Graph
/**
* A user of a cloud network that provides [Job]s for the simulation.
@@ -32,6 +32,9 @@ import nl.atlarge.opendc.topology.Node
* <p>Each [User] in a simulation has its own logical view of the cloud network which is used to route its jobs in the
* physical network.
*
+ * @param id The unique identifier of the user.
+ * @param name The name of the user.
+ * @param view The view of the user on the topology.
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-data class User(val id: Int, val name: String, val view: Node<*>) {}
+data class User(val id: Int, val name: String, val view: Graph)
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Channel.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Channel.kt
new file mode 100644
index 00000000..b33b720d
--- /dev/null
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Channel.kt
@@ -0,0 +1,55 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 atlarge-research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package nl.atlarge.opendc.experiment.messaging
+
+import nl.atlarge.opendc.topology.Entity
+import nl.atlarge.opendc.topology.Label
+
+/**
+ * A direct bi-directional communication channel between two [Entity] instances as seen from one of the entities.
+ *
+ * <p>A [Channel] is viewed as an edge that connects two entities in the topology of a cloud network.
+ *
+ * @param <E> The type of [Entity] this channel points to.
+ * @param <T> The type of the label data of this channel.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface Channel<out E: Entity, out T>: Pushable, Pullable {
+ /**
+ * The [Entity] instance this channel is points to.
+ */
+ val entity: E
+
+ /**
+ * The label of the channel, possibly containing user-defined information.
+ */
+ val label: Label<T>
+
+ /**
+ * The channel the message originates from.
+ */
+ val Receivable<Any?>.channel: Channel<E, T>
+ get() = this@Channel
+}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Port.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Port.kt
new file mode 100644
index 00000000..a2cdba32
--- /dev/null
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Port.kt
@@ -0,0 +1,34 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 atlarge-research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package nl.atlarge.opendc.experiment.messaging
+
+import nl.atlarge.opendc.topology.Entity
+
+/**
+ * A port connects multiple [Channel]s to an entity in the topology of a cloud network.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface Port<out E: Entity, out T>: Iterable<Channel<E, T>>, Pullable, Pushable
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pullable.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pullable.kt
new file mode 100644
index 00000000..7a756a73
--- /dev/null
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pullable.kt
@@ -0,0 +1,47 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 atlarge-research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package nl.atlarge.opendc.experiment.messaging
+
+/**
+ * A [Pullable] instance allows objects to pull messages from the instance.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface Pullable {
+ /**
+ * Pull one message from this [Channel] for processing via the given block.
+ *
+ * @param block The block to process the message with.
+ * @return The result of the processed messaged.
+ */
+ fun <T> pull(block: Receivable<Any?>.(Any?) -> T): T
+
+ /**
+ * Pull one message from this [Channel].
+ *
+ * @return The message that was received from the channel
+ */
+ fun pull(): Any? = pull { it }
+}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pushable.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pushable.kt
new file mode 100644
index 00000000..8ec14b6d
--- /dev/null
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pushable.kt
@@ -0,0 +1,18 @@
+package nl.atlarge.opendc.experiment.messaging
+
+import nl.atlarge.opendc.topology.Entity
+
+/**
+ * A [Pushable] instance allows objects to send messages to it.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface Pushable {
+ /**
+ * Push one message to downstream.
+ *
+ * @param msg The message to send downstream.
+ * @param sender The sender of the message.
+ */
+ fun push(msg: Any?, sender: Entity)
+}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Receivable.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Receivable.kt
new file mode 100644
index 00000000..f40ebd30
--- /dev/null
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Receivable.kt
@@ -0,0 +1,44 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 atlarge-research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package nl.atlarge.opendc.experiment.messaging
+
+import nl.atlarge.opendc.topology.Entity
+
+/**
+ * A message that is received from a [Channel], also containing the metadata of the message.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface Receivable<out T> {
+ /**
+ * The value of this message.
+ */
+ val value: T
+
+ /**
+ * The sender of this message.
+ */
+ val sender: Entity
+}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/AbstractSimulator.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/AbstractSimulator.kt
new file mode 100644
index 00000000..109d765e
--- /dev/null
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/AbstractSimulator.kt
@@ -0,0 +1,52 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 atlarge-research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package nl.atlarge.opendc.experiment.simulator
+
+import nl.atlarge.opendc.experiment.messaging.Port
+import nl.atlarge.opendc.topology.Entity
+
+/**
+ * A simulator that simulates a single entity in the topology of a cloud network.
+ *
+ * @param ctx The context in which the simulation is run.
+ * @param <E> The type of entity to simulate.
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+abstract class AbstractSimulator<E: Entity>(val ctx: Context<E>): Simulator<E> {
+ /**
+ * The [Entity] that is simulated.
+ */
+ val self: E = ctx.entity
+
+ /**
+ * Create a [Port] of the given type.
+ *
+ * @param name The name of the label to create the port for.
+ * @return The port that has been created or the cached result.
+ */
+ inline fun <reified E: Entity, T> port(name: String): Port<E, T> {
+ throw NotImplementedError()
+ }
+}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Context.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Context.kt
new file mode 100644
index 00000000..29ad4dc8
--- /dev/null
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Context.kt
@@ -0,0 +1,67 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 atlarge-research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package nl.atlarge.opendc.experiment.simulator
+
+import nl.atlarge.opendc.topology.Entity
+
+/**
+ * A context for [Simulator] instance.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+interface Context<E: Entity> {
+ /**
+ * The current tick of the experiment.
+ */
+ val tick: Long
+
+ /**
+ * The [Entity] that is simulated.
+ */
+ val entity: E
+
+ /**
+ * Update the state of the entity being simulated.
+ *
+ * <p>Instead of directly mutating the entity, we create a new instance of the entity to prevent other objects
+ * referencing the old entity having their data changed.
+ *
+ * @param next The next state of the entity.
+ */
+ fun update(next: E)
+
+ /**
+ * Push the given given tick handler on the stack and change the simulator's behaviour to become the new tick
+ * handler.
+ *
+ * @param block The tick handler to push onto the stack.
+ */
+ fun become(block: Context<E>.() -> Unit)
+
+ /**
+ * Revert the behaviour of the simulator to the previous handler in the stack.
+ */
+ fun unbecome()
+}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulates.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulates.kt
new file mode 100644
index 00000000..c69c5eff
--- /dev/null
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulates.kt
@@ -0,0 +1,35 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 atlarge-research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package nl.atlarge.opendc.experiment.simulator
+
+import nl.atlarge.opendc.topology.Entity
+import kotlin.reflect.KClass
+
+/**
+ * Classes annotated by this annotation indicates that the annotated class simulates the given entity.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+annotation class Simulates<T: Entity>(val entity: KClass<T>)
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/simulator/Simulator.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulator.kt
index 07db1e4c..73747d08 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/simulator/Simulator.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulator.kt
@@ -22,33 +22,35 @@
* SOFTWARE.
*/
-package nl.atlarge.opendc.simulator
+package nl.atlarge.opendc.experiment.simulator
import nl.atlarge.opendc.topology.Entity
/**
- * A simulator that simulates a single entity in the topology of a cloud network.
+ * A simulator that simulates a single [Entity] instance in a cloud network.
*
- * @param entity The entity to simulate.
- * @param ctx The context in which the simulation is run.
- * @param <E> The type of entity to simulate.
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-abstract class Simulator<out E: Entity>(val entity: E, val ctx: SimulatorContext) {
+interface Simulator<E: Entity> {
/**
- * This method is invoked at least once before a tick. This allows the [Simulator] to setup its state before a tick
+ * This method is invoked once at the start of the simulation to setup the initial state of the [Simulator].
+ */
+ fun Context<E>.setUp() {}
+
+ /**
+ * This method is invoked at least once before a tick. This allows a [Simulator] to setup its state before a tick
* event.
*
* <p>The pre-tick consists of multiple sub-cycles in which all messages which have been sent
* in the previous sub-cycle can optionally be processed in the sub-cycle by the receiving [Simulator].
*/
- fun preTick() {}
+ fun Context<E>.preTick() {}
/**
- * This method is invoked once per tick, which allows the [Simulator] to process events and simulate an entity in a
+ * This method is invoked once per tick, which allows a [Simulator] to process events to simulate an entity in a
* cloud network.
*/
- fun tick() {}
+ fun Context<E>.tick() {}
/**
* This method is invoked at least once per tick. This allows the [Simulator] to do work after a tick.
@@ -56,13 +58,10 @@ abstract class Simulator<out E: Entity>(val entity: E, val ctx: SimulatorContext
* <p>Like the pre-tick, the post-tick consists of multiple sub-cycles in which all messages which have been sent
* in the previous sub-cycle can optionally be processed in the sub-cycle by the receiving [Simulator].
*/
- fun postTick() {}
+ fun Context<E>.postTick() {}
/**
- * Send the given message to the given [Entity] for processing.
- *
- * @param destination The entity to send the message to.
- * @param message The message to send to the entity.
+ * This method is invoked once at the end of the simulation to tear down resources of the [Simulator].
*/
- fun send(destination: Entity, message: Any?) {}
+ fun Context<E>.tearDown() {}
}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/impl/MachineSimulator.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/impl/MachineSimulator.kt
new file mode 100644
index 00000000..4b351753
--- /dev/null
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/impl/MachineSimulator.kt
@@ -0,0 +1,44 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2017 atlarge-research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package nl.atlarge.opendc.experiment.simulator.impl
+
+import nl.atlarge.opendc.experiment.simulator.AbstractSimulator
+import nl.atlarge.opendc.experiment.simulator.Context
+import nl.atlarge.opendc.experiment.simulator.Simulates
+import nl.atlarge.opendc.topology.machine.Cpu
+import nl.atlarge.opendc.topology.machine.Machine
+
+/**
+ * A simulator for [Machine] entities.
+ *
+ * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
+ */
+@Simulates<Machine>(Machine::class)
+class MachineSimulator(ctx: Context<Machine>): AbstractSimulator<Machine>(ctx) {
+ val cpus = port<Cpu, Nothing>("cpu")
+
+ override fun Context<Machine>.tick() {
+ }
+}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/sampler/Sampler.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/sampler/Sampler.kt
index 2d6d4dc8..2f36e6b7 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/sampler/Sampler.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/sampler/Sampler.kt
@@ -34,6 +34,7 @@ package nl.atlarge.opendc.sampler
* <p>An example would be a sampler that tracks [Machine] occupation per time unit, which is achieved by observing the
* [Entity]'s event stream and filtering for [JobAssignment] events.
*
+ * @param <T> The data type of result generated by this sampler.
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-interface Sampler
+interface Sampler<out T>
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Edge.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Edge.kt
index de5bb0d4..4344e1b5 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Edge.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Edge.kt
@@ -24,56 +24,72 @@
package nl.atlarge.opendc.topology
+import java.util.*
+
/**
- * An edge that represents a connection between exactly two instances of [Node].
- * Instances of [Edge] may be either directed or undirected.
+ * An undirected edge that represents a connection between exactly two instances of [Entity].
*
+ * @param from The first incident node.
+ * @param to The second incident node.
+ * @param label The label of the edge.
+ * @param <T> The data type of the label value.
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-interface Edge<out T> {
+class Edge<out T>(val from: Entity, val to: Entity, val label: Label<T>) {
/**
- * The label of this edge.
+ * Return the [Entity] at the opposite end of this [Edge] from the
+ * specified entity.
+ *
+ * Throws [IllegalArgumentException] if <code>entity</code> is
+ * not incident to this edge.
+ *
+ * @param entity The entity to get the opposite of for this edge pair.
+ * @return The entity at the opposite end of this edge from the specified entity.
+ * @throws IllegalArgumentException if <code>entity</code> is not incident to this edge.
*/
- val label: T
+ fun opposite(entity: Entity): Entity = when (entity) {
+ from -> to
+ to -> from
+ else -> throw IllegalArgumentException()
+ }
/**
- * An [Edge] that is directed, having a source and destination [Node].
+ * Return a [Pair] representing this edge consisting of both incident nodes.
+ * Note that the pair is in no particular order.
+ *
+ * @return The edge represented as pair of both incident nodes.
*/
- interface Directed<out T>: Edge<T> {
- /**
- * The source of the edge.
- */
- val from: Node<*>
-
- /**
- * The destination of the edge.
- */
- val to: Node<*>
- }
+ fun endpoints(): Pair<Entity, Entity> = Pair(from, to)
/**
- * An [Edge] that is undirected.
+ * Determine whether the given object is equal to this instance.
+ *
+ * @param other The other object to compare against.
+ * @return <code>true</code> both edges are equal, <code>false</code> otherwise.
*/
- interface Undirected<out T>: Edge<T>
+ override fun equals(other: Any?): Boolean =
+ if (other is Edge<*>) {
+ from == other.from && to == other.to ||
+ from == other.to && to == other.from
+ } else {
+ false
+ }
/**
- * Return the [Node] at the opposite end of this [Edge] from the
- * specified node.
+ * Return the hash code of this edge pair.
*
- * Throws [IllegalArgumentException] if <code>node</code> is
- * not incident to this edge.
- *
- * @param node The node to get the opposite of for this edge pair.
- * @return The node at the opposite end of this edge from the specified node.
- * @throws IllegalArgumentException if <code>node</code> is not incident to this edge.
+ * @return The hash code of this edge pair.
*/
- fun opposite(node: Node<*>): Node<*>
+ override fun hashCode(): Int {
+ return Objects.hash(from, to)
+ }
/**
- * Return a [Pair] representing this edge consisting of both incident nodes.
- * Note that the pair is in no particular order.
+ * Return a string representation of this [Edge].
*
- * @return The edge represented as pair of both incident nodes.
+ * @return A string representation of this [Edge].
*/
- fun endpoints(): Pair<Node<*>, Node<*>>
+ override fun toString(): String {
+ return "Edge($from<->$to)"
+ }
}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Entity.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Entity.kt
index ef9f3593..c78cba3c 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Entity.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Entity.kt
@@ -25,13 +25,16 @@
package nl.atlarge.opendc.topology
/**
- * An entity in a cloud network.
+ * An entity in the logical topology of a cloud network.
+ *
+ * <p>Instances of the [Entity] interface provide direct access to observable state of the entity to other entities in
+ * the topology connected to it.
*
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
interface Entity {
/**
- * A unique identifier of this node within the topology represented as a [Int].
+ * A unique identifier of this entity within the topology represented as a [Int].
*/
val id: Int
}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Graph.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Graph.kt
index e1e361f9..fe1714fc 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Graph.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Graph.kt
@@ -32,16 +32,16 @@ package nl.atlarge.opendc.topology
*/
interface Graph {
/**
- * Add the given [Node] to this graph.
+ * Return the set of incoming edges of this node.
*
- * @param node The node to add.
+ * @return All edges whose destination is this node.
*/
- fun addNode(node: Node<*>)
+ fun Entity.incomingEdges(): Set<Edge<*>>
/**
- * Add the given [Edge] to this graph.
+ * Return the set of outgoing edges of this node.
*
- * @param edge The edge to add.
+ * @return All edges whose source is this node.
*/
- fun addEdge(edge: Edge<*>)
+ fun Entity.outgoingEdges(): Set<Edge<*>>
}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Node.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/GraphBuilder.kt
index cce5990f..a280e88a 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Node.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/GraphBuilder.kt
@@ -25,27 +25,29 @@
package nl.atlarge.opendc.topology
/**
- * A node in the logical topology of a cloud network, representing some [Entity].
+ * A builder for [Graph] instances.
*
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-interface Node<out E: Entity> {
+interface GraphBuilder {
/**
- * The [Entity] this node represents.
+ * Add the given [Entity] to this graph.
+ *
+ * @param entity The entity to add.
*/
- val entity: E
+ fun add(entity: Entity)
/**
- * Return the set of incoming edges of this node.
+ * Add the given [Edge] to this graph.
*
- * @return All edges whose destination is this node.
+ * @param edge The edge to add.
*/
- fun incomingEdges(): Set<Edge<*>>
+ fun add(edge: Edge<*>)
/**
- * Return the set of outgoing edges of this node.
+ * Build a [Graph] instance from the current state of this builder.
*
- * @return All edges whose source is this node.
+ * @return The graph built from this builder.
*/
- fun outgoingEdges(): Set<Edge<*>>
+ fun build(): Graph
}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/simulator/SimulatorContext.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Label.kt
index 1ddfbc6a..69174263 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/simulator/SimulatorContext.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Label.kt
@@ -22,16 +22,21 @@
* SOFTWARE.
*/
-package nl.atlarge.opendc.simulator
+package nl.atlarge.opendc.topology
/**
- * The context in which a [Simulator] runs.
+ * A label for an edge in the topology.
*
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-class SimulatorContext {
+interface Label<out T> {
/**
- * The current tick of the simulation.
+ * The name of the label.
*/
- var tick: Long = 0
+ val name: String
+
+ /**
+ * The user-specified data of the label.
+ */
+ val data: T
}
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Rack.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Rack.kt
index cf947ebb..c40b1660 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Rack.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Rack.kt
@@ -31,6 +31,7 @@ import nl.atlarge.opendc.topology.Entity
* other datacenter computing equipment.
*
* @param id The unique identifier of this entity.
+ * @param <T> The type of nodes that are placed in the rack.
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-data class Rack(override val id: Int): Entity
+data class Rack<T: Entity>(override val id: Int): Entity
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Slot.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Slot.kt
index 2556598e..203f7f3b 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Slot.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Slot.kt
@@ -24,9 +24,12 @@
package nl.atlarge.opendc.topology.container.rack
+import nl.atlarge.opendc.topology.Edge
+import nl.atlarge.opendc.topology.Entity
+
/**
* This class represents a slot in a [Rack] of [Machine]s.
*
* @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl)
*/
-data class Slot(val index: Int)
+class Slot<T: Entity>(val rack: Rack<T>, val contents: T, val index: Int): Edge.Directed(rack, contents)
diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt
index 5fc0086d..cc047136 100644
--- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt
+++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/power/PowerUnit.kt
@@ -27,7 +27,7 @@ package nl.atlarge.opendc.topology.power
import nl.atlarge.opendc.topology.Entity
/**
- * An [Entity] which provides power for other entities a cloud network to run.
+ * A [Entity] which provides power for other entities a cloud network to run.
*
* @param id The unique identifier of the [Entity].
* @param output The output of the power unit in Watts.