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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy