Skip to content

Commit 52ef723

Browse files
authored
Merge pull request #622 from yakra/gtmb_rebase_5
TMBitsets for subgraph membership, etc
2 parents fd96ac6 + 3282921 commit 52ef723

34 files changed

+809
-450
lines changed

siteupdate/cplusplus/classes/Args/Args.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
/* k */ bool Args::skipgraphs = 0;
88
/* v */ bool Args::mtvertices = 0;
99
/* C */ bool Args::mtcsvfiles = 0;
10+
/* E */ bool Args::edgecounts = 0;
11+
/* b */ bool Args::bitsetlogs = 0;
1012
/* w */ std::string Args::datapath = "../../HighwayData";
1113
/* s */ std::string Args::systemsfile = "systems.csv";
1214
/* u */ std::string Args::userlistfilepath = "../../UserData/list_files";
@@ -33,6 +35,8 @@ bool Args::init(int argc, char *argv[])
3335
else if ARG(0, "-k", "--skipgraphs") skipgraphs = 1;
3436
else if ARG(0, "-v", "--mt-vertices") mtvertices = 1;
3537
else if ARG(0, "-C", "--mt-csvs") mtcsvfiles = 1;
38+
else if ARG(0, "-E", "--edge-counts") edgecounts = 1;
39+
else if ARG(0, "-b", "--bitset-logs") bitsetlogs = 1;
3640
else if ARG(0, "-h", "--help") {show_help(); return 1;}
3741
else if ARG(1, "-w", "--datapath") {datapath = argv[++n];}
3842
else if ARG(1, "-s", "--systemsfile") {systemsfile = argv[++n];}
@@ -81,7 +85,7 @@ void Args::show_help()
8185
std::cout << indent << " [-c CSVSTATFILEPATH] [-g GRAPHFILEPATH] [-k]\n";
8286
std::cout << indent << " [-n NMPMERGEPATH] [-p SPLITREGIONPATH SPLITREGION]\n";
8387
std::cout << indent << " [-U USERLIST [USERLIST ...]] [-t NUMTHREADS] [-e]\n";
84-
std::cout << indent << " [-T TIMEPRECISION] [-v] [-C]\n";
88+
std::cout << indent << " [-T TIMEPRECISION] [-v] [-C] [-E] [-b]\n";
8589
std::cout << indent << " [-L COLOCATIONLIMIT] [-N NMPTHRESHOLD]\n";
8690
std::cout << "\n";
8791
std::cout << "Create SQL, stats, graphs, and log files from highway and user data for the\n";
@@ -124,6 +128,9 @@ void Args::show_help()
124128
std::cout << " timestamp readouts\n";
125129
std::cout << " -v, --mt-vertices Multi-threaded vertex construction\n";
126130
std::cout << " -C, --mt-csvs Multi-threaded stats csv files\n";
131+
std::cout << " -E, --edge-counts Report the quantity of each format graph edge\n";
132+
std::cout << " -b, --bitset-logs Write TMBitset RAM use logs for region & system\n";
133+
std::cout << " vertices & edges\n";
127134
std::cout << " -L, --colocationlimit COLOCATIONLIMIT\n";
128135
std::cout << " Threshold to report colocation counts\n";
129136
std::cout << " -N, --nmp-threshold NMPTHRESHOLD\n";

siteupdate/cplusplus/classes/Args/Args.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class Args
1919
/* T */ static int timeprecision;
2020
/* v */ static bool mtvertices;
2121
/* C */ static bool mtcsvfiles;
22+
/* E */ static bool edgecounts;
23+
/* b */ static bool bitsetlogs;
2224
/* L */ static int colocationlimit;
2325
/* N */ static double nmpthreshold;
2426
static const char* exec;

siteupdate/cplusplus/classes/GraphGeneration/GraphListEntry.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
std::vector<GraphListEntry> GraphListEntry::entries;
77
size_t GraphListEntry::num; // iterator for entries
88

9-
GraphListEntry::GraphListEntry(std::string r, std::string d, char f, char c, std::list<Region*> *rg, std::list<HighwaySystem*> *sys, PlaceRadius *pr):
9+
GraphListEntry::GraphListEntry(std::string r, std::string d, char f, char c, std::vector<Region*> *rg, std::vector<HighwaySystem*> *sys, PlaceRadius *pr):
1010
regions(rg), systems(sys), placeradius(pr),
1111
root(r), descr(d), form(f), cat(c) {}
1212

13-
void GraphListEntry::add_group(std::string&& r, std::string&& d, char c, std::list<Region*> *rg, std::list<HighwaySystem*> *sys, PlaceRadius *pr)
13+
void GraphListEntry::add_group(std::string&& r, std::string&& d, char c, std::vector<Region*> *rg, std::vector<HighwaySystem*> *sys, PlaceRadius *pr)
1414
{ GraphListEntry::entries.emplace_back(r, d, 's', c, rg, sys, pr);
1515
GraphListEntry::entries.emplace_back(r, d, 'c', c, rg, sys, pr);
1616
GraphListEntry::entries.emplace_back(r, d, 't', c, rg, sys, pr);

siteupdate/cplusplus/classes/GraphGeneration/GraphListEntry.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
class HighwaySystem;
22
class PlaceRadius;
33
class Region;
4-
#include <list>
54
#include <string>
65
#include <vector>
76

@@ -12,8 +11,8 @@ class GraphListEntry
1211
match column names in the "graphs" DB table. */
1312
public:
1413
// Info for use in threaded subgraph generation. Not used in DB.
15-
std::list<Region*> *regions;
16-
std::list<HighwaySystem*> *systems;
14+
std::vector<Region*> *regions;
15+
std::vector<HighwaySystem*> *systems;
1716
PlaceRadius *placeradius;
1817

1918
// Info for the "graphs" DB table
@@ -29,6 +28,6 @@ class GraphListEntry
2928
static size_t num; // iterator for entries
3029
std::string tag();
3130

32-
GraphListEntry(std::string, std::string, char, char, std::list<Region*>*, std::list<HighwaySystem*>*, PlaceRadius*);
33-
static void add_group(std::string&&, std::string&&, char, std::list<Region*>*, std::list<HighwaySystem*>*, PlaceRadius*);
31+
GraphListEntry(std::string, std::string, char, char, std::vector<Region*>*, std::vector<HighwaySystem*>*, PlaceRadius*);
32+
static void add_group(std::string&&, std::string&&, char, std::vector<Region*>*, std::vector<HighwaySystem*>*, PlaceRadius*);
3433
};

siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp

Lines changed: 26 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -7,51 +7,31 @@
77
#include "../Waypoint/Waypoint.h"
88
#include "../../templates/contains.cpp"
99

10+
HGVertex* HGEdge::v_array;
11+
1012
HGEdge::HGEdge(HighwaySegment *s)
1113
{ // initial construction is based on a HighwaySegment
12-
written = new char[Args::numthreads];
13-
// deleted by HGEdge::detach
14-
// we only need to initialize the first element, for master graphs.
15-
// the rest will get zeroed out for each subgraph set.
16-
written[0] = 0;
1714
vertex1 = s->waypoint1->hashpoint()->vertex;
1815
vertex2 = s->waypoint2->hashpoint()->vertex;
1916
format = simple | collapsed | traveled;
2017
segment_name = s->segment_name();
21-
vertex1->incident_s_edges.push_back(this);
22-
vertex2->incident_s_edges.push_back(this);
23-
vertex1->incident_c_edges.push_back(this);
24-
vertex2->incident_c_edges.push_back(this);
25-
vertex1->incident_t_edges.push_back(this);
26-
vertex2->incident_t_edges.push_back(this);
18+
vertex1->incident_edges.push_back(this);
19+
vertex2->incident_edges.push_back(this);
20+
vertex1->edge_count++;
21+
vertex2->edge_count++;
2722
// canonical segment, used to reference region and list of travelers
2823
// assumption: each edge/segment lives within a unique region
2924
// and a 'multi-edge' would not be able to span regions as there
3025
// would be a required visible waypoint at the border
3126
segment = s;
3227
}
3328

34-
HGEdge::HGEdge(HGVertex *vertex, unsigned char fmt_mask)
29+
HGEdge::HGEdge(HGVertex *vertex, unsigned char fmt_mask, HGEdge *e1, HGEdge *e2)
3530
{ // build by collapsing two existing edges around a common hidden vertex
36-
written = new char[Args::numthreads];
37-
// deleted by HGEdge::detach
38-
written[0] = 0;
31+
c_idx = vertex - v_array;
3932
format = fmt_mask;
40-
// we know there are exactly 2 incident edges, as we
41-
// checked for that, and we will replace these two
42-
// with the single edge we are constructing here...
43-
HGEdge *edge1 = 0;
44-
HGEdge *edge2 = 0;
45-
if (fmt_mask & collapsed)
46-
{ // ...in the compressed graph, and/or...
47-
edge1 = vertex->incident_c_edges.front();
48-
edge2 = vertex->incident_c_edges.back();
49-
}
50-
if (fmt_mask & traveled)
51-
{ // ...in the traveled graph, as appropriate
52-
edge1 = vertex->incident_t_edges.front();
53-
edge2 = vertex->incident_t_edges.back();
54-
}
33+
HGEdge *edge1 = e1;
34+
HGEdge *edge2 = e2;
5535
// segment names should match as routes should not start or end
5636
// nor should concurrencies begin or end at a hidden point
5737
if (edge1->segment_name != edge2->segment_name)
@@ -103,50 +83,31 @@ HGEdge::HGEdge(HGVertex *vertex, unsigned char fmt_mask)
10383
intermediate_point_string() << " to " << *(vertex2->unique_name) << std::endl;
10484
//std::cout << "DEBUG: new " << str() << std::endl;
10585

86+
// clear format bits of old edges
87+
edge1->format &= ~fmt_mask;
88+
edge2->format &= ~fmt_mask;
10689
// replace edge references at our endpoints with ourself
107-
edge1->detach(fmt_mask);
108-
edge2->detach(fmt_mask);
109-
if (fmt_mask & collapsed)
110-
{ vertex1->incident_c_edges.push_back(this);
111-
vertex2->incident_c_edges.push_back(this);
112-
}
113-
if (fmt_mask & traveled)
114-
{ vertex1->incident_t_edges.push_back(this);
115-
vertex2->incident_t_edges.push_back(this);
116-
}
90+
if (!edge1->format) edge1->detach();
91+
if (!edge2->format) edge2->detach();
92+
vertex1->incident_edges.push_back(this);
93+
vertex2->incident_edges.push_back(this);
11794
}
11895

119-
void HGEdge::detach() {return detach(format);}
120-
void HGEdge::detach(unsigned char fmt_mask)
96+
void HGEdge::detach()
12197
{ // detach edge from vertices in graph(s) specified in fmt_mask
122-
#define DETACH(v) \
123-
for (std::list<HGEdge*>::iterator e = v.begin(); e != v.end(); e++) \
98+
auto detach = [&](std::vector<HGEdge*>& v) \
99+
{ for (std::vector<HGEdge*>::iterator e = v.begin(); e != v.end(); e++) \
124100
if (*e == this) \
125101
{ v.erase(e); \
126102
break; \
127103
}
128-
if (fmt_mask & simple)
129-
{ DETACH(vertex1->incident_s_edges)
130-
DETACH(vertex2->incident_s_edges)
131-
}
132-
if (fmt_mask & collapsed)
133-
{ DETACH(vertex1->incident_c_edges)
134-
DETACH(vertex2->incident_c_edges)
135-
}
136-
if (fmt_mask & traveled)
137-
{ DETACH(vertex1->incident_t_edges)
138-
DETACH(vertex2->incident_t_edges)
139-
}
140-
#undef DETACH
141-
format &= ~fmt_mask;
142-
if (!format)
143-
{ delete[] written;
144-
delete this;
145-
}
104+
};
105+
detach(vertex1->incident_edges);
106+
detach(vertex2->incident_edges);
146107
}
147108

