WIP
This commit is contained in:
parent
bd8a1f0b0c
commit
b399e8af78
2 changed files with 41 additions and 5 deletions
|
@ -825,7 +825,8 @@ __sm_get_fully_aligned_offset(size_t idx)
|
|||
*
|
||||
* @param[in] map The sparsemap_t in question.
|
||||
* @param[in] idx The index of the chunk map to locate.
|
||||
* @returns the byte offset of a __sm_chunk_t in m_data.
|
||||
* @returns the byte offset of a __sm_chunk_t in m_data, or -1 there
|
||||
* are no chunks.
|
||||
*/
|
||||
static size_t
|
||||
__sm_get_chunk_map_offset(sparsemap_t *map, sparsemap_idx_t idx)
|
||||
|
@ -843,7 +844,7 @@ __sm_get_chunk_map_offset(sparsemap_t *map, sparsemap_idx_t idx)
|
|||
__sm_assert(s == __sm_get_aligned_offset(s));
|
||||
__sm_chunk_t chunk;
|
||||
__sm_chunk_map_init(&chunk, p + sizeof(sm_idx_t));
|
||||
if (s >= idx || (unsigned long)idx < s + __sm_chunk_map_get_capacity(&chunk)) {
|
||||
if (s >= idx || idx < s + __sm_chunk_map_get_capacity(&chunk)) {
|
||||
break;
|
||||
}
|
||||
p += sizeof(sm_idx_t) + __sm_chunk_map_get_size(&chunk);
|
||||
|
@ -1070,7 +1071,7 @@ sparsemap_set(sparsemap_t *map, sparsemap_idx_t idx, bool value)
|
|||
return SPARSEMAP_IDX_MAX;
|
||||
}
|
||||
|
||||
/* If there is no __sm_chunk_t and the bit is set to zero then return
|
||||
/* If there are no __sm_chunk_t and the bit is set to zero then return
|
||||
immediately; otherwise create an initial __sm_chunk_t. */
|
||||
if (offset == -1) {
|
||||
if (value == false) {
|
||||
|
@ -1270,6 +1271,7 @@ sparsemap_merge(sparsemap_t *map, sparsemap_t *other)
|
|||
__sm_chunk_t dst_chunk;
|
||||
__sm_chunk_map_init(&dst_chunk, dst + sizeof(sm_idx_t));
|
||||
__sm_chunk_map_merge(map, src_start, src_chunk);
|
||||
*(sm_idx_t *)dst = __sm_get_aligned_offset(src_start);
|
||||
src += sizeof(sm_idx_t) + __sm_chunk_map_get_size(&src_chunk);
|
||||
dst += sizeof(sm_idx_t) + __sm_chunk_map_get_size(&dst_chunk);
|
||||
dst_count--;
|
||||
|
@ -1280,14 +1282,24 @@ sparsemap_merge(sparsemap_t *map, sparsemap_t *other)
|
|||
__sm_chunk_t src_chunk;
|
||||
__sm_chunk_map_init(&src_chunk, src + sizeof(sm_idx_t));
|
||||
size_t src_size = __sm_chunk_map_get_size(&src_chunk);
|
||||
__sm_insert_data(map, dst_start, src, src_size);
|
||||
uint8_t buf[sizeof(sm_idx_t) + sizeof(sm_bitvec_t) * 2] = { 0 };
|
||||
if (dst_count == 0) {
|
||||
__sm_append_data(map, &buf[0], sizeof(buf));
|
||||
} else {
|
||||
size_t offset = __sm_get_chunk_map_offset(map, dst_start);
|
||||
__sm_insert_data(map, offset, &buf[0], sizeof(buf));
|
||||
}
|
||||
memcpy(dst + sizeof(sm_idx_t), &src_chunk, src_size);
|
||||
*(sm_idx_t *)dst = src_start;
|
||||
|
||||
/* Update the chunk count and data_used. */
|
||||
__sm_set_chunk_map_count(map, __sm_get_chunk_map_count(map) + 1);
|
||||
|
||||
/* Carry on to the next chunk. */
|
||||
__sm_chunk_t dst_chunk;
|
||||
__sm_chunk_map_init(&dst_chunk, dst + sizeof(sm_idx_t));
|
||||
src += sizeof(sm_idx_t) + __sm_chunk_map_get_size(&src_chunk);
|
||||
dst += sizeof(sm_idx_t) + __sm_chunk_map_get_size(&dst_chunk);
|
||||
src_count--;
|
||||
}
|
||||
}
|
||||
|
|
26
tests/test.c
26
tests/test.c
|
@ -631,8 +631,10 @@ test_api_merge(const MunitParameter params[], void *data)
|
|||
assert_ptr_not_null(map);
|
||||
assert_ptr_not_null(other);
|
||||
|
||||
// Merge two empty maps to get an empty map.
|
||||
sparsemap_merge(map, other);
|
||||
|
||||
// Merge a single set bit in the first chunk into the empty map.
|
||||
sparsemap_set(other, 0, true);
|
||||
sparsemap_merge(map, other);
|
||||
|
||||
|
@ -642,6 +644,7 @@ test_api_merge(const MunitParameter params[], void *data)
|
|||
sparsemap_clear(map);
|
||||
sparsemap_clear(other);
|
||||
|
||||
// Merge two maps with the same single bit set.
|
||||
sparsemap_set(map, 0, true);
|
||||
sparsemap_set(other, 0, true);
|
||||
sparsemap_merge(map, other);
|
||||
|
@ -649,6 +652,7 @@ test_api_merge(const MunitParameter params[], void *data)
|
|||
sparsemap_clear(map);
|
||||
sparsemap_clear(other);
|
||||
|
||||
// Merge an empty map with one that has the first bit set.
|
||||
sparsemap_set(map, 0, true);
|
||||
sparsemap_merge(map, other);
|
||||
|
||||
|
@ -680,12 +684,32 @@ test_api_merge(const MunitParameter params[], void *data)
|
|||
assert_true(sparsemap_is_set(map, 8193));
|
||||
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
if (i == 2050 || i == 1 || i == 2049 || i == 4097 || i == 8193)
|
||||
if (i == 2049 || i == 1 || i == 2050 || i == 4097 || i == 8193)
|
||||
continue;
|
||||
else
|
||||
assert_false(sparsemap_is_set(map, i));
|
||||
}
|
||||
|
||||
sparsemap_clear(map);
|
||||
sparsemap_clear(other);
|
||||
|
||||
sparsemap_set(map, 0, true);
|
||||
sparsemap_set(map, 2048, true);
|
||||
sparsemap_set(map, 2049, true);
|
||||
sparsemap_set(map, 8193, true);
|
||||
for (int i = 2049; i < 4096; i++) {
|
||||
sparsemap_set(other, i, true);
|
||||
}
|
||||
|
||||
sparsemap_merge(map, other);
|
||||
|
||||
assert(sparsemap_is_set(map, 0));
|
||||
assert(sparsemap_is_set(map, 2048));
|
||||
assert(sparsemap_is_set(map, 8193));
|
||||
for (int i = 2049; i < 4096; i++) {
|
||||
assert(sparsemap_is_set(map, i));
|
||||
}
|
||||
|
||||
free(other);
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue