This commit is contained in:
Gregory Burd 2024-04-29 22:49:34 -04:00
parent 47aa5c4801
commit aeebfdd928
2 changed files with 42 additions and 20 deletions

View file

@ -438,7 +438,7 @@ __sm_chunk_map_set(__sm_chunk_t *map, size_t idx, bool value, size_t *pos, sm_bi
* SM_BITS_PER_VECTOR
*/
static size_t
__sm_chunk_map_select(__sm_chunk_t *map, size_t n, ssize_t *offset, bool value)
__sm_chunk_map_select(__sm_chunk_t *map, size_t n, sparsemap_idx_t *offset, bool value)
{
size_t ret = 0;
register uint8_t *p;
@ -509,12 +509,10 @@ __sm_chunk_map_select(__sm_chunk_t *map, size_t n, ssize_t *offset, bool value)
}
}
}
*offset = (ssize_t)n;
*offset = n;
return ret;
}
extern void print_bits(char *name, uint64_t value); // GSB
/** @brief Counts the bits matching \b value in the range [0, \b idx]
* inclusive after ignoring the first \b offset bits in the chunk.
*
@ -1067,7 +1065,6 @@ sparsemap_set(sparsemap_t *map, sparsemap_idx_t idx, bool value)
/* Get the __sm_chunk_t which manages this index */
ssize_t offset = __sm_get_chunk_map_offset(map, idx);
bool dont_grow = false;
if (map->m_data_used + sizeof(sm_idx_t) + sizeof(sm_bitvec_t) * 2 > map->m_capacity) {
errno = ENOSPC;
return SPARSEMAP_IDX_MAX;
@ -1137,7 +1134,7 @@ sparsemap_set(sparsemap_t *map, sparsemap_idx_t idx, bool value)
}
size_t size = __sm_chunk_map_get_size(&chunk);
offset += (ssize_t)(sizeof(sm_idx_t) + size);
offset += (sizeof(sm_idx_t) + size);
p += sizeof(sm_idx_t) + size;
uint8_t buf[sizeof(sm_idx_t) + sizeof(sm_bitvec_t) * 2] = { 0 };
@ -1170,7 +1167,7 @@ sparsemap_set(sparsemap_t *map, sparsemap_idx_t idx, bool value)
break;
case SM_NEEDS_TO_GROW:
if (!dont_grow) {
offset += (ssize_t)(sizeof(sm_idx_t) + position * sizeof(sm_bitvec_t));
offset += (sizeof(sm_idx_t) + position * sizeof(sm_bitvec_t));
__sm_insert_data(map, offset, (uint8_t *)&fill, sizeof(sm_bitvec_t));
}
__sm_chunk_map_set(&chunk, idx - start, value, &position, &fill, true);
@ -1182,7 +1179,7 @@ sparsemap_set(sparsemap_t *map, sparsemap_idx_t idx, bool value)
__sm_remove_data(map, offset, sizeof(sm_idx_t) + sizeof(sm_bitvec_t) * 2);
__sm_set_chunk_map_count(map, __sm_get_chunk_map_count(map) - 1);
} else {
offset += (ssize_t)(sizeof(sm_idx_t) + position * sizeof(sm_bitvec_t));
offset += (sizeof(sm_idx_t) + position * sizeof(sm_bitvec_t));
__sm_remove_data(map, offset, sizeof(sm_bitvec_t));
}
break;
@ -1258,7 +1255,7 @@ __sm_chunk_map_merge(sparsemap_t *map, sparsemap_idx_t offset, __sm_chunk_t src)
void
sparsemap_merge(sparsemap_t *map, sparsemap_t *other)
{
uint8_t *src, *dst, *dst_tail;
uint8_t *src, *dst;
size_t src_count = __sm_get_chunk_map_count(other), dst_count = __sm_get_chunk_map_count(map), max_chunk_count = src_count + dst_count;
dst = __sm_get_chunk_map_data(map, 0);
@ -1283,20 +1280,28 @@ sparsemap_merge(sparsemap_t *map, sparsemap_t *other)
__sm_chunk_t src_chunk;
__sm_chunk_map_init(&src_chunk, src + sizeof(sm_idx_t));
uint8_t buf[sizeof(sm_idx_t) + sizeof(sm_bitvec_t) * 2] = { 0 };
size_t size = __sm_chunk_map_get_size(&src_chunk);
memcpy(buf, src + sizeof(sm_idx_t), size);
__sm_insert_data(map, src_start, &buf[0], sizeof(buf));
size_t src_size = __sm_chunk_map_get_size(&src_chunk);
size_t offset = src_start + (sizeof(sm_idx_t) + src_size);
__sm_insert_data(map, offset, &buf[0], sizeof(buf));
*(sm_idx_t *)dst = src_start;
size_t aligned_idx = __sm_get_fully_aligned_offset(src_start);
if (src_start - aligned_idx < SM_CHUNK_MAX_CAPACITY) {
__sm_chunk_t dst_chunk;
__sm_chunk_map_init(&dst_chunk, dst + sizeof(sm_idx_t));
__sm_chunk_map_set_capacity(&dst_chunk, src_start - aligned_idx);
}
*(sm_idx_t *)src = src_start = aligned_idx;
__sm_chunk_t dst_chunk;
__sm_chunk_map_init(&dst_chunk, dst + sizeof(sm_idx_t));
/* Update the chunk count and data_used. */
__sm_set_chunk_map_count(map, __sm_get_chunk_map_count(map) + 1);
if (other->m_data_used != 0) {
other->m_data_used += sizeof(sm_idx_t) + sizeof(sm_bitvec_t);
}
size_t capacity = __sm_chunk_map_get_capacity(&src_chunk);
/* Reduce the capacity of the source-chunk map. */
__sm_chunk_map_set_capacity(&dst_chunk, offset % capacity);
/*
uint8_t *src_data = __sm_get_chunk_map_data(other, src_start);
memcpy(&buf, src_data, src_size);
*/
/* Carry on to the next chunk. */
src += sizeof(sm_idx_t) + __sm_chunk_map_get_size(&src_chunk);
@ -1441,7 +1446,7 @@ sparsemap_select(sparsemap_t *map, sparsemap_idx_t n, bool value)
__sm_chunk_t chunk;
__sm_chunk_map_init(&chunk, p);
ssize_t new_n = (ssize_t)n;
ssize_t new_n = n;
size_t index = __sm_chunk_map_select(&chunk, n, &new_n, value);
if (new_n == -1) {
return start + index;

View file

@ -631,6 +631,8 @@ test_api_merge(const MunitParameter params[], void *data)
assert_ptr_not_null(map);
assert_ptr_not_null(other);
sparsemap_merge(map, other);
sparsemap_set(other, 0, true);
sparsemap_merge(map, other);
@ -640,6 +642,21 @@ test_api_merge(const MunitParameter params[], void *data)
sparsemap_clear(map);
sparsemap_clear(other);
sparsemap_set(map, 0, true);
sparsemap_set(other, 0, true);
sparsemap_merge(map, other);
sparsemap_clear(map);
sparsemap_clear(other);
sparsemap_set(map, 0, true);
sparsemap_merge(map, other);
assert_true(sparsemap_is_set(map, 0));
sparsemap_clear(map);
sparsemap_clear(other);
sparsemap_set(other, 2049, true);
sparsemap_merge(map, other);