148109
// write line to tmg collapsed edge file
149-
void HGEdge::collapsed_tmg_line(std::ofstream& file, char* fstr, unsigned int threadnum, std::list<HighwaySystem*> *systems)
110+
void HGEdge::collapsed_tmg_line(std::ofstream& file, char* fstr, unsigned int threadnum, std::vector<HighwaySystem*> *systems)
150111
{ file << vertex1->c_vertex_num[threadnum] << ' ' << vertex2->c_vertex_num[threadnum] << ' ';
151112
segment->write_label(file, systems);
152113
for (HGVertex *intermediate : intermediate_points)
@@ -157,7 +118,7 @@ void HGEdge::collapsed_tmg_line(std::ofstream& file, char* fstr, unsigned int th
157118
}
158119

159120
// write line to tmg traveled edge file
160-
void HGEdge::traveled_tmg_line(std::ofstream& file, char* fstr, unsigned int threadnum, std::list<HighwaySystem*> *systems, bool trav, char* code)
121+
void HGEdge::traveled_tmg_line(std::ofstream& file, char* fstr, unsigned int threadnum, std::vector<HighwaySystem*> *systems, bool trav, char* code)
161122
{ file << vertex1->t_vertex_num[threadnum] << ' ' << vertex2->t_vertex_num[threadnum] << ' ';
162123
segment->write_label(file, systems);
163124
file << ' ' << (trav ? segment->clinchedby_code(code, threadnum) : "0");
@@ -169,7 +130,7 @@ void HGEdge::traveled_tmg_line(std::ofstream& file, char* fstr, unsigned int thr
169130
}
170131

171132
/* line appropriate for a tmg collapsed edge file, with debug info
172-
std::string HGEdge::debug_tmg_line(std::list<HighwaySystem*> *systems, unsigned int threadnum)
133+
std::string HGEdge::debug_tmg_line(std::vector<HighwaySystem*> *systems, unsigned int threadnum)
173134
{ std::string line = std::to_string(vertex1->c_vertex_num[threadnum]) + " [" + *vertex1->unique_name + "] " \
174135
+ std::to_string(vertex2->c_vertex_num[threadnum]) + " [" + *vertex2->unique_name + "] " + label(systems);
175136
char fstr[58];

siteupdate/cplusplus/classes/GraphGeneration/HGEdge.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,37 @@ class HighwaySegment;
33
class HighwaySystem;
44
#include <iostream>
55
#include <list>
6+
#include <vector>
67

78
class HGEdge
89
{ /* This class encapsulates information needed for a highway graph
910
edge that can incorporate intermediate points.
1011
*/
1112
public:
12-
char *written;
1313
std::string segment_name;
1414
HGVertex *vertex1, *vertex2;
1515
std::list<HGVertex*> intermediate_points; // if more than 1, will go from vertex1 to vertex2
1616
HighwaySegment *segment;
17+
uint32_t c_idx; // index of last vertex collapsed, if applicable
18+
// no "real" use, only for diagnostics & logging
1719
unsigned char format;
1820

1921
// constants for more human-readable format masks
2022
static constexpr unsigned char simple = 1;
2123
static constexpr unsigned char collapsed = 2;
2224
static constexpr unsigned char traveled = 4;
2325

26+
// this avoids adding more arguments to the collapse ctor
27+
// and adding more ugly code to the collapse routine in the graph ctor
28+
static HGVertex* v_array; // for calculating c_idx
29+
2430
HGEdge(HighwaySegment *);
25-
HGEdge(HGVertex *, unsigned char);
31+
HGEdge(HGVertex *, unsigned char, HGEdge*, HGEdge*);
2632

2733
void detach();
28-
void detach(unsigned char);
29-
void collapsed_tmg_line(std::ofstream&, char*, unsigned int, std::list<HighwaySystem*>*);
30-
void traveled_tmg_line (std::ofstream&, char*, unsigned int, std::list<HighwaySystem*>*, bool, char*);
31-
std::string debug_tmg_line(std::list<HighwaySystem*> *, unsigned int);
34+
void collapsed_tmg_line(std::ofstream&, char*, unsigned int, std::vector<HighwaySystem*>*);
35+
void traveled_tmg_line (std::ofstream&, char*, unsigned int, std::vector<HighwaySystem*>*, bool, char*);
36+
std::string debug_tmg_line(std::vector<HighwaySystem*> *, unsigned int);
3237
std::string str();
3338
std::string intermediate_point_string();
3439
};

siteupdate/cplusplus/classes/GraphGeneration/HGVertex.cpp

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,62 @@
77
#include "../Route/Route.h"
88
#include "../Waypoint/Waypoint.h"
99

10+
std::atomic_uint HGVertex::num_hidden(0);
11+
1012
void HGVertex::setup(Waypoint *wpt, const std::string *n)
1113
{ lat = wpt->lat;
1214
lng = wpt->lng;
1315
wpt->vertex = this;
1416
s_vertex_num = new int[Args::numthreads];
1517
c_vertex_num = new int[Args::numthreads];
1618
t_vertex_num = new int[Args::numthreads];
17-
// deleted by ~HGVertex, called by HighwayGraph::clear
19+
// deleted by ~HGVertex
1820
unique_name = n;
21+
edge_count = 0;
1922
visibility = 0;
2023
// permitted values:
2124
// 0: never visible outside of simple graphs
2225
// 1: visible only in traveled graph; hidden in collapsed graph
2326
// 2: visible in both traveled & collapsed graphs
24-
if (!wpt->colocated)
25-
{ if (!wpt->is_hidden) visibility = 2;
26-
wpt->route->region->add_vertex(this, wpt);
27-
wpt->route->system->add_vertex(this);
28-
return;
29-
}
30-
for (Waypoint *w : *(wpt->colocated))
27+
if (wpt->colocated)
3128
{ // will consider hidden iff all colocated waypoints are hidden
32-
if (!w->is_hidden) visibility = 2;
33-
w->route->region->add_vertex(this, wpt);// Yes, a region/system can get the same vertex multiple times
34-
w->route->system->add_vertex(this); // from different routes. But HighwayGraph::write_subgraphs_tmg
35-
} // gets rid of any redundancy when making the final set.
29+
for (Waypoint *w : *(wpt->colocated))
30+
if (!w->is_hidden)
31+
{ visibility = 2;
32+
return;
33+
}
34+
num_hidden++;
35+
}
36+
else if (!wpt->is_hidden)
37+
visibility = 2;
38+
else num_hidden++;
3639
}
3740

