Skip to content

Commit

Permalink
Merge pull request #18 from AmyangXYZ/jem/features
Browse files Browse the repository at this point in the history
Jem/features
  • Loading branch information
AmyangXYZ authored Jan 29, 2024
2 parents a38f685 + 75c5c0f commit 29d6042
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 27 deletions.
45 changes: 26 additions & 19 deletions src/components/FlowsPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,45 +7,52 @@ const columns: any = [
key: 'flow_id',
title: 'ID',
dataKey: 'flow_id',
width: 60,
width: 40,
align: 'center',
cellRenderer: ({ rowIndex }: any) => rowIndex + 1
},
{
key: 'src',
title: 'Source',
dataKey: 'src',
title: 'SRC',
dataKey: 'e2e_src',
width: 40,
align: 'center'
},
{
key: 'dst',
title: 'Dest',
dataKey: 'dst',
title: 'DST',
dataKey: 'e2e_dst',
width: 40,
align: 'center'
},
// {
// key: 'deadline',
// title: 'Deadline',
// dataKey: 'deadline',
// width: 50,
// align: 'center'
// },
{
key: 'deadline',
title: 'Deadline',
dataKey: 'deadline',
width: 50,
key: 'period',
title: 'PERIOD',
dataKey: 'period',
width: 40,
align: 'center'
},
{
key: 'period',
title: 'Period',
dataKey: 'period',
width: 60,
key: 'path',
title: 'PATH',
dataKey: 'path',
width: 120,
align: 'center'
},
{
key: 'payload_size',
title: 'Payload Size',
dataKey: 'payload_size',
width: 100,
align: 'center',
cellRenderer: ({ cellData: payload_size }: any) => payload_size.toString()
key: 'workload',
title: 'WORKLOAD',
dataKey: 'workload',
width: 50,
align: 'center'
// cellRenderer: ({ cellData: payload_size }: any) => payload_size.toString()
}
]
Expand Down
116 changes: 109 additions & 7 deletions src/core/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,24 @@ import {
type ASNMsgPayload,
LINK_TYPE,
type InitMsgPayload,
PROTOCOL_TYPE
PROTOCOL_TYPE,
type RoutingGraph
} from './typedefs'
import { SeededRandom } from '@/utils/rand'

import presetTopos from './preset_topologies.json'
import presetTopos from './preset_topologies.json'

