adding a merge map function #6
2 changed files with 42 additions and 20 deletions
|
@ -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;
|
||||
|
||||
/* 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;
|
||||
|
|
17
tests/test.c
17
tests/test.c
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue