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);
|
/* 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 */
|
#endif /* JEMALLOC_INTERNAL_FB_H */
|
||||||
|
@ -301,6 +301,10 @@ TEST_BEGIN(test_empty_full) {
|
|||||||
}
|
}
|
||||||
TEST_END
|
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) {
|
TEST_BEGIN(test_iter_range_simple) {
|
||||||
size_t set_limit = 30;
|
size_t set_limit = 30;
|
||||||
size_t nbits = 100;
|
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*. */
|
/* A set of checks with only the first set_limit bits *set*. */
|
||||||
fb_set_range(fb, nbits, 0, set_limit);
|
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++) {
|
for (size_t i = 0; i < set_limit; i++) {
|
||||||
result = fb_srange_iter(fb, nbits, i, &begin, &len);
|
result = fb_srange_iter(fb, nbits, i, &begin, &len);
|
||||||
expect_true(result, "Should have found a range at %zu", i);
|
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*. */
|
/* A set of checks with only the first set_limit bits *unset*. */
|
||||||
fb_unset_range(fb, nbits, 0, set_limit);
|
fb_unset_range(fb, nbits, 0, set_limit);
|
||||||
fb_set_range(fb, nbits, set_limit, nbits - 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++) {
|
for (size_t i = 0; i < set_limit; i++) {
|
||||||
result = fb_srange_iter(fb, nbits, i, &begin, &len);
|
result = fb_srange_iter(fb, nbits, i, &begin, &len);
|
||||||
expect_true(result, "Should have found a range at %zu", i);
|
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;
|
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
|
static void
|
||||||
expect_iter_results_at(fb_group_t *fb, size_t nbits, size_t pos,
|
expect_iter_results_at(fb_group_t *fb, size_t nbits, size_t pos,
|
||||||
bool val, bool forward) {
|
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, false);
|
||||||
expect_iter_results_at(fb, nbits, i, true, true);
|
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
|
static void
|
||||||
@ -527,6 +564,10 @@ do_test_iter_range_exhaustive(size_t nbits) {
|
|||||||
free(fb);
|
free(fb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Like test_iter_range_simple, this tests both iteration and longest-range
|
||||||
|
* computation.
|
||||||
|
*/
|
||||||
TEST_BEGIN(test_iter_range_exhaustive) {
|
TEST_BEGIN(test_iter_range_exhaustive) {
|
||||||
#define NB(nbits) \
|
#define NB(nbits) \
|
||||||
do_test_iter_range_exhaustive(nbits);
|
do_test_iter_range_exhaustive(nbits);
|
||||||
|
Loading…
Reference in New Issue
Block a user