/* Ċ Ġ* ĠMIT ĠLicense Ċ Ġ* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 1 8 Ġem u fog Ġcontributors Ċ Ġ* Ċ Ġ* Ġ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 Ġem u fog . reader . ca ida Ċ Ċ import Ġem u fog . config . Config Ċ import Ġem u fog . graph . Edge Node Ċ import Ġem u fog . graph . Graph Ċ import Ġem u fog . graph . Node Ċ import Ġem u fog . reader . Graph Reader Ċ import Ġem u fog . util . ID Manager Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġjava . nio . charset . StandardCharsets Ċ import Ġjava . nio . file . Path Ċ Ċ /** Ċ Ġ* ĠThis Ġreader Ġcan Ġread Ġin Ġthe Ġ[ CA ID A ]( https :// www . ca ida . org /) Ġtopology Ġan Ġbuild Ġa Ġgraph Ġbased Ġon Ġthat Ġdata . Ċ Ġ*/ Ċ object ĠCa ida Format Reader Ġ: ĠGraph Reader Ġ{ ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReads Ġin Ġa Ġgraph Ġfrom Ġa ĠCa ida Ġdataset . ĠSuch Ġa Ġdataset Ġconsists Ġof Ġa Ġ`. nodes . geo `, Ġa Ġ`. nodes . as ` Ġand Ġa Ġ`. links ` ĊĠĠĠĠ Ġ* Ġfile . ĠThe Ġlist Ġof Ġinput Ġfiles Ġneed Ġto Ġcontain Ġthose Ġthree Ġfiles . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġfiles Ġthe Ġlist Ġof Ġfiles Ġto Ġread Ġin ĊĠĠĠĠ Ġ* Ġ@ return Ġread Ġin Ġgraph Ġobject ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġoverride Ġfun Ġread Graph ( files : ĠList < Path >): ĠGraph Ġ= ĠCa ida Format Reader Impl ( files ). read Graph () Ċ } Ċ Ċ private Ġclass ĠCa ida Format Reader Impl ( files : ĠList < Path >) Ġ{ ĊĊĠĠĠ Ġprivate Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠLOG Ġ= ĠLoggerFactory . getLogger ( Ca ida Format Reader :: class . java ) ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġinitialize Ġcharset Ġaccording Ġto Ġhttps :// en . wikipedia . org / wiki / ISO / IE C _ 8 8 5 9 - 1 ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠCHARSET Ġ= ĠStandard Charsets . ISO _ 8 8 5 9 _ 1 ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠNODE _ COLUMNS Ġ= Ġ 8 ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠAS _ COLUMNS Ġ= Ġ 3 ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠED GE _ COLUMNS Ġ= Ġ 4 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/* Ġnumber Ġof Ġtimes ĠAS Ġfield Ġexceeds Ġthe ĠInteger Ġrange Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġas No Integer Ġ= Ġ 0 ĊĊĠĠĠ Ġ/* Ġnumber Ġof Ġtimes Ġno Ġnode Ġhas Ġbeen Ġfound Ġwith Ġan ĠID Ġto Ġassign Ġan ĠAS Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġno Node Found For AS Ġ= Ġ 0 ĊĊĠĠĠ Ġ/* Ġnumber Ġof Ġtimes Ġno Ġnode Ġhas Ġbeen Ġfound Ġwith Ġan ĠID Ġto Ġestablish Ġa Ġconnection Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġno Node Found For Edge Ġ= Ġ 0 ĊĊĠĠĠ Ġ/* Ġnumber Ġof Ġtimes ĠID Ġfield Ġexceeds Ġthe ĠInteger Ġrange Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġids No Integer Ġ= Ġ 0 ĊĊĠĠĠ Ġ/* Ġnumber Ġof Ġtimes Ġa Ġnode Ġline Ġwas Ġskipped Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġnode Line Skipped Ġ= Ġ 0 ĊĊĠĠĠ Ġ/* Ġnumber Ġof Ġtimes Ġa ĠAS Ġline Ġwas Ġskipped Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġas Line Skipped Ġ= Ġ 0 ĊĊĠĠĠ Ġ/* Ġnumber Ġof Ġtimes Ġa Ġlink Ġline Ġwas Ġskipped Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġlink Line Skipped Ġ= Ġ 0 ĊĊĠĠĠ Ġ/* Ġnumber Ġof Ġtimes Ġcoordinate Ġfield Ġexceeds Ġthe ĠFloat Ġrange Ġ*/ ĊĠĠĠ Ġprivate Ġvar Ġcoordinates No Float s Ġ= Ġ 0 ĊĊĠĠĠ Ġ/* Ġmapping Ġfrom ĠID 's Ġto Ġcoordinates Ġof Ġthe Ġnodes Ġ*/ ĊĠĠĠ Ġprivate Ġval Ġnode Coordinates : ĠMutable Map < Int , ĠCoordinates > Ġ= ĠHashMap () ĊĊĠĠĠ Ġprivate Ġval Ġnodes File Ġ= ĠgetFile With Ending ( files , Ġ". nodes . geo ") ĊĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠIllegalArgumentException (" The Ġgiven Ġfiles Ġdo Ġnot Ġcontain Ġa Ġ. nodes . geo Ġfile .") ĊĊĠĠĠ Ġprivate Ġval Ġas File Ġ= ĠgetFile With Ending ( files , Ġ". nodes . as ") ĊĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠIllegalArgumentException (" The Ġgiven Ġfiles Ġdo Ġnot Ġcontain Ġa Ġ. nodes . as Ġfile .") ĊĊĠĠĠ Ġprivate Ġval Ġlink File Ġ= ĠgetFile With Ending ( files , Ġ". links ") ĊĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠIllegalArgumentException (" The Ġgiven Ġfiles Ġdo Ġnot Ġcontain Ġa Ġ. links Ġfile .") ĊĊĠĠĠ Ġprivate Ġval Ġspace Regex Ġ= Ġ"\\ s ". to Regex () ĊĊĠĠĠ Ġprivate Ġval Ġid Manager Ġ= ĠID Manager () ĊĊĠĠĠ Ġprivate Ġval Ġgraph Ġ= ĠGraph ( Config . config !! ) ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReads Ġin Ġand Ġreturns Ġa Ġ[ Graph ] Ġobject Ġfrom Ġthe Ġfirst Ġ`. nodes . geo `, Ġ`. nodes . as ` Ġand Ġ`. links ` Ġfile . ĠSk ips Ġall Ġthe ĊĠĠĠĠ Ġ* Ġlines Ġthat Ġcan Ġnot Ġbe Ġprocessed . ĠSuch Ġcases Ġare Ġcounted Ġand Ġprinted Ġto Ġthe Ġdebug Ġoutput Ġafter Ġreading Ġin Ġthe ĊĠĠĠĠ Ġ* Ġgraph . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġinternal Ġfun Ġread Graph (): ĠGraph Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġread Ġin Ġthe Ġnodes ĊĠĠĠĠĠĠĠ Ġnodes File . to File (). forEach Line ( CHARSET ) Ġ{ Ġprocess Node Line ( it ) Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġread Ġin Ġthe ĠAS ĊĠĠĠĠĠĠĠ Ġas File . to File (). forEach Line ( CHARSET ) Ġ{ Ġprocess AS Line ( it ) Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġread Ġin Ġthe Ġedges ĊĠĠĠĠĠĠĠ Ġlink File . to File (). forEach Line ( CHARSET ) Ġ{ Ġprocess Link Line ( it ) Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// Ġlog Ġerrors ĊĠĠĠĠĠĠĠ Ġlog Results () ĊĊĠĠĠĠĠĠĠ Ġreturn Ġgraph ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠLogs Ġthe Ġerrors Ġand Ġnot Ġmatching ĠIDs Ġwhile Ġreading . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġlog Results () Ġ{ ĊĠĠĠĠĠĠĠ Ġ// Ġadditional Ġlogging Ġfor Ġdebugging ĊĠĠĠĠĠĠĠ ĠLOG . debug (" ID Ġout Ġof ĠInteger Ġrange : Ġ{}", Ġids No Integer ) ĊĠĠĠĠĠĠĠ ĠLOG . debug (" AS Ġout Ġof ĠInteger Ġrange : Ġ{}", Ġas No Integer ) ĊĠĠĠĠĠĠĠ ĠLOG . debug (" Coordinates Ġout Ġof ĠFloat Ġrange : Ġ{}", Ġcoordinates No Float s ) ĊĠĠĠĠĠĠĠ ĠLOG . debug (" Number Ġof Ġtimes Ġno Ġnodes Ġwere Ġfound Ġto Ġassign Ġan ĠAS : Ġ{}", Ġno Node Found For AS ) ĊĠĠĠĠĠĠĠ ĠLOG . debug (" Number Ġof Ġtimes Ġno Ġnodes Ġwere Ġfound Ġto Ġbuild Ġan Ġedge : Ġ{}", Ġno Node Found For Edge ) ĊĠĠĠĠĠĠĠ ĠLOG . debug (" Nodes Ġread Ġwithout Ġan ĠAS : Ġ{}", Ġnode Coordinates . size ) ĊĠĠĠĠĠĠĠ ĠLOG . debug (" Number Ġof Ġnode Ġlines Ġskipped : Ġ{}", Ġnode Line Skipped ) ĊĠĠĠĠĠĠĠ ĠLOG . debug (" Number Ġof ĠAS Ġlines Ġskipped : Ġ{}", Ġas Line Skipped ) ĊĠĠĠĠĠĠĠ ĠLOG . debug (" Number Ġof Ġlink Ġlines Ġskipped : Ġ{}", Ġlink Line Skipped ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReads Ġin Ġan Ġedge Ġof Ġthe Ġgraph . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġprocess Link Line ( line : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( line . startsWith ('# ')) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= Ġline . split ( space Regex ) ĊĠĠĠĠĠĠĠ Ġif Ġ( values . size Ġ< ĠED GE _ COLUMNS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . debug (" There Ġare Ġnot Ġ{} Ġcolumns Ġin Ġthe Ġlink Ġline : Ġ{}", ĠED GE _ COLUMNS , Ġline ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlink Line Skipped ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġlink Str Ġ= Ġextract Id FromString ( values [ 1 ]) ĊĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġlink Str . toInt OrNull () ĊĠĠĠĠĠĠĠ Ġif Ġ( id Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . debug (" Failed Ġto Ġparse Ġthe Ġlink Ġid Ġ{} Ġto Ġan Ġinteger .", Ġlink Str ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġids No Integer ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġsource Str Ġ= Ġextract Id FromString ( values [ 3 ]) ĊĠĠĠĠĠĠĠ Ġval Ġsource ID Ġ= Ġsource Str . toInt OrNull () ĊĠĠĠĠĠĠĠ Ġif Ġ( source ID Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . debug (" Failed Ġto Ġparse Ġthe Ġlink 's Ġsource Ġid Ġ{} Ġto Ġan Ġinteger .", Ġsource Str ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġids No Integer ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġ 4 Ġuntil Ġvalues . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdestination Str Ġ= Ġextract Id FromString ( values [ i ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdestination ID Ġ= Ġdestination Str . toInt OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( destination ID Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . debug (" Failed Ġto Ġparse Ġthe Ġlink 's Ġdestination Ġid Ġ{} Ġto Ġan Ġinteger .", Ġdestination Str ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġids No Integer ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfrom : ĠEdge Node ? Ġ= Ġgraph . get Edge Node ( source ID ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġto : ĠEdge Node ? Ġ= Ġgraph . get Edge Node ( destination ID ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( from Ġ== Ġnull Ġ|| Ġto Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . debug (" To Ġcreate Ġa Ġlink Ġsource Ġand Ġdestination Ġmust Ġbe Ġfound .") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġno Node Found For Edge ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġchecked Id : ĠInt Ġ= Ġid ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( id Manager . is Used ( id )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchecked Id Ġ= Ġid Manager . getNext ID () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . debug (" The Ġoriginal Ġedge ĠID : Ġ{} Ġis Ġalready Ġin Ġuse . ĠUsing Ġ{} Ġinstead .", Ġid , Ġchecked Id ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgraph . create Edge ( checked Id , Ġfrom , Ġto , Ġget Latency ( from , Ġto ), Ġ 1 0 0 0 f ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġid Manager . set Used ( checked Id ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠAd ap ts Ġthe ĠAS Ġfield Ġof Ġthe Ġnode Ġidentified Ġin Ġthe Ġcurrent Ġline . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġprocess AS Line ( line : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( line . startsWith ('# ')) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= Ġline . split ( space Regex ) ĊĠĠĠĠĠĠĠ Ġif Ġ( values . size Ġ< ĠAS _ COLUMNS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġas Line Skipped ++ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . debug (" There Ġare Ġnot Ġ{} Ġcolumns Ġin Ġthe Ġaut onomous Ġsystem Ġline : Ġ{}", ĠAS _ COLUMNS , Ġline ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġnode Str Ġ= Ġextract Id FromString ( values [ 1 ]) ĊĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġnode Str . toInt OrNull () ĊĠĠĠĠĠĠĠ Ġif Ġ( id Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . debug (" Failed Ġto Ġparse Ġthe Ġid Ġ{} Ġto Ġan Ġinteger .", Ġnode Str ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġids No Integer ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġsystem Ġ= Ġvalues [ 2 ]. toInt OrNull () ĊĠĠĠĠĠĠĠ Ġif Ġ( system Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . debug (" Failed Ġto Ġparse Ġthe Ġaut onomous Ġsystem Ġid Ġ{} Ġto Ġan Ġinteger .", Ġvalues [ 2 ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġas No Integer ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġgraph . create Edge Node ( id , Ġgraph . get OrCreate Aut onomous System ( system )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠReads Ġin Ġand Ġprocess Ġa Ġline Ġof Ġthe Ġinput Ġfile Ġto Ġadd Ġa Ġnode Ġto Ġthe Ġgraph Ġgiven . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġprocess Node Line ( line : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( line . startsWith ('# ')) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= Ġline . split ( space Regex ) ĊĠĠĠĠĠĠĠ Ġif Ġ( values . size Ġ< ĠNODE _ COLUMNS ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . debug (" There Ġare Ġnot Ġ{} Ġcolumns Ġin Ġthe Ġnode Ġline : Ġ{}", ĠNODE _ COLUMNS , Ġline ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnode Line Skipped ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġnode Str Ġ= Ġextract Id FromString ( values [ 1 ]) ĊĠĠĠĠĠĠĠ Ġval Ġid Ġ= Ġnode Str . toInt OrNull () ĊĠĠĠĠĠĠĠ Ġif Ġ( id Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . debug (" Failed Ġto Ġparse Ġthe Ġid Ġ{} Ġto Ġan Ġinteger .", Ġnode Str ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġids No Integer ++ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnode Coordinates [ id ] Ġ= ĠCoordinates ( values [ 6 ]. toFloat (), Ġvalues [ 7 ]. toFloat ()) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠNumber FormatException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . debug (" Failed Ġto Ġparse Ġcoordinates Ġ{} Ġand Ġ{} Ġto Ġfloats .", Ġvalues [ 6 ], Ġvalues [ 7 ]) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcoordinates No Float s ++ ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġget Latency ( from : ĠNode , Ġto : ĠNode ): ĠFloat Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ 1 F ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġextract Id FromString ( s : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġend Ġ= Ġs . indexOf First Ġ{ Ġit Ġ== Ġ':' Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( end Ġ== Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġend Ġ= Ġs . length ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġs . substring ( 1 , Ġend ) ĊĠĠĠ Ġ} Ċ } Ċ Ċ /** Ċ Ġ* ĠCoordinates Ġof Ġa Ġnode Ġin Ġthe Ġgraph . ĠThis Ġclass Ġgets Ġmapped Ġto Ġthe Ġrespective ĠID Ġof Ġthe Ġnode . Ċ Ġ* Ċ Ġ* Ġ@ property Ġx Pos Ġx Ġcoordinate Ċ Ġ* Ġ@ property Ġy Pos Ġy Ġcoordinate Ċ Ġ*/ Ċ private Ġdata Ġclass ĠCoordinates ( val Ġx Pos : ĠFloat , Ġval Ġy Pos : ĠFloat ) Ċ Ċ /** Ċ Ġ* ĠReturns Ġthe Ġpath Ġof Ġthe Ġfile Ġmatching Ġthe Ġgiving Ġfile Ġextension Ġat Ġthe Ġend . Ċ Ġ* Ċ Ġ* Ġ@ param Ġfiles Ġlist Ġof Ġpossible Ġfiles Ċ Ġ* Ġ@ param Ġfile Extension Ġfile Ġextension Ġto Ġmatch Ċ Ġ* Ġ@ return Ġthe Ġfile Ġof Ġthe Ġlist Ġmatching Ġthe Ġextension Ġor Ġ` null ` Ġif Ġnot Ġfound Ċ Ġ*/ Ċ private Ġfun ĠgetFile With Ending ( files : ĠList < Path >, Ġfile Extension : ĠString ): ĠPath ? Ġ{ ĊĠĠĠ Ġreturn Ġfiles . first OrNull Ġ{ Ġit . toString (). endsWith ( file Extension ) Ġ} Ċ } Ċ