{
struct seq_range *range, value;
unsigned int i, count;
- uint32_t next_min_seq;
+ uint32_t prev_min_seq;
if (array_is_created(array))
range = array_get_modifiable(array, &count);
}
for (i = 0; i < count; ) {
- next_min_seq = range[i].seq2 + 1;
- if (range[i].seq1 == min_seq) {
+ prev_min_seq = min_seq;
+ min_seq = range[i].seq2;
+ if (range[i].seq1 == prev_min_seq) {
array_delete(array, i, 1);
range = array_get_modifiable(array, &count);
} else {
range[i].seq2 = range[i].seq1 - 1;
- range[i].seq1 = min_seq;
+ range[i].seq1 = prev_min_seq;
i++;
}
- min_seq = next_min_seq;
+ if (min_seq >= max_seq) {
+ /* max_seq is reached. the rest of the array should be
+ empty. we'll return here, because min_seq++ may
+ wrap to 0. */
+ i_assert(min_seq == max_seq);
+ i_assert(i == count);
+ return;
+ }
+ min_seq++;
}
if (min_seq <= max_seq) {
value.seq1 = min_seq;
static const unsigned int input[] = {
1, 2, 3, 4, 5, UINT_MAX,
2, 3, 4, UINT_MAX,
+ 3, 4, 5, UINT_MAX,
1, 2, 4, 5, UINT_MAX,
1, 3, 5, UINT_MAX,
1, UINT_MAX,
}
}
+static void test_seq_range_array_invert_edges(void)
+{
+ const struct {
+ int64_t a_seq1, a_seq2, b_seq1, b_seq2;
+ int64_t resa_seq1, resa_seq2, resb_seq1, resb_seq2;
+ } tests[] = {
+ { -1, -1, -1, -1,
+ 0, 0xffffffff, -1, -1 },
+ { 0, 0xffffffff, -1, -1,
+ -1, -1, -1, -1 },
+ { 0, 0xfffffffe, -1, -1,
+ 0xffffffff, 0xffffffff, -1, -1 },
+ { 1, 0xfffffffe, -1, -1,
+ 0, 0, 0xffffffff, 0xffffffff },
+ { 1, 0xffffffff, -1, -1,
+ 0, 0, -1, -1 },
+ { 0, 0, 0xffffffff, 0xffffffff,
+ 1, 0xfffffffe, -1, -1 },
+ { 0xffffffff, 0xffffffff, -1, -1,
+ 0, 0xfffffffe, -1, -1 },
+ };
+ ARRAY_TYPE(seq_range) range = ARRAY_INIT;
+ const struct seq_range *result;
+ unsigned int count;
+
+ test_begin("seq_range_array_invert() edges");
+ for (unsigned int i = 0; i < N_ELEMENTS(tests); i++) T_BEGIN {
+ t_array_init(&range, 10);
+ if (tests[i].a_seq1 != -1)
+ seq_range_array_add_range(&range, tests[i].a_seq1, tests[i].a_seq2);
+ if (tests[i].b_seq1 != -1)
+ seq_range_array_add_range(&range, tests[i].b_seq1, tests[i].b_seq2);
+ seq_range_array_invert(&range, 0, 0xffffffff);
+
+ result = array_get(&range, &count);
+ if (tests[i].resa_seq1 == -1)
+ test_assert_idx(count == 0, i);
+ else {
+ test_assert(result[0].seq1 == tests[i].resa_seq1);
+ test_assert(result[0].seq2 == tests[i].resa_seq2);
+ if (tests[i].resb_seq1 == -1)
+ test_assert_idx(count == 1, i);
+ else {
+ test_assert(result[1].seq1 == tests[i].resb_seq1);
+ test_assert(result[1].seq2 == tests[i].resb_seq2);
+ }
+ }
+ } T_END;
+ test_end();
+}
+
static void test_seq_range_create(ARRAY_TYPE(seq_range) *array, uint8_t byte)
{
unsigned int i;
test_seq_range_array_add_merge();
test_seq_range_array_remove_nth();
test_seq_range_array_invert();
+ test_seq_range_array_invert_edges();
test_seq_range_array_have_common();
test_seq_range_array_random();
}