Skip to content

Commit 25cff80

Browse files
committed
[WIP] further improvements in irange_handle_cover_internal()
1 parent ed2a778 commit 25cff80

File tree

1 file changed

+52
-19
lines changed

1 file changed

+52
-19
lines changed

src/rangeset.c

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ irange_cmp_lossiness(IndexRange a, IndexRange b)
5656
IndexRange
5757
irange_union_simple(IndexRange a, IndexRange b)
5858
{
59+
/* Ranges should be connected somehow */
5960
Assert(iranges_intersect(a, b) || iranges_adjoin(a, b));
6061

6162
return make_irange(Min(irange_lower(a), irange_lower(b)),
@@ -67,6 +68,7 @@ irange_union_simple(IndexRange a, IndexRange b)
6768
IndexRange
6869
irange_intersection_simple(IndexRange a, IndexRange b)
6970
{
71+
/* Ranges should be connected somehow */
7072
Assert(iranges_intersect(a, b) || iranges_adjoin(a, b));
7173

7274
return make_irange(Max(irange_lower(a), irange_lower(b)),
@@ -81,43 +83,74 @@ irange_handle_cover_internal(IndexRange ir_covering,
8183
IndexRange ir_inner,
8284
List **new_iranges)
8385
{
86+
/* Equal lossiness should've been taken into cosideration earlier */
87+
Assert(is_irange_lossy(ir_covering) != is_irange_lossy(ir_inner));
88+
8489
/* range 'ir_inner' is lossy */
8590
if (is_irange_lossy(ir_covering) == false)
86-
/* Good, this means 'ir_covering' is not */
8791
return ir_covering;
8892

89-
/* range 'ir_covering' is lossy */
93+
/* range 'ir_covering' is lossy, 'ir_inner' is lossless! */
9094
else
9195
{
92-
/* which means that 'ir_inner' is lossless! */
93-
IndexRange left_range,
94-
right_range;
96+
IndexRange ret; /* IndexRange to be returned */
97+
98+
/* 'left_range_upper' should not be less than 'left_range_lower' */
99+
uint32 left_range_lower = irange_lower(ir_covering),
100+
left_range_upper = Max(irb_pred(irange_lower(ir_inner)),
101+
left_range_lower);
102+
103+
/* 'right_range_lower' should not be greater than 'right_range_upper' */
104+
uint32 right_range_upper = irange_upper(ir_covering),
105+
right_range_lower = Min(irb_succ(irange_upper(ir_inner)),
106+
right_range_upper);
95107

96108
/* We have to split the covering lossy IndexRange */
97109
Assert(is_irange_lossy(ir_covering) == true);
98110

99-
/* Left IndexRange is lossy */
100-
left_range = make_irange(irange_lower(ir_covering),
101-
irange_lower(ir_inner),
102-
true);
111+
/* 'ir_inner' should not cover leftmost IndexRange */
112+
if (irange_lower(ir_inner) > left_range_upper)
113+
{
114+
IndexRange left_range;
115+
116+
/* Leftmost IndexRange is lossy */
117+
left_range = make_irange(left_range_lower,
118+
left_range_upper,
119+
true);
103120

104-
/* Right IndexRange is also lossy */
105-
right_range = make_irange(irange_upper(ir_inner),
106-
irange_upper(ir_covering),
107-
true);
121+
/* Append leftmost IndexRange ('left_range') to 'new_iranges' */
122+
*new_iranges = lappend_irange(*new_iranges, left_range);
123+
}
108124

109-
/* Append leftmost and medial IndexRanges to list */
110-
*new_iranges = lappend_irange(*new_iranges, left_range);
111-
*new_iranges = lappend_irange(*new_iranges, ir_inner);
125+
/* 'ir_inner' should not cover rightmost IndexRange */
126+
if (right_range_lower > irange_upper(ir_inner))
127+
{
128+
IndexRange right_range;
129+
130+
/* Rightmost IndexRange is also lossy */
131+
right_range = make_irange(right_range_lower,
132+
right_range_upper,
133+
true);
134+
135+
/* 'right_range' is indeed rightmost IndexRange */
136+
ret = right_range;
137+
138+
/* Append medial IndexRange ('ir_inner') to 'new_iranges' */
139+
*new_iranges = lappend_irange(*new_iranges, ir_inner);
140+
}
141+
/* Else return 'ir_inner' as rightmost IndexRange */
142+
else ret = ir_inner;
112143

113-
/* Return rightmost IndexRange */
114-
return right_range;
144+
/* Return rightmost IndexRange (right_range | ir_inner) */
145+
return ret;
115146
}
116147
}
117148

118149
/* Calculate union of two IndexRanges, return rightmost IndexRange */
119150
static IndexRange
120-
irange_union_internal(IndexRange first, IndexRange second, List **new_iranges)
151+
irange_union_internal(IndexRange first,
152+
IndexRange second,
153+
List **new_iranges)
121154
{
122155
/* Swap 'first' and 'second' if order is incorrect */
123156
if (irange_lower(first) > irange_lower(second))

0 commit comments

Comments
 (0)