diff options
Diffstat (limited to 'opendc-stdlib/src/main/kotlin/com')
11 files changed, 726 insertions, 0 deletions
diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/AdjacencyList.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/AdjacencyList.kt new file mode 100644 index 00000000..c042a2d5 --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/AdjacencyList.kt @@ -0,0 +1,260 @@ +/* + * 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 com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Entity +import com.atlarge.opendc.model.topology.Edge as BaseEdge +import java.util.concurrent.atomic.AtomicInteger + +/** + * This module provides a [Topology] implementation backed internally by an adjacency list. + * + * This implementation is best suited for sparse graphs, where an adjacency matrix would take up too much space with + * empty cells. + * + * *Note that this implementation is not synchronized.* + */ +object AdjacencyList { + /** + * Return a [TopologyBuilder] that constructs the topology represents as an adjacency list. + * + * @return A [TopologyBuilder] instance. + */ + fun builder(): TopologyBuilder = AdjacencyListTopologyBuilder() +} + +/** + * A builder for [Topology] instances, which is backed by an adjacency list. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +internal class AdjacencyListTopologyBuilder : TopologyBuilder { + /** + * Build a [Topology] instance from the current state of this builder. + * + * @return The graph built from this builder. + */ + override fun create(): MutableTopology = AdjacencyListTopology() +} + +/** + * A [Topology] whose graph is represented as adjacency list. + */ +internal class AdjacencyListTopology : MutableTopology { + /** + * The identifier for the next node in the graph. + */ + private var nextId: AtomicInteger = AtomicInteger(0) + + /** + * A mapping of nodes to their internal representation with the edges of the nodes. + */ + private var nodes: MutableMap<Entity<*, Topology>, Node> = HashMap() + + // Topology + + /** + * The listeners of this topology. + */ + override val listeners: MutableSet<TopologyListener> = HashSet() + + /** + * A unique identifier of this node within the topology. + */ + override val Entity<*, Topology>.id: Int + get() = nodes[this]!!.id + + /** + * The set of ingoing edges of this node. + */ + override val Entity<*, Topology>.ingoingEdges: MutableSet<BaseEdge<*>> + get() = nodes[this]!!.ingoingEdges + + /** + * The set of outgoing edges of this node. + */ + override val Entity<*, Topology>.outgoingEdges: MutableSet<BaseEdge<*>> + get() = nodes[this]!!.outgoingEdges + + // MutableTopology + + /** + * 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: Entity<*, Topology>, to: Entity<*, Topology>, label: T, tag: String?): BaseEdge<T> { + if (!contains(from) || !contains(to)) + throw IllegalArgumentException("One of the entities is not part of the topology") + val edge = Edge(label, tag, from, to) + from.outgoingEdges.add(edge) + to.ingoingEdges.add(edge) + listeners.forEach { it.run { this@AdjacencyListTopology.onEdgeAdded(edge) } } + return edge + } + + // Cloneable + + /** + * Create a copy of the graph. + * + * @return A new [Topology] instance with a copy of the graph. + */ + override fun clone(): Topology { + val copy = AdjacencyListTopology() + copy.nextId = AtomicInteger(nextId.get()) + copy.nodes = HashMap(nodes) + return copy + } + + // Set + + /** + * Returns the size of the collection. + */ + override val size: Int = nodes.size + + /** + * Checks if the specified element is contained in this collection. + */ + override fun contains(element: Entity<*, Topology>): Boolean = nodes.contains(element) + + /** + * Checks if all elements in the specified collection are contained in this collection. + */ + override fun containsAll(elements: Collection<Entity<*, Topology>>): Boolean = + elements.all { nodes.containsKey(it) } + + /** + * Returns `true` if the collection is empty (contains no elements), `false` otherwise. + */ + override fun isEmpty(): Boolean = nodes.isEmpty() + + // MutableSet + + /** + * Add a node to the graph. + * + * @param element The element to add to this graph. + * @return `true` if the graph has changed, `false` otherwise. + */ + override fun add(element: Entity<*, Topology>): Boolean { + if (nodes.putIfAbsent(element, Node(nextId.getAndIncrement())) == null) { + listeners.forEach { it.run { this@AdjacencyListTopology.onNodeAdded(element) } } + return true + } + return false + } + + /** + * Add all nodes in the specified collection to the graph. + * + * @param elements The nodes to add to this graph. + * @return `true` if the graph has changed, `false` otherwise. + */ + override fun addAll(elements: Collection<Entity<*, Topology>>): Boolean = elements.any { add(it) } + + /** + * Remove all nodes and their respective edges from the graph. + */ + override fun clear() = nodes.clear() + + /** + * Remove the given node and its edges from the graph. + * + * @param element The element to remove from the graph. + * @return `true` if the graph has changed, `false` otherwise. + */ + override fun remove(element: Entity<*, Topology>): Boolean { + nodes[element]?.ingoingEdges?.forEach { + it.from.outgoingEdges.remove(it) + } + nodes[element]?.outgoingEdges?.forEach { + it.to.ingoingEdges.remove(it) + } + if (nodes.keys.remove(element)) { + listeners.forEach { it.run { this@AdjacencyListTopology.onNodeRemoved(element) } } + return true + } + return false + } + + + /** + * Remove all nodes in the given collection from the graph. + * + * @param elements The elements to remove from the graph. + * @return `true` if the graph has changed, `false` otherwise. + */ + override fun removeAll(elements: Collection<Entity<*, Topology>>): Boolean = elements.any(this::remove) + + /** + * Remove all nodes in the graph, except those in the specified collection. + * + * Take note that this method currently only guarantees a maximum runtime complexity of O(n^2). + * + * @param elements The elements to retain in the graph. + */ + override fun retainAll(elements: Collection<Entity<*, Topology>>): Boolean { + val iterator = nodes.keys.iterator() + var changed = false + while (iterator.hasNext()) { + val entity = iterator.next() + + if (entity !in elements) { + iterator.remove() + changed = true + } + } + return changed + } + + /** + * Return a mutable iterator over the nodes of the graph. + * + * @return A [MutableIterator] over the nodes of the graph. + */ + override fun iterator(): MutableIterator<Entity<*, Topology>> = nodes.keys.iterator() + + /** + * The internal representation of a node within the graph. + */ + internal data class Node(val id: Int) { + val ingoingEdges: MutableSet<BaseEdge<*>> = HashSet() + val outgoingEdges: MutableSet<BaseEdge<*>> = HashSet() + } + + /** + * The internal representation of an edge within the graph. + */ + internal class Edge<out T>(override val label: T, + override val tag: String?, + override val from: Entity<*, Topology>, + override val to: Entity<*, Topology>) : BaseEdge<T> +} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Bootstrap.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Bootstrap.kt new file mode 100644 index 00000000..de9a41d5 --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Bootstrap.kt @@ -0,0 +1,23 @@ +package com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Bootstrap +import com.atlarge.opendc.simulator.Entity + +/** + * Create a [Bootstrap] procedure for the given [Topology]. + * + * @return A bootstrap procedure for the topology. + */ +fun <T: Topology> T.bootstrap(): Bootstrap<T> = Bootstrap.create { ctx -> + forEach { ctx.register(it) } + listeners += object : TopologyListener { + override fun Topology.onNodeAdded(node: Entity<*, Topology>) { + ctx.register(node) + } + + override fun Topology.onNodeRemoved(node: Entity<*, Topology>) { + ctx.deregister(node) + } + } + this +} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Component.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Component.kt new file mode 100644 index 00000000..5e8611a0 --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Component.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 com.atlarge.opendc.model.topology + +/** + * A component within a [Topology], which is either a node or an [Edge] representing the relationship between + * entities within a logical topology of a cloud network. + ** + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Component diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Edge.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Edge.kt new file mode 100644 index 00000000..3e507887 --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Edge.kt @@ -0,0 +1,61 @@ +/* + * 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 com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Entity + +/** + * An edge that represents a directed relationship between exactly two nodes in a logical topology of a cloud network. + * + * @param T The relationship type the edge represents within a logical topology. + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface Edge<out T> : Component { + /** + * The label of this edge. + */ + val label: T + + /** + * A tag to uniquely identify the relationship this edge represents. + */ + val tag: String? + + /** + * The source of the 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. + */ + val from: Entity<*, Topology> + + /** + * The destination of the 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. + */ + val to: Entity<*, Topology> +} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/MutableTopology.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/MutableTopology.kt new file mode 100644 index 00000000..ac1b4ba5 --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/MutableTopology.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 com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Entity + +/** + * 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, MutableSet<Entity<*, Topology>> { + /** + * Create a directed, labeled edge between two nodes 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: Entity<*, Topology>, to: Entity<*, Topology>, label: T, tag: String? = null): Edge<T> + + /** + * Create a directed, unlabeled edge between two nodes 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: Entity<*, Topology>, to: Entity<*, Topology>, tag: String? = null): Edge<Unit> = + connect(from, to, Unit, tag) + + /** + * Create a directed, unlabeled edge between two nodes in the topology. + * + * @param dest The destination of the edge. + * @return The edge that has been created. + */ + infix fun Entity<*, Topology>.to(dest: Entity<*, Topology>): Edge<Unit> = connect(this, dest) +} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Topology.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Topology.kt new file mode 100644 index 00000000..1e5a404f --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Topology.kt @@ -0,0 +1,50 @@ +/* + * 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 com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Entity + +/** + * A graph data structure which represents the logical topology of a cloud network consisting of one or more + * datacenters. + * + * 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 Topology : TopologyContext, Cloneable, Set<Entity<*, Topology>> { + /** + * The listeners of this topology. + */ + val listeners: MutableSet<TopologyListener> + + /** + * Create a copy of the topology. + * + * @return A new [Topology] with a copy of the graph. + */ + public override fun clone(): Topology +} + diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyBuilder.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyBuilder.kt new file mode 100644 index 00000000..44b1cb4e --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyBuilder.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 com.atlarge.opendc.model.topology + +/** + * A builder for [Topology] instances. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface TopologyBuilder : TopologyFactory { + /** + * Construct a [Topology] from the given block and return it. + * + * @param block The block to construct the topology. + * @return The topology that has been built. + */ + fun construct(block: MutableTopology.() -> Unit): MutableTopology = create().apply(block) +} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyContext.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyContext.kt new file mode 100644 index 00000000..2bf87a39 --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyContext.kt @@ -0,0 +1,50 @@ +/* + * 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 com.atlarge.opendc.model.topology + +import com.atlarge.opendc.simulator.Entity + +/** + * A [TopologyContext] represents the context for entities in a specific topology, providing access to the identifier + * and ingoing and outgoing edges of the [Entity] within a [Topology]. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface TopologyContext { + /** + * A unique identifier of an [Entity] within the topology. + */ + val Entity<*, Topology>.id: Int + + /** + * The set of ingoing edges of an [Entity]. + */ + val Entity<*, Topology>.ingoingEdges: Set<Edge<*>> + + /** + * The set of outgoing edges of an [Entity]. + */ + val Entity<*, Topology>.outgoingEdges: Set<Edge<*>> +} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyFactory.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyFactory.kt new file mode 100644 index 00000000..35cfa97a --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyFactory.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 com.atlarge.opendc.model.topology + +/** + * An interface for producing [Topology] instances. Implementors of this interface provide a way of generating a + * topology based on the state of the factory. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface TopologyFactory { + /** + * Create a [MutableTopology] instance. + * + * @return A mutable topology. + */ + fun create(): MutableTopology +} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyListener.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyListener.kt new file mode 100644 index 00000000..93108cc0 --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/TopologyListener.kt @@ -0,0 +1,63 @@ +/* + * 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 com.atlarge.opendc.model.topology; + +import com.atlarge.opendc.simulator.Entity + +/** + * A listener interface for [Topology] instances. The methods of this interface are invoked on + * mutation of the topology the listener is listening to. + * + * @author Fabian Mastenbroek (f.s.mastenbroek@student.tudelft.nl) + */ +interface TopologyListener { + /** + * This method is invoked when an [Entity] is added to the [Topology]. + * + * @param node The entity that has been added to the [Topology]. + */ + fun Topology.onNodeAdded(node: Entity<*, Topology>) {} + + /** + * This method is invoked when an [Entity] is removed from the [Topology]. + * + * @param node The entity that has been removed from the [Topology]. + */ + fun Topology.onNodeRemoved(node: Entity<*, Topology>) {} + + /** + * This method is invoked when an [Edge] is added to the [Topology]. + * + * @param edge The edge that has been added to the [Topology]. + */ + fun Topology.onEdgeAdded(edge: Edge<*>) {} + + /** + * This method is invoked when an [Edge] is removed from the [Topology]. + * + * @param edge The entity that has been removed from the [Topology]. + */ + fun Topology.onEdgeRemoved(edge: Edge<*>) {} +} diff --git a/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Traversable.kt b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Traversable.kt new file mode 100644 index 00000000..23720c46 --- /dev/null +++ b/opendc-stdlib/src/main/kotlin/com/atlarge/opendc/model/topology/Traversable.kt @@ -0,0 +1,41 @@ +/* + * 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 com.atlarge.opendc.model.topology + +/** + * Filter a [Set] of [Edge]s based on the tag of the edges and return the origin nodes casted to type `T`. + * + * @param tag The tag of the edges to get. + * @return An [Iterable] of the specified type `T` with the given tag. + */ +inline fun <reified T> Set<Edge<*>>.origins(tag: String) = filter { it.tag == tag }.map { it.from as T } + +/** + * Filter a [Set] of [Edge]s based on the tag of the edges and return the destination nodes casted to type `T`. + * + * @param tag The tag of the edges to get. + * @return An [Iterable] of the specified type `T` with the given tag. + */ +inline fun <reified T> Set<Edge<*>>.destinations(tag: String) = filter { it.tag == tag }.map { it.to as T } |
