This commit is contained in:
Gregory Burd 2024-04-09 17:10:22 -04:00
parent 92b6cc00db
commit 1ea0871506
2 changed files with 31 additions and 37 deletions

View file

@ -429,10 +429,9 @@ __sm_chunk_map_select(__sm_chunk_t *map, size_t n, ssize_t *pnew_n)
* Counts the set bits in the range [first, last] inclusive. * Counts the set bits in the range [first, last] inclusive.
*/ */
static size_t static size_t
__sm_chunk_map_rank(__sm_chunk_t *map, size_t first, size_t last, size_t *after) __sm_chunk_map_rank(__sm_chunk_t *map, size_t last, size_t *after)
{ {
size_t ret = 0; size_t ret = 0;
(void)first; // TODO
register uint8_t *p = (uint8_t *)map->m_data; register uint8_t *p = (uint8_t *)map->m_data;
for (size_t i = 0; i < sizeof(sm_bitvec_t); i++, p++) { for (size_t i = 0; i < sizeof(sm_bitvec_t); i++, p++) {
@ -480,24 +479,10 @@ __sm_chunk_map_rank(__sm_chunk_t *map, size_t first, size_t last, size_t *after)
*after = 0; *after = 0;
} }
} else { } else {
uint64_t mask_l, mask_r, mask; uint64_t mask;
if (*after > 0) { /* Create a mask for the range between after and last inclusive [*after, last]. */
if (*after > last) { mask = ((uint64_t)1 << (last + 1)) - 1 - (((uint64_t)1 << *after) - 1);
*after = *after - last; *after -= (*after > last) ? last : *after;
/* This gives us 'last' number of ones on the right. */
mask_r = ((uint64_t)1 << last) - 1;
} else {
/* This gives us '*after' number of ones on the right. */
mask_r = (((uint64_t)1 << *after) - 1);
*after = 0;
}
/* Used to shift the mask_r block to the left 'last' times. */
mask_l = ((uint64_t)1 << (last + 1));
mask = mask_l - 1 - mask_r;
} else {
mask = UINT64_MAX >> (SM_BITS_PER_VECTOR - last - 1);
}
/* Create a mask for the range between *after and last. */
uint64_t mw = w & mask; uint64_t mw = w & mask;
ret += popcountll(mw); ret += popcountll(mw);
return (ret); return (ret);
@ -1207,7 +1192,7 @@ sparsemap_rank(sparsemap_t *map, size_t first, size_t last)
__sm_chunk_t chunk; __sm_chunk_t chunk;
__sm_chunk_map_init(&chunk, p); __sm_chunk_map_init(&chunk, p);
result += __sm_chunk_map_rank(&chunk, first - start, last - start, &after); result += __sm_chunk_map_rank(&chunk, last - start, &after);
p += __sm_chunk_map_get_size(&chunk); p += __sm_chunk_map_get_size(&chunk);
} }
return (result); return (result);

View file

@ -550,16 +550,16 @@ test_api_rank(const MunitParameter params[], void *data)
/* rank() is also 0-based, for consistency (and confusion sake); consider the /* rank() is also 0-based, for consistency (and confusion sake); consider the
range as [start, end] of [0, 9] counts the bits set in the first 10 range as [start, end] of [0, 9] counts the bits set in the first 10
positions (starting from the LSB) in the index. */ positions (starting from the LSB) in the index. */
r1 = sparsemap_rank(map, 0, 9); r1 = rank_uint64((uint64_t)-1, 0, 9);
r2 = rank_uint64((uint64_t)-1, 0, 9); r2 = sparsemap_rank(map, 0, 9);
assert_true(r1 == r2); assert_true(r1 == r2);
assert_true(sparsemap_rank(map, 0, 9) == 10); assert_true(sparsemap_rank(map, 0, 9) == 10);
assert_true(sparsemap_rank(map, 1000, 1050) == 0); assert_true(sparsemap_rank(map, 1000, 1050) == 0);
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
for (int j = i; j < 10; j++) { for (int j = i; j < 10; j++) {
r1 = sparsemap_rank(map, i, j); r1 = rank_uint64((uint64_t)-1, i, j);
r2 = rank_uint64((uint64_t)-1, i, j); r2 = sparsemap_rank(map, i, j);
assert_true(r1 == r2); assert_true(r1 == r2);
} }
} }
@ -597,11 +597,20 @@ test_api_span(const MunitParameter params[], void *data)
for (int j = 1; j < amt / 10; j++) { for (int j = 1; j < amt / 10; j++) {
sparsemap_clear(map); sparsemap_clear(map);
placed_at = create_sequential_set_in_empty_map(map, amt, j); placed_at = create_sequential_set_in_empty_map(map, amt, j);
// whats_set(map, amt);
located_at = sparsemap_span(map, 0, j); located_at = sparsemap_span(map, 0, j);
assert_true(located_at == placed_at); assert_true(located_at == placed_at);
//TODO located_at = sparsemap_span(map, (placed_at < j ? 0 : placed_at / 2), i); }
// assert_true(placed_at == located_at); }
for (int i = 1; i < amt; i++) {
for (int j = 1; j < amt / 10; j++) {
sparsemap_clear(map);
populate_map(map, 1024, 3 * 1024);
placed_at = create_sequential_set_in_empty_map(map, amt, j);
located_at = sparsemap_span(map, 0, j);
assert_true(located_at <= placed_at);
//TODO located_at = sparsemap_span(map, (placed_at < j ? 0 : placed_at / 2), i);
// assert_true(placed_at == located_at);
} }
} }