1
1
#include "pathman.h"
2
2
3
+ /* Check if two ranges are intersecting */
3
4
bool
4
5
irange_intersects (IndexRange a ,IndexRange b )
5
6
{
6
7
return (irange_lower (a ) <=irange_upper (b ))||
7
8
(irange_lower (b ) <=irange_upper (a ));
8
9
}
9
10
11
+ /* Check if two ranges are conjuncted */
10
12
bool
11
13
irange_conjuncted (IndexRange a ,IndexRange b )
12
14
{
13
15
return (irange_lower (a )- 1 <=irange_upper (b ))||
14
16
(irange_lower (b )- 1 <=irange_upper (a ));
15
17
}
16
18
19
+ /* Make union of two ranges. They should have the same lossiness. */
17
20
IndexRange
18
21
irange_union (IndexRange a ,IndexRange b )
19
22
{
@@ -23,6 +26,7 @@ irange_union(IndexRange a, IndexRange b)
23
26
irange_is_lossy (a ));
24
27
}
25
28
29
+ /* Get intersection of two ranges */
26
30
IndexRange
27
31
irange_intersect (IndexRange a ,IndexRange b )
28
32
{
@@ -31,6 +35,9 @@ irange_intersect(IndexRange a, IndexRange b)
31
35
irange_is_lossy (a )|| irange_is_lossy (b ));
32
36
}
33
37
38
+ /*
39
+ * Make union of two index rage lists.
40
+ */
34
41
List *
35
42
irange_list_union (List * a ,List * b )
36
43
{
@@ -47,6 +54,7 @@ irange_list_union(List *a, List *b)
47
54
{
48
55
IndexRange next ;
49
56
57
+ /* Fetch next range with lesser lower bound */
50
58
if (ca && cb )
51
59
{
52
60
if (irange_lower (lfirst_irange (ca )) <=irange_lower (lfirst_irange (cb )))
@@ -73,13 +81,17 @@ irange_list_union(List *a, List *b)
73
81
74
82
if (!have_cur )
75
83
{
84
+ /* Put this range as current value if don't have it yet */
76
85
cur = next ;
77
86
have_cur = true;
78
87
}
79
88
else
80
89
{
81
90
if (irange_conjuncted (next ,cur ))
82
91
{
92
+ /*
93
+ * Ranges are conjuncted, try to unify them.
94
+ */
83
95
if (irange_is_lossy (next )== irange_is_lossy (cur ))
84
96
{
85
97
cur = irange_union (next ,cur );
@@ -105,18 +117,26 @@ irange_list_union(List *a, List *b)
105
117
}
106
118
else
107
119
{
120
+ /*
121
+ * Next range is not conjuncted with current. Put current to the
122
+ * result list and put next as current.
123
+ */
108
124
result = lappend_irange (result ,cur );
109
125
cur = next ;
110
126
}
111
127
}
112
128
}
113
129
130
+ /* Put current value into result list if any */
114
131
if (have_cur )
115
132
result = lappend_irange (result ,cur );
116
133
117
134
return result ;
118
135
}
119
136
137
+ /*
138
+ * Find intersection of two range lists.
139
+ */
120
140
List *
121
141
irange_list_intersect (List * a ,List * b )
122
142
{
@@ -132,10 +152,16 @@ irange_list_intersect(List *a, List *b)
132
152
{
133
153
ra = lfirst_irange (ca );
134
154
rb = lfirst_irange (cb );
155
+
156
+ /* Only care about intersecting ranges */
135
157
if (irange_intersects (ra ,rb ))
136
158
{
137
159
IndexRange intersect ,last ;
138
160
161
+ /*
162
+ * Get intersection and try to "glue" it to previous range,
163
+ * put it separately otherwise.
164
+ */
139
165
intersect = irange_intersect (ra ,rb );
140
166
if (result != NIL )
141
167
{
@@ -156,6 +182,11 @@ irange_list_intersect(List *a, List *b)
156
182
}
157
183
}
158
184
185
+ /*
186
+ * Fetch next ranges. We use upper bound of current range to determine
187
+ * which lists to fetch, since lower bound of next range is greater (or
188
+ * equal) to upper bound of current.
189
+ */
159
190
if (irange_upper (ra ) <=irange_upper (rb ))
160
191
ca = lnext (ca );
161
192
if (irange_upper (ra ) >=irange_upper (rb ))
@@ -164,6 +195,7 @@ irange_list_intersect(List *a, List *b)
164
195
return result ;
165
196
}
166
197
198
+ /* Get total number of elements in range list */
167
199
int
168
200
irange_list_length (List * rangeset )
169
201
{
@@ -178,6 +210,7 @@ irange_list_length(List *rangeset)
178
210
return result ;
179
211
}
180
212
213
+ /* Find particular index in range list */
181
214
bool
182
215
irange_list_find (List * rangeset ,int index ,bool * lossy )
183
216
{