Flat bitmap: Add longest-range computation.
This will come in handy in the (upcoming) page-slab set assertions.
This commit is contained in:
parent
e034500698
commit
ed99d300b9
@ -284,4 +284,29 @@ fb_urange_riter(fb_group_t *fb, size_t nbits, size_t start, size_t *r_begin,
|
||||
/* val */ false, /* forward */ false);
|
||||
}
|
||||
|
||||
JEMALLOC_ALWAYS_INLINE size_t
|
||||
fb_range_longest_impl(fb_group_t *fb, size_t nbits, bool val) {
|
||||
size_t begin = 0;
|
||||
size_t longest_len = 0;
|
||||
size_t len = 0;
|
||||
while (begin < nbits && fb_iter_range_impl(fb, nbits, begin, &begin,
|
||||
&len, val, /* forward */ true)) {
|
||||
if (len > longest_len) {
|
||||
longest_len = len;
|
||||
}
|
||||
begin += len;
|
||||
}
|
||||
return longest_len;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
fb_srange_longest(fb_group_t *fb, size_t nbits) {
|
||||
return fb_range_longest_impl(fb, nbits, /* val */ true);
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
fb_urange_longest(fb_group_t *fb, size_t nbits) {
|
||||
return fb_range_longest_impl(fb, nbits, /* val */ false);
|
||||
}
|
||||
|
||||
#endif /* JEMALLOC_INTERNAL_FB_H */
|
||||
|
@ -301,6 +301,10 @@ TEST_BEGIN(test_empty_full) {
|
||||
}
|
||||
TEST_END
|
||||
|
||||
/*
|
||||
* This tests both iter_range and the longest range functionality, which is
|
||||
* built closely on top of it.
|
||||
*/
|
||||
TEST_BEGIN(test_iter_range_simple) {
|
||||
size_t set_limit = 30;
|
||||
size_t nbits = 100;
|
||||
@ -318,6 +322,10 @@ TEST_BEGIN(test_iter_range_simple) {
|
||||
|
||||
/* A set of checks with only the first set_limit bits *set*. */
|
||||
fb_set_range(fb, nbits, 0, set_limit);
|
||||
expect_zu_eq(set_limit, fb_srange_longest(fb, nbits),
|
||||
"Incorrect longest set range");
|
||||
expect_zu_eq(nbits - set_limit, fb_urange_longest(fb, nbits),
|
||||
"Incorrect longest unset range");
|
||||
for (size_t i = 0; i < set_limit; i++) {
|
||||
result = fb_srange_iter(fb, nbits, i, &begin, &len);
|
||||
expect_true(result, "Should have found a range at %zu", i);
|
||||
@ -360,6 +368,10 @@ TEST_BEGIN(test_iter_range_simple) {
|
||||
/* A set of checks with only the first set_limit bits *unset*. */
|
||||
fb_unset_range(fb, nbits, 0, set_limit);
|
||||
fb_set_range(fb, nbits, set_limit, nbits - set_limit);
|
||||
expect_zu_eq(nbits - set_limit, fb_srange_longest(fb, nbits),
|
||||
"Incorrect longest set range");
|
||||
expect_zu_eq(set_limit, fb_urange_longest(fb, nbits),
|
||||
"Incorrect longest unset range");
|
||||
for (size_t i = 0; i < set_limit; i++) {
|
||||
result = fb_srange_iter(fb, nbits, i, &begin, &len);
|
||||
expect_true(result, "Should have found a range at %zu", i);
|
||||
@ -436,6 +448,27 @@ fb_iter_simple(fb_group_t *fb, size_t nbits, size_t start, size_t *r_begin,
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Similar, but for finding longest ranges. */
|
||||
static size_t
|
||||
fb_range_longest_simple(fb_group_t *fb, size_t nbits, bool val) {
|
||||
size_t longest_so_far = 0;
|
||||
for (size_t begin = 0; begin < nbits; begin++) {
|
||||
if (fb_get(fb, nbits, begin) != val) {
|
||||
continue;
|
||||
}
|
||||
size_t end = begin + 1;
|
||||
for (; end < nbits; end++) {
|
||||
if (fb_get(fb, nbits, end) != val) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (end - begin > longest_so_far) {
|
||||
longest_so_far = end - begin;
|
||||
}
|
||||
}
|
||||
return longest_so_far;
|
||||
}
|
||||
|
||||
static void
|
||||
expect_iter_results_at(fb_group_t *fb, size_t nbits, size_t pos,
|
||||
bool val, bool forward) {
|
||||
@ -487,6 +520,10 @@ expect_iter_results(fb_group_t *fb, size_t nbits) {
|
||||
expect_iter_results_at(fb, nbits, i, true, false);
|
||||
expect_iter_results_at(fb, nbits, i, true, true);
|
||||
}
|
||||
expect_zu_eq(fb_range_longest_simple(fb, nbits, true),
|
||||
fb_srange_longest(fb, nbits), "Longest range mismatch");
|
||||
expect_zu_eq(fb_range_longest_simple(fb, nbits, false),
|
||||
fb_urange_longest(fb, nbits), "Longest range mismatch");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -527,6 +564,10 @@ do_test_iter_range_exhaustive(size_t nbits) {
|
||||
free(fb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Like test_iter_range_simple, this tests both iteration and longest-range
|
||||
* computation.
|
||||
*/
|
||||
TEST_BEGIN(test_iter_range_exhaustive) {
|
||||
#define NB(nbits) \
|
||||
do_test_iter_range_exhaustive(nbits);
|
||||
|
Loading…
Reference in New Issue
Block a user