From b2d5fc7efb21bf6c03d6d73a5d09ed4ff1b99df3 Mon Sep 17 00:00:00 2001 From: eric bryant Date: Thu, 15 Jan 2026 07:54:21 -0500 Subject: [PATCH 1/4] use segment_name when no GLE system restrictions --- siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp | 8 ++++++-- .../cplusplus/classes/GraphGeneration/HighwayGraph.cpp | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp b/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp index e3f0929..573e733 100644 --- a/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp +++ b/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp @@ -100,7 +100,9 @@ void HGEdge::detach() // write line to tmg collapsed edge file void HGEdge::collapsed_tmg_line(std::ofstream& file, char* fstr, unsigned int threadnum, std::vector *systems) { file << vertex1->c_vertex_num[threadnum] << ' ' << vertex2->c_vertex_num[threadnum] << ' '; - segment->write_label(file, systems); + if (systems) + segment->write_label(file, systems); + else file << segment_name; for (HGVertex *intermediate : intermediate_points) { *fmt::format_to(fstr, " {:.15} {:.15}", intermediate->lat, intermediate->lng) = 0; file << fstr; @@ -111,7 +113,9 @@ void HGEdge::collapsed_tmg_line(std::ofstream& file, char* fstr, unsigned int th // write line to tmg traveled edge file void HGEdge::traveled_tmg_line(std::ofstream& file, char* fstr, unsigned int threadnum, std::vector *systems, bool trav, char* code) { file << vertex1->t_vertex_num[threadnum] << ' ' << vertex2->t_vertex_num[threadnum] << ' '; - segment->write_label(file, systems); + if (systems) + segment->write_label(file, systems); + else file << segment_name; file << ' ' << (trav ? segment->clinchedby_code(code, threadnum) : "0"); for (HGVertex *intermediate : intermediate_points) { *fmt::format_to(fstr, " {:.15} {:.15}", intermediate->lat, intermediate->lng) = 0; diff --git a/siteupdate/cplusplus/classes/GraphGeneration/HighwayGraph.cpp b/siteupdate/cplusplus/classes/GraphGeneration/HighwayGraph.cpp index 3d9d6b7..ef6d8fa 100644 --- a/siteupdate/cplusplus/classes/GraphGeneration/HighwayGraph.cpp +++ b/siteupdate/cplusplus/classes/GraphGeneration/HighwayGraph.cpp @@ -402,7 +402,7 @@ void HighwayGraph::write_master_graphs_tmg() if (e->format & HGEdge::simple) { simplefile << e->vertex1->s_vertex_num[0] << ' ' << e->vertex2->s_vertex_num[0] << ' '; - e->segment->write_label(simplefile, 0); + simplefile << e->segment_name; simplefile << '\n'; } } @@ -490,7 +490,9 @@ void HighwayGraph::write_subgraphs_tmg { if (e->format & HGEdge::simple) { simplefile << e->vertex1->s_vertex_num[threadnum] << ' ' << e->vertex2->s_vertex_num[threadnum] << ' '; - e->segment->write_label(simplefile, g->systems); + if (g->systems) + e->segment->write_label(simplefile, g->systems); + else simplefile << e->segment_name; simplefile << '\n'; } if (e->format & HGEdge::collapsed) From 28be0f08fe4d7555ca7110d91755555b351752a3 Mon Sep 17 00:00:00 2001 From: eric bryant Date: Thu, 15 Jan 2026 08:30:14 -0500 Subject: [PATCH 2/4] store+retrieve formatted vertex coord strings cherrypick 73b6045 manually + 1f326fa and bits of ddc5a7c --- .../classes/GraphGeneration/HGEdge.cpp | 12 +++----- .../classes/GraphGeneration/HGEdge.h | 4 +-- .../classes/GraphGeneration/HGVertex.cpp | 11 ++++++++ .../classes/GraphGeneration/HGVertex.h | 2 ++ .../classes/GraphGeneration/HighwayGraph.cpp | 28 ++++++++----------- .../cplusplus/tasks/graph_generation.cpp | 8 ++++++ siteupdate/cplusplus/threads/VtxFmtThread.cpp | 4 +++ siteupdate/cplusplus/threads/threads.cpp | 2 ++ siteupdate/cplusplus/threads/threads.h | 2 ++ 9 files changed, 47 insertions(+), 26 deletions(-) create mode 100644 siteupdate/cplusplus/threads/VtxFmtThread.cpp diff --git a/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp b/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp index e3f0929..7693f09 100644 --- a/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp +++ b/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp @@ -98,25 +98,21 @@ void HGEdge::detach() } // write line to tmg collapsed edge file -void HGEdge::collapsed_tmg_line(std::ofstream& file, char* fstr, unsigned int threadnum, std::vector *systems) +void HGEdge::collapsed_tmg_line(std::ofstream& file, unsigned int threadnum, std::vector *systems) { file << vertex1->c_vertex_num[threadnum] << ' ' << vertex2->c_vertex_num[threadnum] << ' '; segment->write_label(file, systems); for (HGVertex *intermediate : intermediate_points) - { *fmt::format_to(fstr, " {:.15} {:.15}", intermediate->lat, intermediate->lng) = 0; - file << fstr; - } + file << intermediate->coordstr; file << '\n'; } // write line to tmg traveled edge file -void HGEdge::traveled_tmg_line(std::ofstream& file, char* fstr, unsigned int threadnum, std::vector *systems, bool trav, char* code) +void HGEdge::traveled_tmg_line(std::ofstream& file, unsigned int threadnum, std::vector *systems, bool trav, char* code) { file << vertex1->t_vertex_num[threadnum] << ' ' << vertex2->t_vertex_num[threadnum] << ' '; segment->write_label(file, systems); file << ' ' << (trav ? segment->clinchedby_code(code, threadnum) : "0"); for (HGVertex *intermediate : intermediate_points) - { *fmt::format_to(fstr, " {:.15} {:.15}", intermediate->lat, intermediate->lng) = 0; - file << fstr; - } + file << intermediate->coordstr; file << '\n'; } diff --git a/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.h b/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.h index eae10da..6468697 100644 --- a/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.h +++ b/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.h @@ -31,8 +31,8 @@ class HGEdge HGEdge(HGVertex *, unsigned char, HGEdge*, HGEdge*); void detach(); - void collapsed_tmg_line(std::ofstream&, char*, unsigned int, std::vector*); - void traveled_tmg_line (std::ofstream&, char*, unsigned int, std::vector*, bool, char*); + void collapsed_tmg_line(std::ofstream&, unsigned int, std::vector*); + void traveled_tmg_line (std::ofstream&, unsigned int, std::vector*, bool, char*); std::string debug_tmg_line(std::vector *, unsigned int); std::string str(); std::string intermediate_point_string(); diff --git a/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.cpp b/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.cpp index 8019014..9a841f6 100644 --- a/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.cpp +++ b/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.cpp @@ -1,3 +1,4 @@ +#define FMT_HEADER_ONLY #include "HGVertex.h" #include "../Args/Args.h" #include "../Datacheck/Datacheck.h" @@ -6,6 +7,7 @@ #include "../Region/Region.h" #include "../Route/Route.h" #include "../Waypoint/Waypoint.h" +#include std::atomic_uint HGVertex::num_hidden(0); @@ -66,3 +68,12 @@ HGEdge* HGVertex::back(unsigned char format) // Nonetheless, let's stop the compiler from complaining. throw this; } + +void HGVertex::format_coordstr() +{ // sanity checks to avoid buffer overflows via >3 digits to L of decimal point + while (lat > 90) lat -= 360; + while (lat < -90) lat += 360; + while (lng >= 540) lng -= 360; + while (lng <= -540) lng += 360; + *fmt::format_to(coordstr, " {:.15} {:.15}", lat, lng) = 0; +} diff --git a/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.h b/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.h index 61d61d5..1102c3c 100644 --- a/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.h +++ b/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.h @@ -19,6 +19,7 @@ class HGVertex int *t_vertex_num; uint16_t edge_count; char visibility; + char coordstr[45]; // only need 43, but alignment requires extra anyway static std::atomic_uint num_hidden; @@ -27,4 +28,5 @@ class HGVertex HGEdge* front(unsigned char); HGEdge* back (unsigned char); + void format_coordstr(); }; diff --git a/siteupdate/cplusplus/classes/GraphGeneration/HighwayGraph.cpp b/siteupdate/cplusplus/classes/GraphGeneration/HighwayGraph.cpp index 3d9d6b7..32045af 100644 --- a/siteupdate/cplusplus/classes/GraphGeneration/HighwayGraph.cpp +++ b/siteupdate/cplusplus/classes/GraphGeneration/HighwayGraph.cpp @@ -374,13 +374,11 @@ void HighwayGraph::write_master_graphs_tmg() unsigned int sv = 0; unsigned int cv = 0; unsigned int tv = 0; - char fstr[57]; for (HGVertex& v : vertices) - { *fmt::format_to(fstr, " {:.15} {:.15}", v.lat, v.lng) = 0; - switch (v.visibility) // fall-thru is a Good Thing! - { case 2: collapfile << *(v.unique_name) << fstr << '\n'; v.c_vertex_num[0] = cv++; - case 1: travelfile << *(v.unique_name) << fstr << '\n'; v.t_vertex_num[0] = tv++; - default: simplefile << *(v.unique_name) << fstr << '\n'; v.s_vertex_num[0] = sv++; + { switch (v.visibility) // fall-thru is a Good Thing! + { case 2: collapfile << *(v.unique_name) << v.coordstr << '\n'; v.c_vertex_num[0] = cv++; + case 1: travelfile << *(v.unique_name) << v.coordstr << '\n'; v.t_vertex_num[0] = tv++; + default: simplefile << *(v.unique_name) << v.coordstr << '\n'; v.s_vertex_num[0] = sv++; } } @@ -394,10 +392,10 @@ void HighwayGraph::write_master_graphs_tmg() //TODO: multiple functions performing the same instructions for multiple files? for (HGEdge *e = edges.begin(), *end = edges.end(); e != end; ++e) { if (e->format & HGEdge::collapsed) - e->collapsed_tmg_line(collapfile, fstr, 0, 0); + e->collapsed_tmg_line(collapfile, 0, 0); if (e->format & HGEdge::traveled) { for (char*n=cbycode; ntraveled_tmg_line(travelfile, fstr, 0, 0, TravelerList::allusers.size, cbycode); + e->traveled_tmg_line(travelfile, 0, 0, TravelerList::allusers.size, cbycode); } if (e->format & HGEdge::simple) { simplefile << e->vertex1->s_vertex_num[0] << ' ' @@ -469,13 +467,11 @@ void HighwayGraph::write_subgraphs_tmg unsigned int sv = 0; unsigned int cv = 0; unsigned int tv = 0; - char fstr[57]; for (HGVertex *v : mv) - { *fmt::format_to(fstr, " {:.15} {:.15}", v->lat, v->lng) = 0; - switch(v->visibility) // fall-thru is a Good Thing! - { case 2: collapfile << *(v->unique_name) << fstr << '\n'; v->c_vertex_num[threadnum] = cv++; - case 1: travelfile << *(v->unique_name) << fstr << '\n'; v->t_vertex_num[threadnum] = tv++; - default: simplefile << *(v->unique_name) << fstr << '\n'; v->s_vertex_num[threadnum] = sv++; + { switch(v->visibility) // fall-thru is a Good Thing! + { case 2: collapfile << *(v->unique_name) << v->coordstr << '\n'; v->c_vertex_num[threadnum] = cv++; + case 1: travelfile << *(v->unique_name) << v->coordstr << '\n'; v->t_vertex_num[threadnum] = tv++; + default: simplefile << *(v->unique_name) << v->coordstr << '\n'; v->s_vertex_num[threadnum] = sv++; } } @@ -494,10 +490,10 @@ void HighwayGraph::write_subgraphs_tmg simplefile << '\n'; } if (e->format & HGEdge::collapsed) - e->collapsed_tmg_line(collapfile, fstr, threadnum, g->systems); + e->collapsed_tmg_line(collapfile, threadnum, g->systems); if (e->format & HGEdge::traveled) { for (char*n=cbycode; ntraveled_tmg_line (travelfile, fstr, threadnum, g->systems, travnum, cbycode); + e->traveled_tmg_line (travelfile, threadnum, g->systems, travnum, cbycode); } } delete[] cbycode; diff --git a/siteupdate/cplusplus/tasks/graph_generation.cpp b/siteupdate/cplusplus/tasks/graph_generation.cpp index fcee32f..778c850 100644 --- a/siteupdate/cplusplus/tasks/graph_generation.cpp +++ b/siteupdate/cplusplus/tasks/graph_generation.cpp @@ -12,6 +12,14 @@ graph_data.waypoint_naming_log.clear(); { // Let's keep these braces here, for easily commenting out subgraph generation when developing waypoint simplification routines GraphListEntry::num = 3; + cout << et.et() << "Formatting vertex coordinate strings." << endl; + #ifdef threading_enabled + THREADLOOP thr[t] = thread(VtxFmtThread, t, &graph_data.vertices); + THREADLOOP thr[t].join(); + #else + for (HGVertex& v : graph_data.vertices) v.format_coordstr(); + #endif + cout << et.et() << "Writing master TM graph files." << endl; // print summary info std::cout << " Simple graph has " << graph_data.vertices.size() << " vertices, " << graph_data.se << " edges." << std::endl; diff --git a/siteupdate/cplusplus/threads/VtxFmtThread.cpp b/siteupdate/cplusplus/threads/VtxFmtThread.cpp new file mode 100644 index 0000000..ec4ada0 --- /dev/null +++ b/siteupdate/cplusplus/threads/VtxFmtThread.cpp @@ -0,0 +1,4 @@ +void VtxFmtThread(unsigned int id, std::vector* vertices) +{ for (auto v = vertices->begin()+id, end = vertices->end(); v < end; v += Args::numthreads) + v->format_coordstr(); +} diff --git a/siteupdate/cplusplus/threads/threads.cpp b/siteupdate/cplusplus/threads/threads.cpp index 302c982..ea0a3a3 100644 --- a/siteupdate/cplusplus/threads/threads.cpp +++ b/siteupdate/cplusplus/threads/threads.cpp @@ -1,5 +1,6 @@ #include "threads.h" #include "../classes/GraphGeneration/GraphListEntry.h" +#include "../classes/GraphGeneration/HGVertex.h" #include "../classes/GraphGeneration/HighwayGraph.h" #include "../classes/HighwaySegment/HighwaySegment.h" #include "../classes/HighwaySystem/HighwaySystem.h" @@ -22,3 +23,4 @@ #include "StatsCsvThread.cpp" #include "SubgraphThread.cpp" #include "UserLogThread.cpp" +#include "VtxFmtThread.cpp" diff --git a/siteupdate/cplusplus/threads/threads.h b/siteupdate/cplusplus/threads/threads.h index 367aac8..aa24ee9 100644 --- a/siteupdate/cplusplus/threads/threads.h +++ b/siteupdate/cplusplus/threads/threads.h @@ -1,5 +1,6 @@ class ElapsedTime; class ErrorList; +class HGVertex; class HighwayGraph; class WaypointQuadtree; #include @@ -16,3 +17,4 @@ void RteIntThread (unsigned int, std::mutex*, ErrorList*); void StatsCsvThread (unsigned int, std::mutex*); void SubgraphThread (unsigned int, std::mutex*, std::mutex*, HighwayGraph*, WaypointQuadtree*, ElapsedTime*); void UserLogThread (unsigned int, std::mutex*, const double, const double); +void VtxFmtThread (unsigned int, std::vector*); From e76ad220622aebbd75ae84cd701c829b21ab0bc0 Mon Sep 17 00:00:00 2001 From: eric bryant Date: Thu, 15 Jan 2026 09:27:22 -0500 Subject: [PATCH 3/4] vertex nums cache locality & fmt::print --- .../classes/GraphGeneration/HGEdge.cpp | 23 ------ .../classes/GraphGeneration/HGEdge.h | 2 - .../classes/GraphGeneration/HGVertex.cpp | 12 +--- .../classes/GraphGeneration/HGVertex.h | 5 +- .../classes/GraphGeneration/HighwayGraph.cpp | 72 +++++++++++++------ .../GraphGeneration/get_subgraph_data.cpp | 11 +-- .../cplusplus/tasks/graph_generation.cpp | 2 + .../cplusplus/threads/MasterTmgThread.cpp | 4 +- .../cplusplus/threads/SubgraphThread.cpp | 2 + siteupdate/cplusplus/threads/threads.cpp | 1 + 10 files changed, 67 insertions(+), 67 deletions(-) diff --git a/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp b/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp index e3f0929..e3a0d7d 100644 --- a/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp +++ b/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp @@ -97,29 +97,6 @@ void HGEdge::detach() detach(vertex2->incident_edges); } -// write line to tmg collapsed edge file -void HGEdge::collapsed_tmg_line(std::ofstream& file, char* fstr, unsigned int threadnum, std::vector *systems) -{ file << vertex1->c_vertex_num[threadnum] << ' ' << vertex2->c_vertex_num[threadnum] << ' '; - segment->write_label(file, systems); - for (HGVertex *intermediate : intermediate_points) - { *fmt::format_to(fstr, " {:.15} {:.15}", intermediate->lat, intermediate->lng) = 0; - file << fstr; - } - file << '\n'; -} - -// write line to tmg traveled edge file -void HGEdge::traveled_tmg_line(std::ofstream& file, char* fstr, unsigned int threadnum, std::vector *systems, bool trav, char* code) -{ file << vertex1->t_vertex_num[threadnum] << ' ' << vertex2->t_vertex_num[threadnum] << ' '; - segment->write_label(file, systems); - file << ' ' << (trav ? segment->clinchedby_code(code, threadnum) : "0"); - for (HGVertex *intermediate : intermediate_points) - { *fmt::format_to(fstr, " {:.15} {:.15}", intermediate->lat, intermediate->lng) = 0; - file << fstr; - } - file << '\n'; -} - /* line appropriate for a tmg collapsed edge file, with debug info std::string HGEdge::debug_tmg_line(std::vector *systems, unsigned int threadnum) { std::string line = std::to_string(vertex1->c_vertex_num[threadnum]) + " [" + *vertex1->unique_name + "] " \ diff --git a/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.h b/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.h index eae10da..c1667b2 100644 --- a/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.h +++ b/siteupdate/cplusplus/classes/GraphGeneration/HGEdge.h @@ -31,8 +31,6 @@ class HGEdge HGEdge(HGVertex *, unsigned char, HGEdge*, HGEdge*); void detach(); - void collapsed_tmg_line(std::ofstream&, char*, unsigned int, std::vector*); - void traveled_tmg_line (std::ofstream&, char*, unsigned int, std::vector*, bool, char*); std::string debug_tmg_line(std::vector *, unsigned int); std::string str(); std::string intermediate_point_string(); diff --git a/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.cpp b/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.cpp index 8019014..ad1335d 100644 --- a/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.cpp +++ b/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.cpp @@ -8,15 +8,12 @@ #include "../Waypoint/Waypoint.h" std::atomic_uint HGVertex::num_hidden(0); +thread_local int* HGVertex::vnums; void HGVertex::setup(Waypoint *wpt, const std::string *n) { lat = wpt->lat; lng = wpt->lng; wpt->vertex = this; - s_vertex_num = new int[Args::numthreads]; - c_vertex_num = new int[Args::numthreads]; - t_vertex_num = new int[Args::numthreads]; - // deleted by ~HGVertex unique_name = n; edge_count = 0; visibility = 0; @@ -38,13 +35,6 @@ void HGVertex::setup(Waypoint *wpt, const std::string *n) else num_hidden++; } -HGVertex::~HGVertex() -{ //std::cout << "deleting vertex at " << first_waypoint->str() << std::endl; - delete[] s_vertex_num; - delete[] c_vertex_num; - delete[] t_vertex_num; -} - HGEdge* HGVertex::front(unsigned char format) { for (HGEdge* e : incident_edges) if (e->format & format) diff --git a/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.h b/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.h index 61d61d5..a7fc618 100644 --- a/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.h +++ b/siteupdate/cplusplus/classes/GraphGeneration/HGVertex.h @@ -14,16 +14,13 @@ class HGVertex double lat, lng; const std::string *unique_name; std::vector incident_edges; - int *s_vertex_num; - int *c_vertex_num; - int *t_vertex_num; uint16_t edge_count; char visibility; static std::atomic_uint num_hidden; + static thread_local int* vnums; void setup(Waypoint*, const std::string*); - ~HGVertex(); HGEdge* front(unsigned char); HGEdge* back (unsigned char); diff --git a/siteupdate/cplusplus/classes/GraphGeneration/HighwayGraph.cpp b/siteupdate/cplusplus/classes/GraphGeneration/HighwayGraph.cpp index 3d9d6b7..0e48e8e 100644 --- a/siteupdate/cplusplus/classes/GraphGeneration/HighwayGraph.cpp +++ b/siteupdate/cplusplus/classes/GraphGeneration/HighwayGraph.cpp @@ -14,8 +14,7 @@ #include "../Waypoint/Waypoint.h" #include "../WaypointQuadtree/WaypointQuadtree.h" #include "../../templates/contains.cpp" -#include -#include +#include #include HighwayGraph::HighwayGraph(WaypointQuadtree &all_waypoints, ElapsedTime &et) @@ -374,13 +373,15 @@ void HighwayGraph::write_master_graphs_tmg() unsigned int sv = 0; unsigned int cv = 0; unsigned int tv = 0; + int* vnum = HGVertex::vnums; char fstr[57]; for (HGVertex& v : vertices) { *fmt::format_to(fstr, " {:.15} {:.15}", v.lat, v.lng) = 0; switch (v.visibility) // fall-thru is a Good Thing! - { case 2: collapfile << *(v.unique_name) << fstr << '\n'; v.c_vertex_num[0] = cv++; - case 1: travelfile << *(v.unique_name) << fstr << '\n'; v.t_vertex_num[0] = tv++; - default: simplefile << *(v.unique_name) << fstr << '\n'; v.s_vertex_num[0] = sv++; + { case 2: collapfile << *(v.unique_name) << fstr << '\n'; vnum[1] = cv++; + case 1: travelfile << *(v.unique_name) << fstr << '\n'; vnum[2] = tv++; + default: simplefile << *(v.unique_name) << fstr << '\n'; vnum[0] = sv++; + vnum += 3; } } @@ -393,15 +394,31 @@ void HighwayGraph::write_master_graphs_tmg() // write edges //TODO: multiple functions performing the same instructions for multiple files? for (HGEdge *e = edges.begin(), *end = edges.end(); e != end; ++e) - { if (e->format & HGEdge::collapsed) - e->collapsed_tmg_line(collapfile, fstr, 0, 0); + { int* v1num = HGVertex::vnums+(e->vertex1-vertices.data())*3; + int* v2num = HGVertex::vnums+(e->vertex2-vertices.data())*3; + + if (e->format & HGEdge::collapsed) + { fmt::print(collapfile, "{} {} ", v1num[1], v2num[1]); + e->segment->write_label(collapfile, 0); + for (HGVertex *intermediate : e->intermediate_points) + { *fmt::format_to(fstr, " {:.15} {:.15}", intermediate->lat, intermediate->lng) = 0; + collapfile << fstr; + } + collapfile << '\n'; + } if (e->format & HGEdge::traveled) { for (char*n=cbycode; ntraveled_tmg_line(travelfile, fstr, 0, 0, TravelerList::allusers.size, cbycode); + fmt::print(travelfile, "{} {} ", v1num[2], v2num[2]); + e->segment->write_label(travelfile, 0); + travelfile << ' ' << (TravelerList::allusers.size ? e->segment->clinchedby_code(cbycode, 0) : "0"); + for (HGVertex *intermediate : e->intermediate_points) + { *fmt::format_to(fstr, " {:.15} {:.15}", intermediate->lat, intermediate->lng) = 0; + travelfile << fstr; + } + travelfile << '\n'; } if (e->format & HGEdge::simple) - { simplefile << e->vertex1->s_vertex_num[0] << ' ' - << e->vertex2->s_vertex_num[0] << ' '; + { fmt::print(simplefile, "{} {} ", v1num[0], v2num[0]); e->segment->write_label(simplefile, 0); simplefile << '\n'; } @@ -466,16 +483,13 @@ void HighwayGraph::write_subgraphs_tmg travelfile << tv_count << ' ' << te_count << ' ' << travnum << '\n'; // write vertices - unsigned int sv = 0; - unsigned int cv = 0; - unsigned int tv = 0; char fstr[57]; for (HGVertex *v : mv) { *fmt::format_to(fstr, " {:.15} {:.15}", v->lat, v->lng) = 0; switch(v->visibility) // fall-thru is a Good Thing! - { case 2: collapfile << *(v->unique_name) << fstr << '\n'; v->c_vertex_num[threadnum] = cv++; - case 1: travelfile << *(v->unique_name) << fstr << '\n'; v->t_vertex_num[threadnum] = tv++; - default: simplefile << *(v->unique_name) << fstr << '\n'; v->s_vertex_num[threadnum] = sv++; + { case 2: collapfile << *(v->unique_name) << fstr << '\n'; + case 1: travelfile << *(v->unique_name) << fstr << '\n'; + default: simplefile << *(v->unique_name) << fstr << '\n'; } } @@ -487,17 +501,33 @@ void HighwayGraph::write_subgraphs_tmg // write edges for (HGEdge *e : me) //TODO: multiple functions performing the same instructions for multiple files? - { if (e->format & HGEdge::simple) - { simplefile << e->vertex1->s_vertex_num[threadnum] << ' ' - << e->vertex2->s_vertex_num[threadnum] << ' '; + { int* v1num = HGVertex::vnums+(e->vertex1-vertices.data())*3; + int* v2num = HGVertex::vnums+(e->vertex2-vertices.data())*3; + + if (e->format & HGEdge::simple) + { fmt::print(simplefile, "{} {} ", v1num[0], v2num[0]); e->segment->write_label(simplefile, g->systems); simplefile << '\n'; } if (e->format & HGEdge::collapsed) - e->collapsed_tmg_line(collapfile, fstr, threadnum, g->systems); + { fmt::print(collapfile, "{} {} ", v1num[1], v2num[1]); + e->segment->write_label(collapfile, g->systems); + for (HGVertex *intermediate : e->intermediate_points) + { *fmt::format_to(fstr, " {:.15} {:.15}", intermediate->lat, intermediate->lng) = 0; + collapfile << fstr; + } + collapfile << '\n'; + } if (e->format & HGEdge::traveled) { for (char*n=cbycode; ntraveled_tmg_line (travelfile, fstr, threadnum, g->systems, travnum, cbycode); + fmt::print(travelfile, "{} {} ", v1num[2], v2num[2]); + e->segment->write_label(travelfile, g->systems); + travelfile << ' ' << (travnum ? e->segment->clinchedby_code(cbycode, threadnum) : "0"); + for (HGVertex *intermediate : e->intermediate_points) + { *fmt::format_to(fstr, " {:.15} {:.15}", intermediate->lat, intermediate->lng) = 0; + travelfile << fstr; + } + travelfile << '\n'; } } delete[] cbycode; diff --git a/siteupdate/cplusplus/classes/GraphGeneration/get_subgraph_data.cpp b/siteupdate/cplusplus/classes/GraphGeneration/get_subgraph_data.cpp index 6e153f2..285d9fa 100644 --- a/siteupdate/cplusplus/classes/GraphGeneration/get_subgraph_data.cpp +++ b/siteupdate/cplusplus/classes/GraphGeneration/get_subgraph_data.cpp @@ -49,12 +49,13 @@ else { // We know there's a PlaceRadius, as no GraphListEntry me.shrink_to_fit(); } -// count vertices +// count vertices & initialize vertex numbers for (HGVertex* v : mv) -{ switch (v->visibility) // fall-thru is a Good Thing! - { case 2: cv_count++; - case 1: tv_count++; - default: sv_count++; +{ int* vnum = HGVertex::vnums+(v-vertices.data())*3; + switch (v->visibility) // fall-thru is a Good Thing! + { case 2: vnum[1] = cv_count++; + case 1: vnum[2] = tv_count++; + default: vnum[0] = sv_count++; } } diff --git a/siteupdate/cplusplus/tasks/graph_generation.cpp b/siteupdate/cplusplus/tasks/graph_generation.cpp index fcee32f..3f02228 100644 --- a/siteupdate/cplusplus/tasks/graph_generation.cpp +++ b/siteupdate/cplusplus/tasks/graph_generation.cpp @@ -26,10 +26,12 @@ graph_data.waypoint_naming_log.clear(); thr[t] = thread(SubgraphThread, t, &list_mtx, &term_mtx, &graph_data, &all_waypoints, &et); THREADLOOP thr[t].join(); #else + HGVertex::vnums = new int[graph_data.vertices.size()*3]; for ( graph_data.write_master_graphs_tmg(); GraphListEntry::num < GraphListEntry::entries.size(); GraphListEntry::num += 3 ) graph_data.write_subgraphs_tmg(GraphListEntry::num, 0, &all_waypoints, &et, &term_mtx); + delete[] HGVertex::vnums; #endif cout << '!' << endl; } //*/ diff --git a/siteupdate/cplusplus/threads/MasterTmgThread.cpp b/siteupdate/cplusplus/threads/MasterTmgThread.cpp index 23b1f89..ececcc8 100644 --- a/siteupdate/cplusplus/threads/MasterTmgThread.cpp +++ b/siteupdate/cplusplus/threads/MasterTmgThread.cpp @@ -1,4 +1,6 @@ void MasterTmgThread(HighwayGraph* graph_data, std::mutex* l, std::mutex* t, WaypointQuadtree *qt, ElapsedTime *et) -{ graph_data->write_master_graphs_tmg(); +{ HGVertex::vnums = new int[graph_data->vertices.size()*3]; + graph_data->write_master_graphs_tmg(); + delete[] HGVertex::vnums; SubgraphThread(0, l, t, graph_data, qt, et); } diff --git a/siteupdate/cplusplus/threads/SubgraphThread.cpp b/siteupdate/cplusplus/threads/SubgraphThread.cpp index 84bf5e4..26f7690 100644 --- a/siteupdate/cplusplus/threads/SubgraphThread.cpp +++ b/siteupdate/cplusplus/threads/SubgraphThread.cpp @@ -3,6 +3,7 @@ void SubgraphThread HighwayGraph* graph_data, WaypointQuadtree* qt, ElapsedTime* et ) { //std::cout << "Starting SubgraphThread " << id << std::endl; + HGVertex::vnums = new int[graph_data->vertices.size()*3]; while (GraphListEntry::num < GraphListEntry::entries.size()) { l->lock(); if (GraphListEntry::num >= GraphListEntry::entries.size()) @@ -16,4 +17,5 @@ void SubgraphThread l->unlock(); graph_data->write_subgraphs_tmg(i, id, qt, et, t); } + delete[] HGVertex::vnums; } diff --git a/siteupdate/cplusplus/threads/threads.cpp b/siteupdate/cplusplus/threads/threads.cpp index 302c982..b4b899f 100644 --- a/siteupdate/cplusplus/threads/threads.cpp +++ b/siteupdate/cplusplus/threads/threads.cpp @@ -1,5 +1,6 @@ #include "threads.h" #include "../classes/GraphGeneration/GraphListEntry.h" +#include "../classes/GraphGeneration/HGVertex.h" #include "../classes/GraphGeneration/HighwayGraph.h" #include "../classes/HighwaySegment/HighwaySegment.h" #include "../classes/HighwaySystem/HighwaySystem.h" From 3e6c39c5a88bac389eebc504df2ba1d212f7d384 Mon Sep 17 00:00:00 2001 From: eric bryant Date: Sun, 1 Feb 2026 19:47:31 -0500 Subject: [PATCH 4/4] remove extraneous condition --- .../cplusplus/classes/HighwaySegment/HighwaySegment.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/siteupdate/cplusplus/classes/HighwaySegment/HighwaySegment.cpp b/siteupdate/cplusplus/classes/HighwaySegment/HighwaySegment.cpp index 8e9e9f9..deb4f39 100644 --- a/siteupdate/cplusplus/classes/HighwaySegment/HighwaySegment.cpp +++ b/siteupdate/cplusplus/classes/HighwaySegment/HighwaySegment.cpp @@ -97,12 +97,13 @@ const char* HighwaySegment::clinchedby_code(char* code, unsigned int threadnum) return code; } -// compute an edge label, optionally restricted by systems +// write an edge label, restricted by systems void HighwaySegment::write_label(std::ofstream& file, std::vector *systems) { if (concurrent) { bool write_comma = 0; for (HighwaySegment* cs : *concurrent) - if ( !cs->route->system->devel() && (!systems || contains(*systems, cs->route->system)) ) + // This function is only called when systems is nonzero. Safe to dereference. + if ( !cs->route->system->devel() && contains(*systems, cs->route->system) ) { if (write_comma) file << ','; else write_comma = 1; file << cs->route->route;