diff --git a/siteupdate/cplusplus/Makefile b/siteupdate/cplusplus/Makefile index e123ac1..f93cf29 100644 --- a/siteupdate/cplusplus/Makefile +++ b/siteupdate/cplusplus/Makefile @@ -43,6 +43,7 @@ CommonObjects = \ classes/Waypoint/Waypoint.o \ classes/Waypoint/canonical_waypoint_name/canonical_waypoint_name.o \ functions/crawl_rte_data.o \ + functions/failure_cleanup.o \ functions/rdstats.o \ functions/route_and_label_logs.o \ functions/tmstring.o diff --git a/siteupdate/cplusplus/functions/failure_cleanup.cpp b/siteupdate/cplusplus/functions/failure_cleanup.cpp new file mode 100644 index 0000000..afd9eea --- /dev/null +++ b/siteupdate/cplusplus/functions/failure_cleanup.cpp @@ -0,0 +1,20 @@ +#include "../classes/Args/Args.h" +#include "../classes/GraphGeneration/GraphListEntry.h" +#include "../classes/GraphGeneration/PlaceRadius.h" +#include "../classes/WaypointQuadtree/WaypointQuadtree.h" +#include + +void failure_cleanup +( WaypointQuadtree& all_waypoints, std::vector& colocate_counts, + std::list& updates, std::list& systemupdates +) +{ Args::colocationlimit = 0; // silence colocation reports + all_waypoints.final_report(colocate_counts); // destroy quadtree nodes & colocation lists + for (auto g = GraphListEntry::entries.begin(); g < GraphListEntry::entries.end(); g += 3) + { delete g->regions; // destroy + delete g->systems; // GraphListEntry + delete g->placeradius; // data + } + for (std::string* u : updates) delete[] u; // destroy updates + for (std::string* u : systemupdates) delete[] u; // & systemupdates +} diff --git a/siteupdate/cplusplus/siteupdate.cpp b/siteupdate/cplusplus/siteupdate.cpp index 2ef83fe..10dbe45 100644 --- a/siteupdate/cplusplus/siteupdate.cpp +++ b/siteupdate/cplusplus/siteupdate.cpp @@ -1,12 +1,12 @@ // Tab Width = 8 -// Travel Mapping Project, Jim Teresco and Eric Bryant, 2015-2024 +// Travel Mapping Project, Jim Teresco and Eric Bryant, 2015-2026 /* Code to read .csv and .wpt files and prepare for adding to the Travel Mapping Project database. -(c) 2015-2024, Jim Teresco and Eric Bryant +(c) 2015-2026, Jim Teresco and Eric Bryant Original Python version by Jim Teresco, with contributions from Eric Bryant and the TravelMapping team -C++ translation by Eric Bryant +C++ version by Eric Bryant and Jim Teresco This module defines classes to represent the contents of a .csv file that lists the highways within a system, and a @@ -39,9 +39,10 @@ This module defines classes to represent the contents of a #include #include "threads/threads.h" #endif -void allbyregionactiveonly(std::mutex*, double); -void allbyregionactivepreview(std::mutex*, double); using namespace std; +void allbyregionactiveonly(mutex*, double); +void allbyregionactivepreview(mutex*, double); +void failure_cleanup(WaypointQuadtree&, vector&, list&, list&); int main(int argc, char *argv[]) { ifstream file; @@ -50,6 +51,7 @@ int main(int argc, char *argv[]) ErrorList el; double active_only_miles = 0; double active_preview_miles = 0; + vector colocate_counts(2,0); // argument parsing if (Args::init(argc, argv)) return 1; @@ -198,6 +200,7 @@ int main(int argc, char *argv[]) { cout << et.et() << "ABORTING due to " << el.error_list.size() << " errors:" << endl; for (unsigned int i = 0; i < el.error_list.size(); i++) cout << i+1 << ": " << el.error_list[i] << endl; + failure_cleanup(all_waypoints, colocate_counts, updates, systemupdates); return 1; } @@ -228,64 +231,7 @@ int main(int argc, char *argv[]) } // print some statistics - cout << et.et() << "Processed " << HighwaySystem::syslist.size << " highway systems." << endl; - unsigned int routes = 0; - unsigned int points = 0; - unsigned int segments = 0; - for (HighwaySystem& h : HighwaySystem::syslist) - { routes += h.routes.size; - for (Route& r : h.routes) - { points += r.points.size; - segments += r.segments.size; - } - } - cout << "Processed " << routes << " routes with a total of " << points << " points and " << segments << " segments." << endl; - if (points != all_waypoints.size()) - cout << "MISMATCH: all_waypoints contains " << all_waypoints.size() << " waypoints!" << endl; - cout << et.et() << "WaypointQuadtree contains " << all_waypoints.total_nodes() << " total nodes." << endl; - - vector colocate_counts(2,0); - if (!Args::errorcheck) - { // compute colocation of waypoints stats - cout << et.et() << "Computing waypoint colocation stats"; - if (Args::colocationlimit) - { cout << ", reporting all with " << Args::colocationlimit << " or more colocations:" << endl; - } - else - { cout << "." << endl; - } - all_waypoints.final_report(colocate_counts); - cout << "Waypoint colocation counts:" << endl; - unsigned int unique_locations = 0; - for (unsigned int c = 1; c < colocate_counts.size(); c++) - { unique_locations += colocate_counts[c]; - printf("%6i are each occupied by %2i waypoints.\n", colocate_counts[c], c); - } - cout << "Unique locations: " << unique_locations << endl; - } else all_waypoints.final_report(colocate_counts); - - /* EDB - cout << endl; - unsigned int a_count = 0; - unsigned int p_count = 0; - unsigned int d_count = 0; - unsigned other_count = 0; - unsigned int total_rtes = 0; - for (HighwaySystem& h : HighwaySystem::syslist) - for (Route* r : h.route_list) - { total_rtes++; - if (h.devel()) d_count++; - else { if (h.active()) a_count++; - else if (h.preview()) p_count++; - else other_count++; - } - } - cout << a_count+p_count << " clinchable routes:" << endl; - cout << a_count << " in active systems, and" << endl; - cout << p_count << " in preview systems." << endl; - cout << d_count << " routes in devel systems." << endl; - if (other_count) cout << other_count << " routes not designated active/preview/devel!" << endl; - cout << total_rtes << " total routes." << endl;//*/ + #include "tasks/final_stats.cpp" if (Args::errorcheck) cout << "\n!!! DATA CHECK SUCCESSFUL !!!\n" << endl; diff --git a/siteupdate/cplusplus/tasks/final_stats.cpp b/siteupdate/cplusplus/tasks/final_stats.cpp new file mode 100644 index 0000000..1b1451c --- /dev/null +++ b/siteupdate/cplusplus/tasks/final_stats.cpp @@ -0,0 +1,31 @@ +cout << et.et() << "Processed " << HighwaySystem::syslist.size << " highway systems." << endl; +unsigned int routes = 0; +unsigned int points = 0; +unsigned int segments = 0; +for (HighwaySystem& h : HighwaySystem::syslist) +{ routes += h.routes.size; + for (Route& r : h.routes) + { points += r.points.size; + segments += r.segments.size; + } +} +cout << "Processed " << routes << " routes with a total of " << points << " points and " << segments << " segments." << endl; +if (points != all_waypoints.size()) + cout << "MISMATCH: all_waypoints contains " << all_waypoints.size() << " waypoints!" << endl; +cout << et.et() << "WaypointQuadtree contains " << all_waypoints.total_nodes() << " total nodes." << endl; + +if (!Args::errorcheck) +{ // compute colocation of waypoints stats + cout << et.et() << "Computing waypoint colocation stats"; + if (Args::colocationlimit) + cout << ", reporting all with " << Args::colocationlimit << " or more colocations:" << endl; + else cout << "." << endl; + all_waypoints.final_report(colocate_counts); + cout << "Waypoint colocation counts:" << endl; + unsigned int unique_locations = 0; + for (unsigned int c = 1; c < colocate_counts.size(); c++) + { unique_locations += colocate_counts[c]; + printf("%6i are each occupied by %2i waypoints.\n", colocate_counts[c], c); + } + cout << "Unique locations: " << unique_locations << endl; +} else all_waypoints.final_report(colocate_counts); diff --git a/siteupdate/cplusplus/tasks/read_updates.cpp b/siteupdate/cplusplus/tasks/read_updates.cpp index afca081..d607cca 100644 --- a/siteupdate/cplusplus/tasks/read_updates.cpp +++ b/siteupdate/cplusplus/tasks/read_updates.cpp @@ -13,6 +13,7 @@ while (getline(file, line)) size_t NumFields = 5; string* fields = new string[5]; // deleted as DB table is written + // or when aborting due to ErrorList errors string* ptr_array[5] = {&fields[0], &fields[1], &fields[2], &fields[3], &fields[4]}; split(line, ptr_array, NumFields, ';'); if (NumFields != 5) @@ -75,6 +76,7 @@ while (getline(file, line)) size_t NumFields = 5; string* fields = new string[5]; // deleted as DB table is written + // or when aborting due to ErrorList errors string* ptr_array[5] = {&fields[0], &fields[1], &fields[2], &fields[3], &fields[4]}; split(line, ptr_array, NumFields, ';'); if (NumFields != 5) diff --git a/siteupdate/cplusplus/tasks/subgraphs/area.cpp b/siteupdate/cplusplus/tasks/subgraphs/area.cpp index dee75c8..ebf6259 100644 --- a/siteupdate/cplusplus/tasks/subgraphs/area.cpp +++ b/siteupdate/cplusplus/tasks/subgraphs/area.cpp @@ -33,6 +33,7 @@ while (getline(file, line)) if (*endptr || r <= 0) {el.add_error("invalid radius in areagraphs.csv line: " + line); r=1;} PlaceRadius *a = new PlaceRadius(fields[0], fields[1], lat, lng, r); // deleted @ end of HighwayGraph::write_subgraphs_tmg + // or when aborting due to ErrorList errors GraphListEntry::add_group( string(fields[1]) + fields[4] + "-area", string(fields[0]) + " (" + fields[4] + " mi radius)", diff --git a/siteupdate/cplusplus/tasks/subgraphs/continent.cpp b/siteupdate/cplusplus/tasks/subgraphs/continent.cpp index 1558f43..6e134fd 100644 --- a/siteupdate/cplusplus/tasks/subgraphs/continent.cpp +++ b/siteupdate/cplusplus/tasks/subgraphs/continent.cpp @@ -2,6 +2,7 @@ for (auto c = Region::continents.data(), dummy = c+Region::continents.size()-1; c < dummy; c++) { regions = new vector; // deleted @ end of HighwayGraph::write_subgraphs_tmg + // or when aborting due to ErrorList errors for (Region& r : Region::allregions) // does it match this continent and have routes? if (c == r.continent && r.active_preview_mileage) diff --git a/siteupdate/cplusplus/tasks/subgraphs/country.cpp b/siteupdate/cplusplus/tasks/subgraphs/country.cpp index 4a628e5..2b0faaa 100644 --- a/siteupdate/cplusplus/tasks/subgraphs/country.cpp +++ b/siteupdate/cplusplus/tasks/subgraphs/country.cpp @@ -2,6 +2,7 @@ for (auto c = Region::countries.data(), dummy = c+Region::countries.size()-1; c < dummy; c++) { regions = new vector; // deleted @ end of HighwayGraph::write_subgraphs_tmg + // or when aborting due to ErrorList errors for (Region& r : Region::allregions) // does it match this country and have routes? if (c == r.country && r.active_preview_mileage) diff --git a/siteupdate/cplusplus/tasks/subgraphs/fullcustom.cpp b/siteupdate/cplusplus/tasks/subgraphs/fullcustom.cpp index c0c2e61..a451280 100644 --- a/siteupdate/cplusplus/tasks/subgraphs/fullcustom.cpp +++ b/siteupdate/cplusplus/tasks/subgraphs/fullcustom.cpp @@ -35,7 +35,7 @@ if (file.is_open()) double r = strtod(radius.data(), &endptr); if (*endptr || r <= 0) {el.add_error("invalid radius in fullcustom.csv line: " + line); ok = 0;} a = new PlaceRadius(descr.data(), root.data(), lat, lng, r); - } // deleted @ end of HighwayGraph::write_subgraphs_tmg + } // deleted @ end of HighwayGraph::write_subgraphs_tmg or when aborting due to ErrorList errors else if (blanks != 3) { el.add_error("lat/lng/radius error in fullcustom.csv line: [" + line + "], either all or none must be populated"); @@ -51,6 +51,7 @@ if (file.is_open()) if (regionlist.empty()) regions = 0; else { regions = new vector; // deleted @ end of HighwayGraph::write_subgraphs_tmg + // or when aborting due to ErrorList errors char* field = new char[regionlist.size()+1]; // deleted once region tokens are processed strcpy(field, regionlist.data()); @@ -68,6 +69,7 @@ if (file.is_open()) if (systemlist.empty()) systems = 0; else { systems = new vector; // deleted @ end of HighwayGraph::write_subgraphs_tmg + // or when aborting due to ErrorList errors char* field = new char[systemlist.size()+1]; // deleted once system tokens are processed strcpy(field, systemlist.data()); diff --git a/siteupdate/cplusplus/tasks/subgraphs/multiregion.cpp b/siteupdate/cplusplus/tasks/subgraphs/multiregion.cpp index 4d879f3..7daef35 100644 --- a/siteupdate/cplusplus/tasks/subgraphs/multiregion.cpp +++ b/siteupdate/cplusplus/tasks/subgraphs/multiregion.cpp @@ -23,6 +23,7 @@ while (getline(file, line)) + " bytes in multiregion.csv line: " + line); regions = new vector; // deleted @ end of HighwayGraph::write_subgraphs_tmg + // or when aborting due to ErrorList errors for(char* rg = strtok(fields[2], ","); rg; rg = strtok(0, ",")) try { regions->push_back(Region::code_hash.at(rg)); } diff --git a/siteupdate/cplusplus/tasks/subgraphs/multisystem.cpp b/siteupdate/cplusplus/tasks/subgraphs/multisystem.cpp index 563547f..39be1a8 100644 --- a/siteupdate/cplusplus/tasks/subgraphs/multisystem.cpp +++ b/siteupdate/cplusplus/tasks/subgraphs/multisystem.cpp @@ -23,6 +23,7 @@ while (getline(file, line)) + " bytes in multisystem.csv line: " + line); systems = new vector; // deleted @ end of HighwayGraph::write_subgraphs_tmg + // or when aborting due to ErrorList errors for(char* s = strtok(fields[2], ","); s; s = strtok(0, ",")) try { HighwaySystem* const h = HighwaySystem::sysname_hash.at(s); if (h->active_or_preview()) diff --git a/siteupdate/cplusplus/tasks/subgraphs/region.cpp b/siteupdate/cplusplus/tasks/subgraphs/region.cpp index 4be8971..0e6367c 100644 --- a/siteupdate/cplusplus/tasks/subgraphs/region.cpp +++ b/siteupdate/cplusplus/tasks/subgraphs/region.cpp @@ -6,5 +6,5 @@ for (Region& region : Region::allregions) region.name + " (" + region.type + ")", 'r', new vector(1, ®ion), nullptr, nullptr); // deleted @ end of HighwayGraph::write_subgraphs_tmg -} +} // or when aborting due to ErrorList errors graph_types.push_back({"region", "Routes Within a Single Region", "These graphs contain all routes currently plotted within the given region."}); diff --git a/siteupdate/cplusplus/tasks/subgraphs/system.cpp b/siteupdate/cplusplus/tasks/subgraphs/system.cpp index 164f753..c6d29ce 100644 --- a/siteupdate/cplusplus/tasks/subgraphs/system.cpp +++ b/siteupdate/cplusplus/tasks/subgraphs/system.cpp @@ -10,6 +10,7 @@ while (getline(file, line)) h->systemname + " (" + h->fullname + ")", 's', nullptr, new vector(1, h), nullptr); // deleted @ end of HighwayGraph::write_subgraphs_tmg + // or when aborting due to ErrorList errors h->is_subgraph_system = 1; } else el.add_error("devel system "+h->systemname+" in systemgraphs.csv"); } diff --git a/siteupdate/cplusplus/tasks/threaded/ReadList.cpp b/siteupdate/cplusplus/tasks/threaded/ReadList.cpp index 1eca76d..432624c 100644 --- a/siteupdate/cplusplus/tasks/threaded/ReadList.cpp +++ b/siteupdate/cplusplus/tasks/threaded/ReadList.cpp @@ -8,7 +8,8 @@ // placement new #endif if (TravelerList::file_not_found) - { cout << "\nCheck for typos in your -U or --userlist arguments, and make sure " << Args::userlistext << " files for all specified users exist.\nAborting." << endl; + { cout << "\nCheck for typos in your -U or --userlist arguments, and make sure " << Args::userlistext << " files for all specified users exist.\nAborting." << endl; + failure_cleanup(all_waypoints, colocate_counts, updates, systemupdates); return 1; } TravelerList::ids.clear();