3841
HGVertex::~HGVertex()
3942
{ //std::cout << "deleting vertex at " << first_waypoint->str() << std::endl;
40-
while (incident_s_edges.size()) incident_s_edges.front()->detach();
41-
while (incident_c_edges.size()) incident_c_edges.front()->detach();
42-
while (incident_t_edges.size()) incident_t_edges.front()->detach();
4343
delete[] s_vertex_num;
4444
delete[] c_vertex_num;
4545
delete[] t_vertex_num;
4646
}
47+
48+
HGEdge* HGVertex::front(unsigned char format)
49+
{ for (HGEdge* e : incident_edges)
50+
if (e->format & format)
51+
return e;
52+
// Using this as intended with single-format bitmasks,
53+
// we should never reach this point, because this function
54+
// will only be called on vertices with edge_count of 2.
55+
// Nonetheless, let's stop the compiler from complaining.
56+
throw this;
57+
}
58+
59+
HGEdge* HGVertex::back(unsigned char format)
60+
{ for (auto e = incident_edges.rbegin(); e != incident_edges.rend(); ++e)
61+
if ((*e)->format & format)
62+
return *e;
63+
// Using this as intended with single-format bitmasks,
64+
// we should never reach this point, because this function
65+
// will only be called on vertices with edge_count of 2.
66+
// Nonetheless, let's stop the compiler from complaining.
67+
throw this;
68+
}

siteupdate/cplusplus/classes/GraphGeneration/HGVertex.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ class HGEdge;
22
class HighwaySystem;
33
class Region;
44
class Waypoint;
5-
#include <list>
5+
#include <atomic>
6+
#include <vector>
67
#include <string>
78

89
class HGVertex
@@ -12,14 +13,18 @@ class HGVertex
1213
public:
1314
double lat, lng;
1415
const std::string *unique_name;
15-
std::list<HGEdge*> incident_s_edges; // simple
16-
std::list<HGEdge*> incident_c_edges; // collapsed
17-
std::list<HGEdge*> incident_t_edges; // traveled
16+
std::vector<HGEdge*> incident_edges;
1817
int *s_vertex_num;
1918
int *c_vertex_num;
2019
int *t_vertex_num;
20+
uint16_t edge_count;
2121
char visibility;
2222

23+
static std::atomic_uint num_hidden;
24+
2325
void setup(Waypoint*, const std::string*);
2426
~HGVertex();
27+
28+
HGEdge* front(unsigned char);
29+
HGEdge* back (unsigned char);
2530
};

0 commit comments

Comments
 (0)