export class NetworkHub {
Config: Ref<Config>
Nodes: Ref<Node[]>
Links = ref<Link[]>([])
Links = ref<{ [uid: number]: Link }>({})
Flows = ref<Flow[]>([])
Packets = ref<Packet[]>([])
PacketsCurrent = ref<Packet[]>([])
Logs = ref<string[]>([])
ASN = ref<number>(0) // absolute slot number
Rand: SeededRandom
RoutingGraph = ref<RoutingGraph>()

// to find nearest neighbors, only network devices are inserted in KDTrees
kdTreeAny: KDTree // any network devices
Expand Down Expand Up @@ -151,12 +153,12 @@ export class NetworkHub {
}
}
this.Nodes.value = [<Node>{ id: 0 }] // placeholder to let node_id start from 1
this.Links.value = []
this.Links.value = {}
}
LoadTopology() {
this.Running.value = false
clearInterval(this.asnTimer)
this.Links.value = []
this.Links.value = {}
this.Packets.value = []
this.PacketsCurrent.value = []
this.ASN.value = 0
Expand Down Expand Up @@ -200,7 +202,7 @@ export class NetworkHub {
this.kdTreeTSCH = new KDTree()
this.kdTreeTSN = new KDTree()
this.kdTreeFiveGgNB = new KDTree()
this.Links.value = []
this.Links.value = {}
for (const n of this.Nodes.value) {
if (n.id == 0 || n.type > 10) continue
this.kdTreeAny.Insert(new KDNode(n.id, n.pos))
Expand All @@ -220,7 +222,7 @@ export class NetworkHub {
}

for (const n of this.Nodes.value) {
if (n.id == 0) continue
if (n.id == 0) continue

let neighbors: any = []

Expand Down Expand Up @@ -350,6 +352,106 @@ export class NetworkHub {
}
}

constructRoutingGraph() {
const graph: RoutingGraph = {}

for (const link of Object.values(this.Links.value)) {
if (link === undefined) continue

const v1 = link.v1
const v2 = link.v2

if (graph[v1]) {
graph[v1].push(v2)
} else {
graph[v1] = [v2]
}

if (graph[v2]) {
graph[v2].push(v1)
} else {
graph[v2] = [v1]
}
}

this.RoutingGraph.value = graph
}

findPath(srcId: number, dstId: number) {
// Dijkstra's shortest path algorithm
const graph = this.RoutingGraph.value || {} // null check
const distances: { [nodeId: number]: number } = {}
const previous: { [nodeId: number]: number | null } = {}

// initialize distance and previous
for (const nodeId in graph) {
distances[nodeId] = parseInt(nodeId) === srcId ? 0 : Infinity
previous[nodeId] = null
}

const unvisited = Object.keys(graph).map((id) => parseInt(id))

while (unvisited.length > 0) {
// node w/ smallest distance
let smallest = 0
for (let i = 1; i < unvisited.length; i++) {
if (distances[unvisited[i]] < distances[unvisited[smallest]]) {
smallest = i
}
}
const current = unvisited[smallest]

// mark visited
unvisited.splice(smallest, 1)

// update distances of neighbors
for (const neighbor of graph[current]) {
const alt = distances[current] + 1
if (alt < distances[neighbor]) {
distances[neighbor] = alt
previous[neighbor] = current
}
}
}

// construct path from previous
const pathIds: number[] = []
let current: number | null = dstId
while (current != null) {
pathIds.unshift(current)
current = previous[current]
}

return pathIds
}

AddFlows(num_flows: number) {

const endSystems = this.Nodes.value.filter(n => n.type >= 11)

for (let i = 0; i < num_flows; i++) {
const src = endSystems[Math.floor(this.Rand.next() * endSystems.length)]

let dst = src
while (dst.id === src.id) {
dst = endSystems[Math.floor(this.Rand.next() * endSystems.length)]
}

const f = <Flow>{
id: this.Flows.value.length,
e2e_src: src.id,
e2e_dst: dst.id,
period: Math.floor(this.Rand.next() * 10), // from 0 to 9 - change this later
deadline: Math.floor(this.Rand.next() * 10), // from 0 to 9 - change this later
workload: Math.floor(this.Rand.next() * 10), // from 0 to 9 - change this later
path: this.findPath(src.id, dst.id)
}
this.Flows.value.push(f)

this.Logs.value.unshift(`New flow: ID:${f.id}, source:${f.e2e_src}, dest:${f.e2e_dst}.`)
}
}

Run = () => {
this.Logs.value.unshift('Emulation started.')
this.ASN.value++
Expand Down
5 changes: 5 additions & 0 deletions src/core/typedefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export interface Flow {
deadline: number
period: number
workload: number
path: number[] // id's of all nodes in path
}

// Packet is transfered among nodes, at data-link layer
Expand Down Expand Up @@ -124,3 +125,7 @@ export interface InitMsgPayload {
export interface ASNMsgPayload {
asn: number
}

export interface RoutingGraph {
[id: number]: number[]
}
8 changes: 7 additions & 1 deletion src/hooks/useDrawTopology.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ export async function useDrawTopology(dom: HTMLElement) {
box.getSize(size)
const label = createLabel(`${NODE_TYPE_DISPLAY_NAME[NODE_TYPE[node.type]]}-${node.id}`)
label.position.set(model.position.x, size.y + 1, model.position.z) // Adjust the position as needed
if (node.type == NODE_TYPE.TSN) {
label.position.y = size.y + 3
}
scene.add(label)

// dragbox and helper
Expand Down Expand Up @@ -578,13 +581,16 @@ export async function useDrawTopology(dom: HTMLElement) {
animate()

await loadGLTFModels()

Network.LoadTopology()
drawNodes()
createDragControls()
Network.EstablishConnection()
Network.StartWebWorkers()

drawLinks()
Network.constructRoutingGraph()
Network.AddFlows(10) // specify number of flows

// ###################

watch(SignalAddNode, () => {
Expand Down

0 comments on commit 29d6042

Please sign in to comment.