diff options
Diffstat (limited to 'opendc-core/src/main')
42 files changed, 1010 insertions, 321 deletions
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 b2845963..14a623a6 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 @@ -24,14 +24,14 @@ 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. + * A task scheduler that is coupled to an [Node] in the topology of the cloud network. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Scheduler<in E: Entity> { +interface Scheduler<in E: Node<*>> { /** * Schedule the given jobs for the given entity. * 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 8bfba407..bb87a167 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.Graph +import nl.atlarge.opendc.topology.Topology /** * A user of a cloud network that provides [Job]s for the simulation. @@ -37,4 +37,4 @@ import nl.atlarge.opendc.topology.Graph * @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: Graph) +data class User(val id: Int, val name: String, val view: Topology) 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 deleted file mode 100644 index 8ec14b6d..00000000 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pushable.kt +++ /dev/null @@ -1,18 +0,0 @@ -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/simulator/Simulator.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulator.kt deleted file mode 100644 index 73747d08..00000000 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulator.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 simulator that simulates a single [Entity] instance in a cloud network. - * - * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) - */ -interface Simulator<E: Entity> { - /** - * 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 Context<E>.preTick() {} - - /** - * This method is invoked once per tick, which allows a [Simulator] to process events to simulate an entity in a - * cloud network. - */ - fun Context<E>.tick() {} - - /** - * This method is invoked at least once per tick. This allows the [Simulator] to do work after a tick. - * - * <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 Context<E>.postTick() {} - - /** - * This method is invoked once at the end of the simulation to tear down resources of the [Simulator]. - */ - fun Context<E>.tearDown() {} -} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/AbstractEntityKernel.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/AbstractEntityKernel.kt new file mode 100644 index 00000000..35b89e4e --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/AbstractEntityKernel.kt @@ -0,0 +1,65 @@ +/* + * 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.kernel + +import nl.atlarge.opendc.kernel.messaging.ReadablePort +import nl.atlarge.opendc.kernel.messaging.WritableChannel +import nl.atlarge.opendc.topology.Edge +import nl.atlarge.opendc.topology.Entity +import nl.atlarge.opendc.topology.Node + +/** + * A simulation kernel 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 shape of the component to simulate. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +abstract class AbstractEntityKernel<E: Entity<*>>(private val ctx: EntityContext<E>): Kernel<EntityContext<E>> { + /** + * The [Node] that is simulated. + */ + val self: Node<E> = ctx.component + + /** + * Create a [WritableChannel] over the edge with the given tag. + * + * @param tag The tag of the edge to create a channel over. + * @return The channel that has been created or the cached result. + */ + inline fun <reified T: Edge<*>> output(tag: String): WritableChannel<T> { + TODO() + } + + /** + * Create a [ReadablePort] over the edges with the given tag. + * + * @param tag The tag of the edges to create a port over. + * @return The port that has been created or the cached result. + */ + inline fun <reified T: Edge<*>> input(tag: String): ReadablePort<T> { + TODO() + } +} 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/kernel/ChannelContext.kt index 203f7f3b..aaf5abba 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/rack/Slot.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/ChannelContext.kt @@ -22,14 +22,14 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.container.rack +package nl.atlarge.opendc.kernel +import nl.atlarge.opendc.kernel.messaging.Writable import nl.atlarge.opendc.topology.Edge -import nl.atlarge.opendc.topology.Entity /** - * This class represents a slot in a [Rack] of [Machine]s. + * The context provided to a simulation kernel for communication channels between entities. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -class Slot<T: Entity>(val rack: Rack<T>, val contents: T, val index: Int): Edge.Directed(rack, contents) +interface ChannelContext<out T>: Context<Edge<T>>, Writable diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Channel.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Context.kt index b33b720d..81431e02 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Channel.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Context.kt @@ -22,34 +22,41 @@ * SOFTWARE. */ -package nl.atlarge.opendc.experiment.messaging +package nl.atlarge.opendc.kernel +import nl.atlarge.opendc.kernel.messaging.Readable +import nl.atlarge.opendc.topology.Component 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. + * The [Context] interface provides a context for a simulation kernel, which defines the environment in which the + * simulation is run. * - * <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 { +interface Context<out T: Component<*>>: Readable { + /** + * The [Component] that is simulated. + */ + val component: T + /** - * The [Entity] instance this channel is points to. + * The observable state of an [Entity] within the simulation is provided by context. */ - val entity: E + val <S> Entity<S>.state: S /** - * The label of the channel, possibly containing user-defined information. + * Suspend the simulation kernel until the next tick occurs in the simulation. */ - val label: Label<T> + suspend fun tick(): Boolean { + sleep(1) + return true + } /** - * The channel the message originates from. + * Suspend the simulation kernel for <code>n</code> ticks before resuming the execution. + * + * @param n The amount of ticks to suspend the simulation kernel. */ - val Receivable<Any?>.channel: Channel<E, T> - get() = this@Channel + suspend fun sleep(n: Int) } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Context.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/EntityContext.kt index 29ad4dc8..ea9c6b04 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Context.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/EntityContext.kt @@ -22,26 +22,17 @@ * SOFTWARE. */ -package nl.atlarge.opendc.experiment.simulator +package nl.atlarge.opendc.kernel import nl.atlarge.opendc.topology.Entity +import nl.atlarge.opendc.topology.Node /** - * A context for [Simulator] instance. + * The context provided to a simulation kernel for stateful entities in the topology. * * @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 - +interface EntityContext<out T: Entity<*>>: Context<Node<T>> { /** * Update the state of the entity being simulated. * @@ -50,18 +41,5 @@ interface Context<E: Entity> { * * @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() + suspend fun <C: EntityContext<E>, E: Entity<S>, S> C.update(next: S) } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/AbstractSimulator.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Kernel.kt index 109d765e..5f399c57 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/AbstractSimulator.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Kernel.kt @@ -22,31 +22,25 @@ * SOFTWARE. */ -package nl.atlarge.opendc.experiment.simulator +package nl.atlarge.opendc.kernel -import nl.atlarge.opendc.experiment.messaging.Port -import nl.atlarge.opendc.topology.Entity +import nl.atlarge.opendc.topology.Component /** - * A simulator that simulates a single entity in the topology of a cloud network. + * A simulation kernel that simulates a single [Component] instance in 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> { +interface Kernel<in C: Context<*>> { /** - * The [Entity] that is simulated. - */ - val self: E = ctx.entity - - /** - * Create a [Port] of the given type. + * This method is invoked to start the simulation of the [Component] associated with this [Kernel]. + * + * <p>This method is assumed to be running during the experiment, but should hand back control to the simulator at + * some point by calling [Context.tick] to wait for the next tick to occur, which allows to allows other entity + * simulators to do work in the current tick of the simulation. * - * @param name The name of the label to create the port for. - * @return The port that has been created or the cached result. + * <p>If this method exists early, before the simulation has finished, the entity is assumed to be shutdown and its + * simulation will not run any further. */ - inline fun <reified E: Entity, T> port(name: String): Port<E, T> { - throw NotImplementedError() - } + suspend fun C.run() } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Simulator.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Simulator.kt new file mode 100644 index 00000000..ee8d5072 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/Simulator.kt @@ -0,0 +1,222 @@ +/* + * 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.kernel + +import nl.atlarge.opendc.kernel.clock.Clock +import nl.atlarge.opendc.kernel.clock.Tick +import nl.atlarge.opendc.kernel.messaging.Envelope +import nl.atlarge.opendc.topology.* +import java.util.* +import kotlin.coroutines.experimental.* + +/** + * A [Simulator] runs the simulation over the specified topology. + * + * @param topology The topology to run the simulation over. + * @param mapping The mapping of components in the topology to the simulation kernels the components should use. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +class Simulator(val topology: Topology, private val mapping: Map<Component<*>, Class<out Kernel<*>>>): Iterator<Unit> { + /** + * The registry of the simulation kernels used in the experiment. + */ + private val registry: MutableMap<Component<*>, Pair<Kernel<Context<*>>, Context<*>>?> = HashMap() + + /** + * A mapping of the entities in the topology to their current state. + */ + private val states: MutableMap<Entity<*>, Any?> = HashMap() + + /** + * The clock of the simulator. + */ + private val clock: DefaultClock = DefaultClock() + + /** + * Initialize the simulator. + */ + init { + topology.forEach { node -> + resolve(node) + node.outgoingEdges().forEach { resolve(it) } + } + + registry.values.forEach { + it?.also { (kernel, ctx) -> + // Start all kernel co-routines + kernel.run { + val block: suspend () -> Unit = { ctx.run() } + block.startCoroutine(SimulationCoroutine()) + } + } + } + } + + /** + * Resolve the given [Component] to the [Kernel] of that component. + * + * @param component The component to resolve. + * @return The [Kernel] that simulates that [Component]. + */ + fun <T: Component<*>> resolve(component: T): Pair<Kernel<Context<T>>, Context<T>>? { + @Suppress("UNCHECKED_CAST") + return registry.computeIfAbsent(component, { + val constructor = mapping[it]?.constructors?.get(0) + val ctx = if (component is Node<*>) { + DefaultEntityContext(component as Node<*>) + } else { + DefaultChannelContext(component as Edge<*>) + } + + if (constructor == null) { + println("warning: invalid constructor for kernel ${mapping[it]}") + null + } else { + Pair(constructor.newInstance(ctx) as Kernel<Context<*>>, ctx) + } + }) as? Pair<Kernel<Context<T>>, Context<T>>? + } + + /** + * Determine whether the simulator has a next non-empty cycle available. + * + * @return <code>true</code> if the simulator has a next non-empty cycle, <code>false</code> otherwise. + */ + override fun hasNext(): Boolean = clock.queue.isNotEmpty() + + /** + * Run the next cycle in the simulation. + */ + override fun next() { + clock.tick++ + while (true) { + val (tick, block) = clock.queue.peek() ?: return + + if (tick > clock.tick) + // Tick has yet to occur + break + else if (tick < clock.tick) + // Tick has already occurred + println("error: tick was not handled correctly") + + clock.queue.poll() + block() + } + } + + class SimulationCoroutine: Continuation<Unit> { + override val context: CoroutineContext = EmptyCoroutineContext + override fun resume(value: Unit) {} + + override fun resumeWithException(exception: Throwable) { + val currentThread = Thread.currentThread() + currentThread.uncaughtExceptionHandler.uncaughtException(currentThread, exception) + } + } + + /** + * The [Context] for an entity within the simulation. + */ + private inner class DefaultEntityContext<out T: Entity<*>>(override val component: Node<T>): EntityContext<T> { + /** + * Retrieves and removes a single message from this channel suspending the caller while the channel is empty. + * + * @param block The block to process the message with. + * @return The processed message. + */ + suspend override fun <T> receive(block: Envelope<*>.(Any?) -> T): T = suspendCoroutine {} + + + /** + * The observable state of an [Entity] within the simulation is provided by context. + */ + @Suppress("UNCHECKED_CAST") + override val <S> Entity<S>.state: S + get() = states[this] as S + + /** + * 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. + */ + suspend override fun <C: EntityContext<E>, E: Entity<S>, S> C.update(next: S) { + states.put(component.entity as Entity<*>, next) + } + + /** + * Suspend the simulation kernel for <code>n</code> ticks before resuming the execution. + * + * @param n The amount of ticks to suspend the simulation kernel. + */ + suspend override fun sleep(n: Int): Unit = suspendCoroutine { cont -> clock.scheduleAfter(n, { cont.resume(Unit) }) } + } + + /** + * The [Context] for an edge within the simulation. + */ + private inner class DefaultChannelContext<out T>(override val component: Edge<T>): ChannelContext<T> { + /** + * Retrieves and removes a single message from this channel suspending the caller while the channel is empty. + * + * @param block The block to process the message with. + * @return The processed message. + */ + suspend override fun <T> receive(block: Envelope<*>.(Any?) -> T): T = suspendCoroutine {} + + /** + * Send the given message downstream. + * + * @param msg The message to send. + * @param sender The sender of the message. + */ + suspend override fun send(msg: Any?, sender: Node<*>): Unit = suspendCoroutine {} + + /** + * The observable state of an [Entity] within the simulation is provided by context. + */ + @Suppress("UNCHECKED_CAST") + override val <S> Entity<S>.state: S + get() = states[this] as S + + /** + * Suspend the simulation kernel for <code>n</code> ticks before resuming the execution. + * + * @param n The amount of ticks to suspend the simulation kernel. + */ + suspend override fun sleep(n: Int): Unit = suspendCoroutine { cont -> clock.scheduleAfter(n, { cont.resume(Unit) }) } + } + + private inner class DefaultClock: Clock { + override var tick: Tick = 0 + internal val queue: PriorityQueue<Pair<Tick, () -> Unit>> = PriorityQueue(Comparator.comparingLong { it.first }) + + override fun scheduleAt(tick: Tick, block: () -> Unit) { + queue.add(Pair(tick, block)) + } + } +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/GraphBuilder.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/clock/Clock.kt index a280e88a..db13eee1 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/GraphBuilder.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/clock/Clock.kt @@ -22,32 +22,32 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology +package nl.atlarge.opendc.kernel.clock /** - * A builder for [Graph] instances. + * A tick represents a moment of time in which some work is done by an entity. + */ +typealias Tick = Long + +/** + * The clock of a simulation manages the ticks that have elapsed and schedules the tick events. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface GraphBuilder { +interface Clock { /** - * Add the given [Entity] to this graph. - * - * @param entity The entity to add. + * The tick the clock is currently at. */ - fun add(entity: Entity) + val tick: Tick /** - * Add the given [Edge] to this graph. * - * @param edge The edge to add. + * @throws IllegalArgumentException */ - fun add(edge: Edge<*>) + fun scheduleAt(tick: Tick, block: () -> Unit) /** - * Build a [Graph] instance from the current state of this builder. - * - * @return The graph built from this builder. + * @throws IllegalArgumentException */ - fun build(): Graph + fun scheduleAfter(n: Int, block: () -> Unit) = scheduleAt(tick + n, block) } 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/kernel/impl/MachineKernel.kt index 4b351753..e34c7060 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/impl/MachineSimulator.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/impl/MachineKernel.kt @@ -22,23 +22,37 @@ * SOFTWARE. */ -package nl.atlarge.opendc.experiment.simulator.impl +package nl.atlarge.opendc.kernel.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.experiment.Task +import nl.atlarge.opendc.kernel.AbstractEntityKernel +import nl.atlarge.opendc.kernel.EntityContext 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") +class MachineKernel(ctx: EntityContext<Machine>): AbstractEntityKernel<Machine>(ctx) { + + suspend override fun EntityContext<Machine>.run() { + println("${this}: Initialising!") - override fun Context<Machine>.tick() { + val cpus = component.outgoingEdges().filter { it.tag == "cpu" }.map { it.to.entity as Cpu } + val speed = cpus.fold(0, { acc, (speed, cores) -> acc + speed * cores }) + val task: Task + + loop@while (true) { + val msg = receive() + when (msg) { + is Task -> { + task = msg + break@loop + } + else -> println("warning: unhandled message $msg") + } + } + + while (tick()) { + task.consume(speed.toLong()) + } } + } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Channel.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Channel.kt new file mode 100644 index 00000000..ad966719 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Channel.kt @@ -0,0 +1,49 @@ +/* + * 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.kernel.messaging + +import nl.atlarge.opendc.topology.Edge +import nl.atlarge.opendc.topology.Node + +/** + * A unidirectional communication channel between two [Node] instances as seen from one of the entities. + * + * <p>A [Channel] is viewed as a directed edge that connects two entities in the topology of a cloud network. + * + * @param T The shape of the label of the edge of this channel. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Channel<out T> { + /** + * The directed edge between two nodes which represents this unidirectional communication channel. + */ + val edge: Edge<T> + + /** + * The channel the message originates from. + */ + val Envelope<*>.channel: Channel<T> + get() = this@Channel +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulates.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/DuplexChannel.kt index c69c5eff..a4ef7409 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/simulator/Simulates.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/DuplexChannel.kt @@ -22,14 +22,12 @@ * SOFTWARE. */ -package nl.atlarge.opendc.experiment.simulator - -import nl.atlarge.opendc.topology.Entity -import kotlin.reflect.KClass +package nl.atlarge.opendc.kernel.messaging /** - * Classes annotated by this annotation indicates that the annotated class simulates the given entity. + * A [DuplexChannel] instance allows bi-directional communication over the channel. * + * @param T The shape of the label of the edge of this channel. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -annotation class Simulates<T: Entity>(val entity: KClass<T>) +interface DuplexChannel<out T>: Channel<T>, Readable, Writable diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/DuplexPort.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/DuplexPort.kt new file mode 100644 index 00000000..5917ac71 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/DuplexPort.kt @@ -0,0 +1,33 @@ +/* + * 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.kernel.messaging + +/** + * A [DuplexPort] instance allows bi-directional communication with multiple channels. + * + * @param T The shape of the label of the edges of the channels of this port. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface DuplexPort<out T>: Port<DuplexChannel<T>>, Readable, Writable diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Receivable.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Envelope.kt index f40ebd30..d4d363d5 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Receivable.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Envelope.kt @@ -22,23 +22,23 @@ * SOFTWARE. */ -package nl.atlarge.opendc.experiment.messaging +package nl.atlarge.opendc.kernel.messaging -import nl.atlarge.opendc.topology.Entity +import nl.atlarge.opendc.topology.Node /** - * A message that is received from a [Channel], also containing the metadata of the message. + * The envelope of 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> { +data class Envelope<out T>( /** - * The value of this message. + * The message in this envelope. */ - val value: T + val message: T, /** - * The sender of this message. + * The sender of the message. */ - val sender: Entity -} + val sender: Node<*> +) diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Port.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Port.kt index a2cdba32..18ec1918 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Port.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Port.kt @@ -22,13 +22,12 @@ * SOFTWARE. */ -package nl.atlarge.opendc.experiment.messaging - -import nl.atlarge.opendc.topology.Entity +package nl.atlarge.opendc.kernel.messaging /** * A port connects multiple [Channel]s to an entity in the topology of a cloud network. * + * @param C The shape of the channels that are connected to this port. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Port<out E: Entity, out T>: Iterable<Channel<E, T>>, Pullable, Pushable +interface Port<out C: Channel<*>>: Iterable<C> diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pullable.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Readable.kt index 7a756a73..422c5668 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/experiment/messaging/Pullable.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Readable.kt @@ -22,26 +22,26 @@ * SOFTWARE. */ -package nl.atlarge.opendc.experiment.messaging +package nl.atlarge.opendc.kernel.messaging /** - * A [Pullable] instance allows objects to pull messages from the instance. + * A [Readable] instance allows objects to pull messages from the instance. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Pullable { +interface Readable { /** - * Pull one message from this [Channel] for processing via the given block. + * Retrieves and removes a single message from this channel suspending the caller while the channel is empty. * * @param block The block to process the message with. - * @return The result of the processed messaged. + * @return The processed message. */ - fun <T> pull(block: Receivable<Any?>.(Any?) -> T): T + suspend fun <T> receive(block: Envelope<*>.(Any?) -> T): T /** - * Pull one message from this [Channel]. + * Retrieve a single message from this [Channel]. * * @return The message that was received from the channel */ - fun pull(): Any? = pull { it } + suspend fun receive(): Any? = receive { it } } diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/ReadableChannel.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/ReadableChannel.kt new file mode 100644 index 00000000..c291b1ea --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/ReadableChannel.kt @@ -0,0 +1,33 @@ +/* + * 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.kernel.messaging + +/** + * A [ReadableChannel] instance allows objects to receive messages from the channel. + * + * @param T The shape of the label of the edge of this channel. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface ReadableChannel<out T>: Channel<T>, Readable diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/ReadablePort.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/ReadablePort.kt new file mode 100644 index 00000000..bfad9490 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/ReadablePort.kt @@ -0,0 +1,33 @@ +/* + * 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.kernel.messaging + +/** + * A [ReadablePort] instance allows objects to receive messages from the channel. + * + * @param T The shape of the label of the edges of the channels of this port. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface ReadablePort<out T>: Port<ReadableChannel<T>>, Readable diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Writable.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Writable.kt new file mode 100644 index 00000000..6bd1ce30 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/Writable.kt @@ -0,0 +1,42 @@ +/* + * 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.kernel.messaging + +import nl.atlarge.opendc.topology.Node + +/** + * A [Writable] instance allows objects to send messages to it. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Writable { + /** + * Send the given message downstream. + * + * @param msg The message to send. + * @param sender The sender of the message. + */ + suspend fun send(msg: Any?, sender: Node<*>) +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/WritableChannel.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/WritableChannel.kt new file mode 100644 index 00000000..60f89a97 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/WritableChannel.kt @@ -0,0 +1,33 @@ +/* + * 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.kernel.messaging + +/** + * A [WritableChannel] instance allows objects to write messages to the channel. + * + * @param T The shape of the label of the edge of this channel. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface WritableChannel<out T>: Channel<T>, Writable diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/WritablePort.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/WritablePort.kt new file mode 100644 index 00000000..0dc92680 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/kernel/messaging/WritablePort.kt @@ -0,0 +1,33 @@ +/* + * 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.kernel.messaging + +/** + * A [WritablePort] instance allows objects to write messages to multiple channels. + * + * @param T The shape of the label of the edges of the channels of this port. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface WritablePort<out T>: Port<WritableChannel<T>>, Writable diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/AdjacencyList.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/AdjacencyList.kt new file mode 100644 index 00000000..bdf60056 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/AdjacencyList.kt @@ -0,0 +1,104 @@ +/* + * 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.topology + +import java.util.concurrent.atomic.AtomicInteger + +/** + * A builder for [Topology] instances, which is backed by an adjacency list. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +class AdjacencyListTopologyBuilder: TopologyBuilder { + /** + * Build a [Topology] instance from the current state of this builder. + * + * @return The graph built from this builder. + */ + override fun build(): MutableTopology = AdjacencyListTopology() +} + +/** + * A [Topology] whose graph is represented as adjacency list. + */ +internal class AdjacencyListTopology: MutableTopology { + private val nextId: AtomicInteger = AtomicInteger(0) + private val nodes: MutableList<Node<*>> = ArrayList() + + /** + * Create a [Node] in this [Topology] for the given [Entity]. + * + * @param entity The entity to create a node for. + * @return The node created for the given entity. + */ + override fun <T : Entity<*>> node(entity: T): Node<T> { + val node = AdjacencyListNode(nextId.incrementAndGet(), entity) + nodes.add(node) + return node + } + + /** + * Create a directed edge between two [Node]s in the topology. + * + * @param from The source of the edge. + * @param to The destination of the edge. + * @param label The label of the edge. + * @param tag The tag of the edge that uniquely identifies the relationship the edge represents. + * @return The edge that has been created. + */ + override fun <T> connect(from: Node<*>, to: Node<*>, label: T, tag: String?): Edge<T> { + if (from !is AdjacencyListNode<*> || to !is AdjacencyListNode<*>) + throw IllegalArgumentException() + if (!from.validate(this) || !to.validate(this)) + throw IllegalArgumentException() + val edge: Edge<T> = AdjacencyListEdge(label, tag, from, to) + from.outgoingEdges.add(edge) + to.ingoingEdges.add(edge) + return edge + } + + /** + * Returns an iterator over the elements of this object. + */ + override fun iterator(): Iterator<Node<*>> = nodes.iterator() + + internal inner class AdjacencyListNode<out T: Entity<*>>(override val id: Int, override val label: T): Node<T> { + internal var ingoingEdges: MutableSet<Edge<*>> = HashSet() + internal var outgoingEdges: MutableSet<Edge<*>> = HashSet() + + override fun ingoingEdges(): Set<Edge<*>> = ingoingEdges + override fun outgoingEdges(): Set<Edge<*>> = outgoingEdges + override fun toString(): String = label.toString() + + internal fun validate(instance: AdjacencyListTopology) = this@AdjacencyListTopology == instance + } + + internal class AdjacencyListEdge<out T>(override val label: T, + override val tag: String?, + override val from: Node<*>, + override val to: Node<*>): Edge<T> { + override fun toString(): String = label.toString() + } +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Component.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Component.kt new file mode 100644 index 00000000..79b35e86 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Component.kt @@ -0,0 +1,40 @@ +/* + * 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.topology + +/** + * A component within a [Topology], which is either an [Node] or an [Edge] representing the relationship between + * entities within a logical topology of a cloud network. + * + * <p>A [Component]'s label provides access to user-specified data. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Component<out T> { + /** + * The label of this [Component]. + */ + val label: 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 4344e1b5..22ad57c1 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,72 +24,31 @@ package nl.atlarge.opendc.topology -import java.util.* - /** - * An undirected edge that represents a connection between exactly two instances of [Entity]. + * An edge that represents a directed relationship between exactly two [Node]s in a logical topology of a cloud network. * - * @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. + * @param T The relationship type the edge represents within a logical topology. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -class Edge<out T>(val from: Entity, val to: Entity, val label: Label<T>) { - /** - * 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. - */ - fun opposite(entity: Entity): Entity = when (entity) { - from -> to - to -> from - else -> throw IllegalArgumentException() - } - +interface Edge<out T>: Component<T> { /** - * 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. - */ - fun endpoints(): Pair<Entity, Entity> = Pair(from, to) - - /** - * 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. + * A tag to uniquely identify the relationship this edge represents. */ - override fun equals(other: Any?): Boolean = - if (other is Edge<*>) { - from == other.from && to == other.to || - from == other.to && to == other.from - } else { - false - } + val tag: String? /** - * Return the hash code of this edge pair. + * The source of the edge. * - * @return The hash code of this edge pair. + * This property is not guaranteed to have a runtime complexity of <code>O(1)</code>, but must be at least + * <code>O(n)</code>, with respect to the size of the topology. */ - override fun hashCode(): Int { - return Objects.hash(from, to) - } + val from: Node<*> /** - * Return a string representation of this [Edge]. + * The destination of the edge. * - * @return A string representation of this [Edge]. + * This property is not guaranteed to have a runtime complexity of <code>O(1)</code>, but must be at least + * <code>O(n)</code>, with respect to the size of the topology. */ - override fun toString(): String { - return "Edge($from<->$to)" - } + val to: Node<*> } 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 c78cba3c..44264a35 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,16 +25,15 @@ package nl.atlarge.opendc.topology /** - * An entity in the logical topology of a cloud network. + * An entity within 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. + * <p>A [Entity] contains the immutable properties of this component given by the topology configuration at the start + * of a simulation and remain unchanged during simulation. * + * <p>In addition, other entities in a simulation have direct, immutable access to the observable state of this entity. + * + * @param S The shape of the observable state of this entity, which is directly accessible by other components within + * a simulation. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Entity { - /** - * A unique identifier of this entity within the topology represented as a [Int]. - */ - val id: Int -} +interface Entity<out S> diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Label.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/ImmutableTopology.kt index 69174263..90ba5dc5 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Label.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/ImmutableTopology.kt @@ -23,20 +23,9 @@ */ package nl.atlarge.opendc.topology - /** - * A label for an edge in the topology. + * A [Topology] whose elements and structural relationships will never change. * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Label<out T> { - /** - * The name of the label. - */ - val name: String - - /** - * The user-specified data of the label. - */ - val data: T -} +interface ImmutableTopology: Topology diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/MutableTopology.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/MutableTopology.kt new file mode 100644 index 00000000..0aa0d1b5 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/MutableTopology.kt @@ -0,0 +1,70 @@ +/* + * 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.topology + +/** + * A subinterface of [Topology] which adds mutation methods. When mutation is not required, users + * should prefer the [Topology] interface. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface MutableTopology: Topology { + /** + * Create a [Node] in this [Topology] for the given [Entity]. + * + * @param entity The entity to create a node for. + * @return The node created for the given entity. + */ + fun <T: Entity<*>> node(entity: T): Node<T> + + /** + * Create a directed edge between two [Node]s in the topology. + * + * @param from The source of the edge. + * @param to The destination of the edge. + * @param label The label of the edge. + * @param tag The tag of the edge that uniquely identifies the relationship the edge represents. + * @return The edge that has been created. + */ + fun <T> connect(from: Node<*>, to: Node<*>, label: T, tag: String? = null): Edge<T> + + /** + * Create a directed edge between two [Node]s in the topology. + * + * @param from The source of the edge. + * @param to The destination of the edge. + * @param tag The tag of the edge that uniquely identifies the relationship the edge represents. + * @return The edge that has been created. + */ + fun connect(from: Node<*>, to: Node<*>, tag: String? = null): Edge<Unit> = connect(from, to, Unit, tag) + + /** + * Create a directed edge between two [Node]s in the topology. + * + * @param dest The destination of the edge. + * @return The edge that has been created. + */ + infix fun Node<*>.to(dest: Node<*>): Edge<Unit> = connect(this, dest) +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Node.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Node.kt new file mode 100644 index 00000000..5b7076ed --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Node.kt @@ -0,0 +1,60 @@ +/* + * 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.topology + +/** + * A labeled node of graph representing an entity in a specific logical topology of a cloud network. + * + * <p>A [Node] is instantiated and managed by a [Topology] instance containing user-specified data in its label. + * + * @param T The entity type the node represents in a logical topology. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Node<out T: Entity<*>>: Component<T> { + /** + * A unique identifier of this node within the topology. + */ + val id: Int + + /** + * Return the set of incoming edges of this node. + * + * @return All edges whose destination is this node. + */ + fun ingoingEdges(): Set<Edge<*>> + + /** + * Return the set of outgoing edges of this node. + * + * @return All edges whose source is this node. + */ + fun outgoingEdges(): Set<Edge<*>> + + /** + * The [Entity] this node represents within a logical topology of a cloud network. + */ + val entity: T + get() = label +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Graph.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Topology.kt index fe1714fc..d8f966d1 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Graph.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/Topology.kt @@ -28,20 +28,8 @@ package nl.atlarge.opendc.topology * A graph data structure which represents the logical topology of a cloud network consisting of one or more * datacenters. * + * <p>A topology is [Iterable] and allows implementation-dependent iteration of the nodes in the topology. + * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface Graph { - /** - * Return the set of incoming edges of this node. - * - * @return All edges whose destination is this node. - */ - fun Entity.incomingEdges(): Set<Edge<*>> - - /** - * Return the set of outgoing edges of this node. - * - * @return All edges whose source is this node. - */ - fun Entity.outgoingEdges(): Set<Edge<*>> -} +interface Topology: Iterable<Node<*>> diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyBuilder.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyBuilder.kt new file mode 100644 index 00000000..5752eb89 --- /dev/null +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/TopologyBuilder.kt @@ -0,0 +1,39 @@ +/* + * 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.topology + +/** + * A builder for [Topology] instances. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface TopologyBuilder { + /** + * Build a [Topology] instance from the current state of this builder. + * + * @return The graph built from this builder. + */ + fun build(): MutableTopology +} diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt index 5a57c70a..2b464f15 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/Datacenter.kt @@ -29,7 +29,6 @@ import nl.atlarge.opendc.topology.Entity /** * A representation of a facility used to house computer systems and associated components. * - * @param id The unique identifier of this entity. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -class Datacenter(override val id: Int): Entity +class Datacenter: Entity<Unit> 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.kt index c40b1660..043ad31a 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.kt @@ -22,7 +22,7 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.container.rack +package nl.atlarge.opendc.topology.container import nl.atlarge.opendc.topology.Entity @@ -30,8 +30,6 @@ import nl.atlarge.opendc.topology.Entity * A type of physical steel and electronic framework that is designed to house servers, networking devices, cables and * 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<T: Entity>(override val id: Int): Entity +class Rack: Entity<Unit> diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/room/Room.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/Room.kt index 638d59e3..844d96a0 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/room/Room.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/container/Room.kt @@ -22,14 +22,13 @@ * SOFTWARE. */ -package nl.atlarge.opendc.topology.container.room +package nl.atlarge.opendc.topology.container import nl.atlarge.opendc.topology.Entity /** - * A physical room in a datacenter which contains [Entity]s. + * A physical room in a datacenter with relationships to the entities within the room. * - * @param id The unique identifier of this entity. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -abstract class Room(override val id: Int): Entity +interface Room: Entity<Unit> diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt index 5c1b8b57..e06ad00c 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/Cpu.kt @@ -30,7 +30,6 @@ package nl.atlarge.opendc.topology.machine * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ data class Cpu( - override val id: Int, override val speed: Int, override val cores: Int, override val energyConsumption: Int diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt index 91a7be6a..f15847e4 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/Gpu.kt @@ -29,9 +29,9 @@ package nl.atlarge.opendc.topology.machine * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -data class Gpu( - override val id: Int, +class Gpu( override val speed: Int, override val cores: Int, override val energyConsumption: Int ): ProcessingUnit + diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt index 39b5267e..396339a2 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/Machine.kt @@ -30,7 +30,6 @@ import nl.atlarge.opendc.topology.Entity * A Physical Machine (PM) inside a rack of a datacenter. It has a speed, and can be given a workload on which it will * work until finished or interrupted. * - * @param id The unique identifier of this entity. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -data class Machine(override val id: Int): Entity +class Machine: Entity<Unit> diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/ProcessingUnit.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/ProcessingUnit.kt index 095a0bb5..a235133f 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/ProcessingUnit.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/machine/ProcessingUnit.kt @@ -31,7 +31,7 @@ import nl.atlarge.opendc.topology.Entity * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface ProcessingUnit: Entity { +interface ProcessingUnit: Entity<Unit> { /** * The speed of this [ProcessingUnit] per core. */ diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/network/NetworkUnit.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/network/NetworkUnit.kt index fcb5f20a..9c294125 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/network/NetworkUnit.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/network/NetworkUnit.kt @@ -31,4 +31,4 @@ import nl.atlarge.opendc.topology.Entity * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface NetworkUnit: Entity +interface NetworkUnit: Entity<Unit> 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 cc047136..e016a12b 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,10 +27,9 @@ package nl.atlarge.opendc.topology.power import nl.atlarge.opendc.topology.Entity /** - * A [Entity] which provides power for other entities a cloud network to run. + * An [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. + * @param output The power output of the power unit in Watt. * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -data class PowerUnit(override val id: Int, val output: Double): Entity +class PowerUnit(val output: Double): Entity<Unit> diff --git a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/storage/StorageUnit.kt b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/storage/StorageUnit.kt index 6fac585f..8e53e365 100644 --- a/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/storage/StorageUnit.kt +++ b/opendc-core/src/main/kotlin/nl/atlarge/opendc/topology/storage/StorageUnit.kt @@ -31,4 +31,4 @@ import nl.atlarge.opendc.topology.Entity * * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) */ -interface StorageUnit: Entity +interface StorageUnit: Entity<Unit> |
