diff --git a/siteupdate/cplusplus/classes/HighwaySystem/HighwaySystem.cpp b/siteupdate/cplusplus/classes/HighwaySystem/HighwaySystem.cpp index 0ee45329..716849e1 100644 --- a/siteupdate/cplusplus/classes/HighwaySystem/HighwaySystem.cpp +++ b/siteupdate/cplusplus/classes/HighwaySystem/HighwaySystem.cpp @@ -12,6 +12,8 @@ std::list HighwaySystem::syslist; std::list::iterator HighwaySystem::it; +unsigned int HighwaySystem::num_active = 0; +unsigned int HighwaySystem::num_preview = 0; HighwaySystem::HighwaySystem(std::string &line, ErrorList &el, std::vector> &countries) { std::ifstream file; @@ -54,7 +56,10 @@ HighwaySystem::HighwaySystem(std::string &line, ErrorList &el, std::vector syslist; static std::list::iterator it; + static unsigned int num_active; + static unsigned int num_preview; HighwaySystem(std::string &, ErrorList &, std::vector> &); diff --git a/siteupdate/cplusplus/classes/Region/Region.cpp b/siteupdate/cplusplus/classes/Region/Region.cpp index a0153e32..56689f14 100644 --- a/siteupdate/cplusplus/classes/Region/Region.cpp +++ b/siteupdate/cplusplus/classes/Region/Region.cpp @@ -9,7 +9,7 @@ std::pair *country_or_continent_by_code(std::string co return 0; } -std::vector Region::allregions; +std::list Region::allregions; std::unordered_map Region::code_hash; Region::Region (const std::string &line, @@ -26,12 +26,8 @@ Region::Region (const std::string &line, split(line, fields, NumFields, ';'); if (NumFields != 5) { el.add_error("Could not parse regions.csv line: [" + line + "], expected 5 fields, found " + std::to_string(NumFields)); - continent = country_or_continent_by_code("error", continents); - country = country_or_continent_by_code("error", countries); - is_valid = 0; - return; + throw 1; } - is_valid = 1; // code if (code.size() > DBFieldLength::regionCode) el.add_error("Region code > " + std::to_string(DBFieldLength::regionCode) diff --git a/siteupdate/cplusplus/classes/Region/Region.h b/siteupdate/cplusplus/classes/Region/Region.h index 4738ff00..a083c923 100644 --- a/siteupdate/cplusplus/classes/Region/Region.h +++ b/siteupdate/cplusplus/classes/Region/Region.h @@ -1,6 +1,7 @@ class ErrorList; class HGVertex; class Waypoint; +#include #include #include #include @@ -46,9 +47,8 @@ class Region double overall_mileage; std::mutex mtx; std::vector> vertices; - bool is_valid; - static std::vector allregions; + static std::list allregions; static std::unordered_map code_hash; Region (const std::string&, diff --git a/siteupdate/cplusplus/classes/TravelerList/userlog.cpp b/siteupdate/cplusplus/classes/TravelerList/userlog.cpp index 2afbf4b9..894dd1ec 100644 --- a/siteupdate/cplusplus/classes/TravelerList/userlog.cpp +++ b/siteupdate/cplusplus/classes/TravelerList/userlog.cpp @@ -29,17 +29,9 @@ void TravelerList::userlog(const double total_active_only_miles, const double to << format_clinched_mi(active_preview_mileage_by_region.at(region), region->active_preview_mileage) << '\n'; } - unsigned int active_systems = 0; - unsigned int preview_systems = 0; - - // present stats by system here, also generate entries for - // DB table clinchedSystemMileageByRegion as we compute and - // have the data handy for (HighwaySystem *h : HighwaySystem::syslist) if (h->active_or_preview()) - { if (h->active()) active_systems++; - else preview_systems++; - double t_system_overall = 0; + { double t_system_overall = 0; if (system_region_mileages.count(h)) t_system_overall = system_region_miles(h); if (t_system_overall) @@ -110,13 +102,13 @@ void TravelerList::userlog(const double total_active_only_miles, const double to // grand summary, active only sprintf(fstr,"\nTraveled %i of %i (%.1f%%), Clinched %i of %i (%.1f%%) active systems", - active_systems_traveled, active_systems, 100*(double)active_systems_traveled/active_systems, - active_systems_clinched, active_systems, 100*(double)active_systems_clinched/active_systems); + active_systems_traveled, HighwaySystem::num_active, 100*(double)active_systems_traveled/HighwaySystem::num_active, + active_systems_clinched, HighwaySystem::num_active, 100*(double)active_systems_clinched/HighwaySystem::num_active); log << fstr << '\n'; // grand summary, active+preview sprintf(fstr,"Traveled %i of %i (%.1f%%), Clinched %i of %i (%.1f%%) preview systems", - preview_systems_traveled, preview_systems, 100*(double)preview_systems_traveled/preview_systems, - preview_systems_clinched, preview_systems, 100*(double)preview_systems_clinched/preview_systems); + preview_systems_traveled, HighwaySystem::num_preview, 100*(double)preview_systems_traveled/HighwaySystem::num_preview, + preview_systems_clinched, HighwaySystem::num_preview, 100*(double)preview_systems_clinched/HighwaySystem::num_preview); log << fstr << '\n'; // updated routes, sorted by date diff --git a/siteupdate/cplusplus/functions/allbyregionactiveonly.cpp b/siteupdate/cplusplus/functions/allbyregionactiveonly.cpp index 573d1da3..81cebcb2 100644 --- a/siteupdate/cplusplus/functions/allbyregionactiveonly.cpp +++ b/siteupdate/cplusplus/functions/allbyregionactiveonly.cpp @@ -4,18 +4,14 @@ #include "../threads/threads.h" #include -void allbyregionactiveonly(std::mutex* mtx) -{ double total_mi; - char fstr[112]; +void allbyregionactiveonly(std::mutex* mtx, double total_mi) +{ char fstr[112]; std::ofstream allfile(Args::csvstatfilepath + "/allbyregionactiveonly.csv"); allfile << "Traveler,Total"; std::list regions; - total_mi = 0; - for (Region* r : Region::allregions) - if (r->active_only_mileage) - { regions.push_back(r); - total_mi += r->active_only_mileage; - } + for (Region& r : Region::allregions) + if (r.active_only_mileage) + regions.push_back(&r); regions.sort(sort_regions_by_code); for (Region *region : regions) allfile << ',' << region->code; diff --git a/siteupdate/cplusplus/functions/allbyregionactivepreview.cpp b/siteupdate/cplusplus/functions/allbyregionactivepreview.cpp index 22fbba39..5590eba9 100644 --- a/siteupdate/cplusplus/functions/allbyregionactivepreview.cpp +++ b/siteupdate/cplusplus/functions/allbyregionactivepreview.cpp @@ -4,18 +4,14 @@ #include "../threads/threads.h" #include -void allbyregionactivepreview(std::mutex* mtx) -{ double total_mi; - char fstr[112]; +void allbyregionactivepreview(std::mutex* mtx, double total_mi) +{ char fstr[112]; std::ofstream allfile(Args::csvstatfilepath + "/allbyregionactivepreview.csv"); allfile << "Traveler,Total"; std::list regions; - total_mi = 0; - for (Region* r : Region::allregions) - if (r->active_preview_mileage) - { regions.push_back(r); - total_mi += r->active_preview_mileage; - } + for (Region& r : Region::allregions) + if (r.active_preview_mileage) + regions.push_back(&r); regions.sort(sort_regions_by_code); for (Region *region : regions) allfile << ',' << region->code; diff --git a/siteupdate/cplusplus/functions/sql_file.cpp b/siteupdate/cplusplus/functions/sql_file.cpp index f5424a8c..fcaf7cbd 100644 --- a/siteupdate/cplusplus/functions/sql_file.cpp +++ b/siteupdate/cplusplus/functions/sql_file.cpp @@ -86,12 +86,12 @@ void sqlfile1 sqlfile << "PRIMARY KEY(code), FOREIGN KEY (country) REFERENCES countries(code), FOREIGN KEY (continent) REFERENCES continents(code));\n"; sqlfile << "INSERT INTO regions VALUES\n"; first = 1; - for (size_t r = 0; r < Region::allregions.size()-1; r++) + for (auto r = Region::allregions.begin(); &*r != &*Region::allregions.rbegin(); r++) { if (!first) sqlfile << ','; first = 0; - sqlfile << "('" << Region::allregions[r]->code << "','" << double_quotes(Region::allregions[r]->name) - << "','" << Region::allregions[r]->country_code() << "','" << Region::allregions[r]->continent_code() - << "','" << Region::allregions[r]->type << "')\n"; + sqlfile << "('" << r->code << "','" << double_quotes(r->name) + << "','" << r->country_code() << "','" << r->continent_code() + << "','" << r->type << "')\n"; } sqlfile << ";\n"; @@ -271,12 +271,12 @@ void sqlfile1 << "), activeMileage DOUBLE, activePreviewMileage DOUBLE);\n"; sqlfile << "INSERT INTO overallMileageByRegion VALUES\n"; first = 1; - for (Region* region : Region::allregions) - { if (region->active_only_mileage+region->active_preview_mileage == 0) continue; + for (Region& region : Region::allregions) + { if (region.active_only_mileage+region.active_preview_mileage == 0) continue; if (!first) sqlfile << ','; first = 0; - sprintf(fstr, "','%.17g','%.17g')\n", region->active_only_mileage, region->active_preview_mileage); - sqlfile << "('" << region->code << fstr; + sprintf(fstr, "','%.17g','%.17g')\n", region.active_only_mileage, region.active_preview_mileage); + sqlfile << "('" << region.code << fstr; } sqlfile << ";\n"; diff --git a/siteupdate/cplusplus/siteupdate.cpp b/siteupdate/cplusplus/siteupdate.cpp index 7170d41e..9de711d5 100644 --- a/siteupdate/cplusplus/siteupdate.cpp +++ b/siteupdate/cplusplus/siteupdate.cpp @@ -41,8 +41,8 @@ This module defines classes to represent the contents of a #include #include "threads/threads.h" #endif -void allbyregionactiveonly(std::mutex*); -void allbyregionactivepreview(std::mutex*); +void allbyregionactiveonly(std::mutex*, double); +void allbyregionactivepreview(std::mutex*, double); using namespace std; int main(int argc, char *argv[]) @@ -161,18 +161,15 @@ int main(int argc, char *argv[]) while(getline(file, line)) { if (line.back() == 0x0D) line.erase(line.end()-1); // trim DOS newlines if (line.empty()) continue; - Region* r = new Region(line, countries, continents, el); - // deleted on termination of program - if (r->is_valid) - { Region::allregions.push_back(r); - Region::code_hash[r->code] = r; - } else delete r; + try { Region::allregions.emplace_back(line, countries, continents, el); + Region::code_hash[Region::allregions.back().code] = &Region::allregions.back(); + } catch (int&err) {} } } file.close(); // create a dummy region to catch unrecognized region codes in .csv files - Region::allregions.push_back(new Region("error;unrecognized region code;error;error;unrecognized region code", countries, continents, el)); - Region::code_hash[Region::allregions.back()->code] = Region::allregions.back(); + Region::allregions.emplace_back("error;unrecognized region code;error;error;unrecognized region code", countries, continents, el); + Region::code_hash[Region::allregions.back().code] = &Region::allregions.back(); // Create a list of HighwaySystem objects, one per system in systems.csv file cout << et.et() << "Reading systems list in " << Args::highwaydatapath << "/" << Args::systemsfile << "." << endl; @@ -503,10 +500,10 @@ int main(int argc, char *argv[]) double active_only_miles = 0; double active_preview_miles = 0; double overall_miles = 0; - for (Region* r : Region::allregions) - { active_only_miles += r->active_only_mileage; - active_preview_miles += r->active_preview_mileage; - overall_miles += r->overall_mileage; + for (Region& r : Region::allregions) + { active_only_miles += r.active_only_mileage; + active_preview_miles += r.active_preview_mileage; + overall_miles += r.overall_mileage; } sprintf(fstr, "Active routes (active): %.2f mi\n", active_only_miles); hdstatsfile << fstr; @@ -519,11 +516,11 @@ int main(int argc, char *argv[]) // a nice enhancement later here might break down by continent, then country, // then region list region_entries; - for (Region* region : Region::allregions) - if (region->overall_mileage) + for (Region& region : Region::allregions) + if (region.overall_mileage) { sprintf(fstr, ": %.2f (active), %.2f (active, preview) %.2f (active, preview, devel)\n", - region->active_only_mileage, region->active_preview_mileage, region->overall_mileage); - region_entries.push_back(region->code + fstr); + region.active_only_mileage, region.active_preview_mileage, region.overall_mileage); + region_entries.push_back(region.code + fstr); } region_entries.sort(); for (string& e : region_entries) hdstatsfile << e; @@ -579,22 +576,22 @@ int main(int argc, char *argv[]) { case 1: #endif cout << et.et() << "Writing allbyregionactiveonly.csv." << endl; - allbyregionactiveonly(0); + allbyregionactiveonly(0, active_only_miles); cout << et.et() << "Writing allbyregionactivepreview.csv." << endl; - allbyregionactivepreview(0); + allbyregionactivepreview(0, active_preview_miles); cout << et.et() << "Writing per-system stats csv files." << endl; for (HighwaySystem* h : HighwaySystem::syslist) h->stats_csv(); #ifdef threading_enabled break; case 2: - thr[0] = thread(allbyregionactiveonly, &list_mtx); - thr[1] = thread(allbyregionactivepreview, &list_mtx); + thr[0] = thread(allbyregionactiveonly, &list_mtx, active_only_miles); + thr[1] = thread(allbyregionactivepreview, &list_mtx, active_preview_miles); thr[0].join(); thr[1].join(); break; default: - thr[0] = thread(allbyregionactiveonly, (std::mutex*)0); - thr[1] = thread(allbyregionactivepreview, (std::mutex*)0); + thr[0] = thread(allbyregionactiveonly, nullptr, active_only_miles); + thr[1] = thread(allbyregionactivepreview, nullptr, active_preview_miles); thr[2] = thread(StatsCsvThread, 2, &list_mtx); thr[0].join(); thr[1].join(); diff --git a/siteupdate/cplusplus/tasks/subgraphs/continent.cpp b/siteupdate/cplusplus/tasks/subgraphs/continent.cpp index e7ee1614..511085d7 100644 --- a/siteupdate/cplusplus/tasks/subgraphs/continent.cpp +++ b/siteupdate/cplusplus/tasks/subgraphs/continent.cpp @@ -6,10 +6,10 @@ cout << et.et() << "Creating continent graphs." << endl; for (size_t c = 0; c < continents.size()-1; c++) { regions = new list; // deleted @ end of HighwayGraph::write_subgraphs_tmg - for (Region* r : Region::allregions) + for (Region& r : Region::allregions) // does it match this continent and have routes? - if (&continents[c] == r->continent && r->active_preview_mileage) - regions->push_back(r); + if (&continents[c] == r.continent && r.active_preview_mileage) + regions->push_back(&r); // generate for any continent with at least 1 region with mileage if (regions->size() < 1) delete regions; else { GraphListEntry::add_group( diff --git a/siteupdate/cplusplus/tasks/subgraphs/country.cpp b/siteupdate/cplusplus/tasks/subgraphs/country.cpp index 448e05db..81416543 100644 --- a/siteupdate/cplusplus/tasks/subgraphs/country.cpp +++ b/siteupdate/cplusplus/tasks/subgraphs/country.cpp @@ -7,10 +7,10 @@ cout << et.et() << "Creating country graphs." << endl; for (size_t c = 0; c < countries.size()-1; c++) { regions = new list; // deleted @ end of HighwayGraph::write_subgraphs_tmg - for (Region* r : Region::allregions) + for (Region& r : Region::allregions) // does it match this country and have routes? - if (&countries[c] == r->country && r->active_preview_mileage) - regions->push_back(r); + if (&countries[c] == r.country && r.active_preview_mileage) + regions->push_back(&r); // does it have at least two? if none, no data, // if 1 we already generated a graph for that one region if (regions->size() < 2) delete regions; diff --git a/siteupdate/cplusplus/tasks/subgraphs/multiregion.cpp b/siteupdate/cplusplus/tasks/subgraphs/multiregion.cpp index 9ef40b70..99ff414a 100644 --- a/siteupdate/cplusplus/tasks/subgraphs/multiregion.cpp +++ b/siteupdate/cplusplus/tasks/subgraphs/multiregion.cpp @@ -28,9 +28,9 @@ while (getline(file, line)) regions = new list; // deleted @ end of HighwayGraph::write_subgraphs_tmg for(char* rg = strtok(fields[2], ","); rg; rg = strtok(0, ",")) - for (Region* r : Region::allregions) - if (rg == r->code) - { regions->push_back(r); + for (Region& r : Region::allregions) + if (rg == r.code) + { regions->push_back(&r); break; } GraphListEntry::add_group(fields[1], fields[0], 'R', regions, nullptr, nullptr); diff --git a/siteupdate/cplusplus/tasks/subgraphs/region.cpp b/siteupdate/cplusplus/tasks/subgraphs/region.cpp index 8b05d01b..4400e88f 100644 --- a/siteupdate/cplusplus/tasks/subgraphs/region.cpp +++ b/siteupdate/cplusplus/tasks/subgraphs/region.cpp @@ -6,13 +6,13 @@ cout << et.et() << "Creating regional data graphs." << endl; // any active or preview systems // add entries to graph vector -for (Region* region : Region::allregions) -{ if (region->active_preview_mileage == 0) continue; - regions = new list(1, region); +for (Region& region : Region::allregions) +{ if (region.active_preview_mileage == 0) continue; + regions = new list(1, ®ion); // deleted @ end of HighwayGraph::write_subgraphs_tmg GraphListEntry::add_group( - region->code + "-region", - region->name + " (" + region->type + ")", + region.code + "-region", + region.name + " (" + region.type + ")", 'r', regions, nullptr, nullptr); } #ifndef threading_enabled diff --git a/siteupdate/cplusplus/threads/ReadListThread.cpp b/siteupdate/cplusplus/threads/ReadListThread.cpp index d5a07daf..2e8e42e7 100644 --- a/siteupdate/cplusplus/threads/ReadListThread.cpp +++ b/siteupdate/cplusplus/threads/ReadListThread.cpp @@ -12,7 +12,6 @@ void ReadListThread(unsigned int id, std::mutex* tl_mtx, ErrorList* el) //printf("ReadListThread %02i (*it)++\n", id); fflush(stdout); std::cout << tl << ' ' << std::flush; tl_mtx->unlock(); - std::string** update; TravelerList *t = new TravelerList(tl, el); // deleted on termination of program TravelerList::mtx.lock(); diff --git a/siteupdate/python-teresco/siteupdate.py b/siteupdate/python-teresco/siteupdate.py index bd5b6547..774b8e80 100755 --- a/siteupdate/python-teresco/siteupdate.py +++ b/siteupdate/python-teresco/siteupdate.py @@ -1307,6 +1307,9 @@ class HighwaySystem: a designation within the same system crosses region boundaries, a connected route defines the entirety of the route. """ + num_active = 0 + num_preview = 0 + def __init__(self,systemname,country,fullname,color,tier,level,el, path="../../../HighwayData/hwy_data/_systems"): self.route_list = [] @@ -2812,6 +2815,10 @@ def __init__(self,filename,descr,vertices,edges,travelers,format,category): # verify Level if fields[5] != "active" and fields[5] != "preview" and fields[5] != "devel": el.add_error("Unrecognized level in " + args.systemsfile + " line: " + line) + elif fields[5] == "preview": + HighwaySystem.num_preview += 1 + elif fields[5] == "active": + HighwaySystem.num_active += 1 print(fields[0] + ".",end="",flush=True) hs = HighwaySystem(fields[0], fields[1], fields[2], @@ -3540,18 +3547,9 @@ def run(self): t.active_systems_clinched = 0 t.preview_systems_traveled = 0 t.preview_systems_clinched = 0 - active_systems = 0 - preview_systems = 0 - # present stats by system here, also generate entries for - # DB table clinchedSystemMileageByRegion as we compute and - # have the data handy for h in highway_systems: if h.active_or_preview(): - if h.active(): - active_systems += 1 - else: - preview_systems += 1 t_system_overall = 0.0 if h.systemname in t.system_region_mileages: t_system_overall = math.fsum(t.system_region_mileages[h.systemname].values()) @@ -3620,16 +3618,16 @@ def run(self): # grand summary, active only - t.log_entries.append("\nTraveled " + str(t.active_systems_traveled) + " of " + str(active_systems) + - " ({0:.1f}%)".format(100*t.active_systems_traveled/active_systems) + - ", Clinched " + str(t.active_systems_clinched) + " of " + str(active_systems) + - " ({0:.1f}%)".format(100*t.active_systems_clinched/active_systems) + + t.log_entries.append("\nTraveled " + str(t.active_systems_traveled) + " of " + str(HighwaySystem.num_active) + + " ({0:.1f}%)".format(100*t.active_systems_traveled/HighwaySystem.num_active) + + ", Clinched " + str(t.active_systems_clinched) + " of " + str(HighwaySystem.num_active) + + " ({0:.1f}%)".format(100*t.active_systems_clinched/HighwaySystem.num_active) + " active systems") # grand summary, active+preview - t.log_entries.append("Traveled " + str(t.preview_systems_traveled) + " of " + str(preview_systems) + - " ({0:.1f}%)".format(100*t.preview_systems_traveled/preview_systems) + - ", Clinched " + str(t.preview_systems_clinched) + " of " + str(preview_systems) + - " ({0:.1f}%)".format(100*t.preview_systems_clinched/preview_systems) + + t.log_entries.append("Traveled " + str(t.preview_systems_traveled) + " of " + str(HighwaySystem.num_preview) + + " ({0:.1f}%)".format(100*t.preview_systems_traveled/HighwaySystem.num_preview) + + ", Clinched " + str(t.preview_systems_clinched) + " of " + str(HighwaySystem.num_preview) + + " ({0:.1f}%)".format(100*t.preview_systems_clinched/HighwaySystem.num_preview) + " preview systems") # updated routes, sorted by date t.log_entries.append("\nMost recent updates for listed routes:") @@ -3668,7 +3666,7 @@ def run(self): else: allfile.write(',0') allfile.write('\n') -allfile.write('TOTAL,{0:.2f}'.format(math.fsum(active_only_mileage_by_region.values()))) +allfile.write('TOTAL,{0:.2f}'.format(active_only_miles)) for region in regions: allfile.write(',{0:.2f}'.format(active_only_mileage_by_region[region])) allfile.write('\n') @@ -3689,7 +3687,7 @@ def run(self): else: allfile.write(',0') allfile.write('\n') -allfile.write('TOTAL,{0:.2f}'.format(math.fsum(active_preview_mileage_by_region.values()))) +allfile.write('TOTAL,{0:.2f}'.format(active_preview_miles)) for region in regions: allfile.write(',{0:.2f}'.format(active_preview_mileage_by_region[region])) allfile.write('\n')