11import { RunningProgram } from "../../programs" ;
22import { DeviceType , Layer , layerFromType } from "../devices/device" ;
33import { layerIncluded } from "../devices/layer" ;
4+ import { Graph , VertexId } from "./graph" ;
45
5- export type DeviceId = number ;
6+ export type DeviceId = VertexId ;
67
78interface CommonGraphNode {
89 x : number ;
910 y : number ;
1011 type : DeviceType ;
11- connections : Set < DeviceId > ;
1212}
1313
1414interface LinkGraphNode extends CommonGraphNode {
@@ -120,34 +120,28 @@ export interface NewDevice {
120120}
121121
122122export class DataGraph {
123- private devices = new Map < DeviceId , GraphNode > ( ) ;
123+ // NOTE: we don't store data in edges yet
124+ private deviceGraph = new Graph < GraphNode , unknown > ( ) ;
124125 private idCounter : DeviceId = 1 ;
125126 private onChanges : ( ( ) => void ) [ ] = [ ] ;
126127
127128 static fromData ( data : GraphData ) : DataGraph {
128129 const dataGraph = new DataGraph ( ) ;
129130 data . forEach ( ( nodeData : GraphDataNode ) => {
130131 console . log ( nodeData ) ;
131- const connections = new Set ( nodeData . connections ) ;
132132
133- let graphNode : GraphNode ;
133+ let graphNode : GraphNode = nodeData ;
134134
135135 if ( nodeData . type === DeviceType . Router ) {
136136 // If the node is a router, include the routing table
137137 const routerNode = nodeData as RouterDataNode ;
138138 graphNode = {
139139 ...routerNode ,
140- connections : connections ,
141140 routingTable : routerNode . routingTable || [ ] , // Ensure routingTable exists
142141 } ;
143- } else {
144- graphNode = {
145- ...nodeData ,
146- connections : connections ,
147- } ;
148142 }
149143
150- dataGraph . addDevice ( nodeData . id , graphNode ) ;
144+ dataGraph . addDevice ( nodeData . id , graphNode , nodeData . connections ) ;
151145 } ) ;
152146
153147 return dataGraph ;
@@ -157,43 +151,45 @@ export class DataGraph {
157151 const graphData : GraphData = [ ] ;
158152
159153 // Serialize nodes
160- this . getDevices ( ) . forEach ( ( info , id ) => {
154+ for ( const [ id , info ] of this . deviceGraph . getVertices ( ) ) {
161155 const graphNode : GraphDataNode = {
162156 ...info ,
163157 id,
164- connections : Array . from ( info . connections . values ( ) ) ,
158+ connections : Array . from ( this . deviceGraph . getNeighbors ( id ) ) ,
165159 } ;
166160 graphData . push ( graphNode ) ;
167- } ) ;
161+ }
168162 return graphData ;
169163 }
170164
171165 // Add a new device to the graph
172166 addNewDevice ( deviceInfo : NewDevice ) : DeviceId {
173167 const id = this . idCounter ++ ;
174- // const graphNode: GraphNode = DataGraph.createGraphNode(deviceInfo);
175168 const graphnode : GraphNode = {
176169 ...deviceInfo ,
177- connections : new Set < number > ( ) ,
178170 routingTable : [ ] ,
179171 runningPrograms : [ ] ,
180172 arpTable : new Map ( ) ,
181173 } ;
182- this . devices . set ( id , graphnode ) ;
174+ this . deviceGraph . setVertex ( id , graphnode ) ;
183175 console . log ( `Device added with ID ${ id } ` ) ;
184176 this . notifyChanges ( ) ;
185177 return id ;
186178 }
187179
188180 // Add a device to the graph
189- addDevice ( idDevice : DeviceId , deviceInfo : GraphNode ) {
190- if ( this . devices . has ( idDevice ) ) {
181+ addDevice (
182+ idDevice : DeviceId ,
183+ deviceInfo : GraphNode ,
184+ connections : DeviceId [ ] ,
185+ ) {
186+ if ( this . deviceGraph . hasVertex ( idDevice ) ) {
191187 console . warn ( `Device with ID ${ idDevice } already exists in the graph.` ) ;
192188 return ;
193189 }
194- this . devices . set ( idDevice , deviceInfo ) ;
195- deviceInfo . connections . forEach ( ( connectedId ) => {
196- this . devices . get ( connectedId ) ?. connections . add ( idDevice ) ;
190+ this . deviceGraph . setVertex ( idDevice , deviceInfo ) ;
191+ connections . forEach ( ( connectedId ) => {
192+ this . deviceGraph . setEdge ( idDevice , connectedId ) ;
197193 } ) ;
198194 if ( this . idCounter <= idDevice ) {
199195 this . idCounter = idDevice + 1 ;
@@ -210,25 +206,21 @@ export class DataGraph {
210206 ) ;
211207 return ;
212208 }
213- const device1 = this . devices . get ( n1Id ) ;
214- const device2 = this . devices . get ( n2Id ) ;
215- if ( ! device1 ) {
216- console . warn ( `Device with ID ${ n1Id } does not exist in devices.` ) ;
209+ if ( ! this . deviceGraph . hasVertex ( n1Id ) ) {
210+ console . warn ( `Device with ID ${ n1Id } does not exist.` ) ;
217211 return ;
218212 }
219- if ( ! device2 ) {
220- console . warn ( `Device with ID ${ n2Id } does not exist in devices .` ) ;
213+ if ( ! this . deviceGraph . hasVertex ( n2Id ) ) {
214+ console . warn ( `Device with ID ${ n2Id } does not exist.` ) ;
221215 return ;
222- // Check if an edge already exists between these two devices
223216 }
224- if ( device1 . connections . has ( n2Id ) ) {
217+ if ( this . deviceGraph . hasEdge ( n1Id , n2Id ) ) {
225218 console . warn (
226219 `Connection between ID ${ n1Id } and ID ${ n2Id } already exists.` ,
227220 ) ;
228221 return ;
229222 }
230- device1 . connections . add ( n2Id ) ;
231- device2 . connections . add ( n1Id ) ;
223+ this . deviceGraph . setEdge ( n1Id , n2Id ) ;
232224
233225 console . log (
234226 `Connection created between devices ID: ${ n1Id } and ID: ${ n2Id } ` ,
@@ -238,101 +230,60 @@ export class DataGraph {
238230 }
239231
240232 updateDevicePosition ( id : DeviceId , newValues : { x ?: number ; y ?: number } ) {
241- const deviceGraphNode = this . devices . get ( id ) ;
233+ const deviceGraphNode = this . deviceGraph . getVertex ( id ) ;
242234 if ( ! deviceGraphNode ) {
243235 console . warn ( "Device's id is not registered" ) ;
244236 return ;
245237 }
246- this . devices . set ( id , { ...deviceGraphNode , ...newValues } ) ;
238+ this . deviceGraph . setVertex ( id , { ...deviceGraphNode , ...newValues } ) ;
247239 this . notifyChanges ( ) ;
248240 }
249241
250242 // Get a device by its ID.
251243 // WARNING: don't modify the device directly, use `modifyDevice` instead
252244 getDevice ( id : DeviceId ) : GraphNode | undefined {
253- return this . devices . get ( id ) ;
245+ return this . deviceGraph . getVertex ( id ) ;
254246 }
255247
256248 // Modify a device in the graph, notifying subscribers of any changes
257249 modifyDevice ( id : DeviceId , fn : ( d : GraphNode | undefined ) => void ) {
258- const device = this . devices . get ( id ) ;
250+ const device = this . deviceGraph . getVertex ( id ) ;
259251 fn ( device ) ;
260252 if ( device ) {
261253 this . notifyChanges ( ) ;
262254 }
263255 }
264256
265- // Get all connections of a device
266- getConnections ( id : DeviceId ) : DeviceId [ ] {
267- const deviceInfo = this . devices . get ( id ) ;
268- return deviceInfo . connections
269- ? Array . from ( deviceInfo . connections . values ( ) )
270- : [ ] ;
271- }
272-
273257 // Get all devices in the graph
274- getDevices ( ) : Map < DeviceId , GraphNode > {
275- return this . devices ;
258+ getDevices ( ) : IterableIterator < [ DeviceId , GraphNode ] > {
259+ return this . deviceGraph . getVertices ( ) ;
276260 }
277261
278262 // Get the number of devices in the graph
279263 getDeviceCount ( ) : number {
280- return this . devices . size ;
264+ return this . deviceGraph . getVertexCount ( ) ;
265+ }
266+
267+ // Get all connections of a device
268+ getConnections ( id : DeviceId ) : DeviceId [ ] | undefined {
269+ return this . deviceGraph . getNeighbors ( id ) ;
281270 }
282271
283272 // Method to remove a device and all its connections
284273 removeDevice ( id : DeviceId ) : void {
285- const device = this . devices . get ( id ) ;
286-
287- if ( ! device ) {
274+ if ( ! this . deviceGraph . hasVertex ( id ) ) {
288275 console . warn ( `Device with ID ${ id } does not exist in the graph.` ) ;
289276 return ;
290277 }
291-
292- // Remove the connection of the current node in connected devices
293- device . connections . forEach ( ( connectedId ) => {
294- // can be done directly by the device
295- const connectedDevice = this . devices . get ( connectedId ) ;
296- if ( connectedDevice ) {
297- connectedDevice . connections . delete ( id ) ;
298- } else {
299- console . warn ( `Connected device ${ connectedId } does not exist` ) ;
300- }
301- } ) ;
302-
303- // Remove the node from the graph
304- this . devices . delete ( id ) ;
278+ this . deviceGraph . removeVertex ( id ) ;
305279 console . log ( `Device with ID ${ id } and its connections were removed.` ) ;
306280 this . notifyChanges ( ) ;
307281 this . regenerateAllRoutingTables ( ) ;
308282 }
309283
310284 // Method to remove a connection (edge) between two devices by their IDs
311285 removeConnection ( n1Id : DeviceId , n2Id : DeviceId ) : void {
312- const device1 = this . devices . get ( n1Id ) ;
313- const device2 = this . devices . get ( n2Id ) ;
314-
315- if ( ! device1 ) {
316- console . warn ( `Device with ID ${ n1Id } does not exist in the graph.` ) ;
317- return ;
318- }
319-
320- if ( ! device2 ) {
321- console . warn ( `Device with ID ${ n2Id } does not exist in the graph.` ) ;
322- return ;
323- }
324-
325- // Check if the connection exists
326- if ( ! device1 . connections . has ( n2Id ) || ! device2 . connections . has ( n1Id ) ) {
327- console . warn (
328- `Connection between ID ${ n1Id } and ID ${ n2Id } does not exist.` ,
329- ) ;
330- return ;
331- }
332-
333- // Remove the connection in both devices
334- device1 . connections . delete ( n2Id ) ;
335- device2 . connections . delete ( n1Id ) ;
286+ this . deviceGraph . removeEdge ( n1Id , n2Id ) ;
336287
337288 console . log (
338289 `Connection removed between devices ID: ${ n1Id } and ID: ${ n2Id } ` ,
@@ -351,46 +302,42 @@ export class DataGraph {
351302
352303 regenerateAllRoutingTables ( ) {
353304 console . log ( "Regenerating all routing tables" ) ;
354- this . devices . forEach ( ( _ , id ) => this . regenerateRoutingTable ( id ) ) ;
305+ for ( const [ id ] of this . deviceGraph . getVertices ( ) ) {
306+ this . regenerateRoutingTable ( id ) ;
307+ }
355308 }
356309
357- public regenerateRoutingTableClean ( id : DeviceId ) : RoutingTableEntry [ ] {
310+ regenerateRoutingTableClean ( id : DeviceId ) : RoutingTableEntry [ ] {
358311 return this . generateRoutingTable ( id ) ;
359312 }
360313
361- public regenerateRoutingTable ( id : DeviceId ) {
362- const router = this . devices . get ( id ) ;
314+ regenerateRoutingTable ( id : DeviceId ) {
315+ const router = this . deviceGraph . getVertex ( id ) ;
363316 if ( ! isRouter ( router ) ) return ;
364317
365318 router . routingTable = this . generateRoutingTable ( id , true ) ;
366- // console.log(
367- // `Routing table regenerated for router ID ${id}:`,
368- // router.routingTable,
369- // );
370319 }
371320
372321 private generateRoutingTable (
373322 id : DeviceId ,
374323 preserveEdits = false ,
375324 ) : RoutingTableEntry [ ] {
376- const router = this . devices . get ( id ) ;
325+ const router = this . deviceGraph . getVertex ( id ) ;
377326 if ( ! isRouter ( router ) ) {
378327 return [ ] ;
379328 }
380329
381- // console.log(
382- // `Regenerating ${preserveEdits ? "full" : "clean"} routing table for ID ${id}`,
383- // );
384330 const parents = new Map < DeviceId , DeviceId > ( ) ;
385331 parents . set ( id , id ) ;
386332 const queue = [ id ] ;
387333
388334 while ( queue . length > 0 ) {
389335 const currentId = queue . shift ( ) ;
390- const current = this . devices . get ( currentId ) ;
336+ const current = this . deviceGraph . getVertex ( currentId ) ;
391337 if ( isHost ( current ) ) continue ;
392338
393- current . connections . forEach ( ( connectedId ) => {
339+ const neighbors = this . deviceGraph . getNeighbors ( currentId ) ;
340+ neighbors . forEach ( ( connectedId ) => {
394341 if ( ! parents . has ( connectedId ) ) {
395342 parents . set ( connectedId , currentId ) ;
396343 queue . push ( connectedId ) ;
@@ -410,7 +357,7 @@ export class DataGraph {
410357 currentId = parentId ;
411358 }
412359
413- const dst = this . devices . get ( dstId ) ;
360+ const dst = this . deviceGraph . getVertex ( dstId ) ;
414361
415362 if ( isNetworkNode ( dst ) ) {
416363 newTable . push ( {
0 commit comments