Skip to content

Commit 897c231

Browse files
committed
TMBitsets for subgraph membership
1 parent d02b171 commit 897c231

18 files changed

Lines changed: 323 additions & 318 deletions

File tree

siteupdate/cplusplus/classes/GraphGeneration/HGEdge.cpp

Lines changed: 22 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -9,49 +9,26 @@
99

1010
HGEdge::HGEdge(HighwaySegment *s)
1111
{ // 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;
1712
vertex1 = s->waypoint1->hashpoint()->vertex;
1813
vertex2 = s->waypoint2->hashpoint()->vertex;
1914
format = simple | collapsed | traveled;
2015
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);
16+
vertex1->incident_edges.push_back(this);
17+
vertex2->incident_edges.push_back(this);
18+
vertex1->edge_count++;
19+
vertex2->edge_count++;
2720
// canonical segment, used to reference region and list of travelers
2821
// assumption: each edge/segment lives within a unique region
2922
// and a 'multi-edge' would not be able to span regions as there
3023
// would be a required visible waypoint at the border
3124
segment = s;
3225
}
3326

34-
HGEdge::HGEdge(HGVertex *vertex, unsigned char fmt_mask)
27+
HGEdge::HGEdge(HGVertex *vertex, int& deletions, unsigned char fmt_mask, HGEdge *e1, HGEdge *e2)
3528
{ // 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;
3929
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-
}
30+
HGEdge *edge1 = e1;
31+
HGEdge *edge2 = e2;
5532
// segment names should match as routes should not start or end
5633
// nor should concurrencies begin or end at a hidden point
5734
if (edge1->segment_name != edge2->segment_name)
@@ -103,46 +80,29 @@ HGEdge::HGEdge(HGVertex *vertex, unsigned char fmt_mask)
10380
intermediate_point_string() << " to " << *(vertex2->unique_name) << std::endl;
10481
//std::cout << "DEBUG: new " << str() << std::endl;
10582

83+
// clear format bits of old edges
84+
// anything with a format of 0 won't be moved to the graph, and
85+
// will be destroyed when the temp_edges container exits scope
86+
edge1->format &= ~fmt_mask;
87+
edge2->format &= ~fmt_mask;
10688
// 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-
}
89+
if (!edge1->format) {edge1->detach(); deletions++;}
90+
if (!edge2->format) {edge2->detach(); deletions++;}
91+
vertex1->incident_edges.push_back(this);
92+
vertex2->incident_edges.push_back(this);
11793
}
11894

119-
void HGEdge::detach() {return detach(format);}
120-
void HGEdge::detach(unsigned char fmt_mask)
95+
void HGEdge::detach()
12196
{ // 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++) \
97+
auto detach = [&](std::vector<HGEdge*>& v) \
98+
{ for (std::vector<HGEdge*>::iterator e = v.begin(); e != v.end(); e++) \
12499
if (*e == this) \
125100
{ v.erase(e); \
126101
break; \
127102
}
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-
}
103+
};
104+
detach(vertex1->incident_edges);
105+
detach(vertex2->incident_edges);
146106
}
147107

148108
// write line to tmg collapsed edge file

siteupdate/cplusplus/classes/GraphGeneration/HGEdge.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ class HGEdge
1010
edge that can incorporate intermediate points.
1111
*/
1212
public:
13-
char *written;
1413
std::string segment_name;
1514
HGVertex *vertex1, *vertex2;
1615
std::list<HGVertex*> intermediate_points; // if more than 1, will go from vertex1 to vertex2
@@ -23,10 +22,9 @@ class HGEdge
2322
static constexpr unsigned char traveled = 4;
2423

2524
HGEdge(HighwaySegment *);
26-
HGEdge(HGVertex *, unsigned char);
25+
HGEdge(HGVertex *, int&, unsigned char, HGEdge*, HGEdge*);
2726

2827
void detach();
29-
void detach(unsigned char);
3028
void collapsed_tmg_line(std::ofstream&, char*, unsigned int, std::vector<HighwaySystem*>*);
3129
void traveled_tmg_line (std::ofstream&, char*, unsigned int, std::vector<HighwaySystem*>*, bool, char*);
3230
std::string debug_tmg_line(std::vector<HighwaySystem*> *, unsigned int);

siteupdate/cplusplus/classes/GraphGeneration/HGVertex.cpp

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,49 @@ void HGVertex::setup(Waypoint *wpt, const std::string *n)
1616
t_vertex_num = new int[Args::numthreads];
1717
// deleted by ~HGVertex, called by HighwayGraph::clear
1818
unique_name = n;
19+
edge_count = 0;
1920
visibility = 0;
2021
// permitted values:
2122
// 0: never visible outside of simple graphs
2223
// 1: visible only in traveled graph; hidden in collapsed graph
2324
// 2: visible in both traveled & collapsed graphs
2425
if (!wpt->colocated)
2526
{ if (!wpt->is_hidden) visibility = 2;
26-
wpt->route->region->add_vertex(this, wpt);
27-
wpt->route->system->add_vertex(this);
2827
return;
2928
}
3029
for (Waypoint *w : *(wpt->colocated))
31-
{ // 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.
30+
// will consider hidden iff all colocated waypoints are hidden
31+
if (!w->is_hidden)
32+
{ visibility = 2;
33+
break;
34+
}
3635
}
3736

3837
HGVertex::~HGVertex()
3938
{ //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();
4339
delete[] s_vertex_num;
4440
delete[] c_vertex_num;
4541
delete[] t_vertex_num;
4642
}
43+
44+
HGEdge* HGVertex::front(unsigned char format)
45+
{ for (HGEdge* e : incident_edges)
46+
if (e->format & format)
47+
return e;
48+
// Using this as intended with single-format bitmasks,
49+
// we should never reach this point, because this function
50+
// will only be called on vertices with edge_count of 2.
51+
// Nonetheless, let's stop the compiler from complaining.
52+
throw this;
53+
}
54+
55+
HGEdge* HGVertex::back(unsigned char format)
56+
{ for (auto e = incident_edges.rbegin(); e != incident_edges.rend(); ++e)
57+
if ((*e)->format & format)
58+
return *e;
59+
// Using this as intended with single-format bitmasks,
60+
// we should never reach this point, because this function
61+
// will only be called on vertices with edge_count of 2.
62+
// Nonetheless, let's stop the compiler from complaining.
63+
throw this;
64+
}

siteupdate/cplusplus/classes/GraphGeneration/HGVertex.h

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

88
class HGVertex
@@ -12,14 +12,16 @@ class HGVertex
1212
public:
1313
double lat, lng;
1414
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
15+
std::vector<HGEdge*> incident_edges;
1816
int *s_vertex_num;
1917
int *c_vertex_num;
2018
int *t_vertex_num;
19+
uint16_t edge_count;
2120
char visibility;
2221

2322
void setup(Waypoint*, const std::string*);
2423
~HGVertex();
24+
25+
HGEdge* front(unsigned char);
26+
HGEdge* back (unsigned char);
2527
};

0 commit comments

Comments
 (0)