adding a merge map function #6
1 changed files with 25 additions and 32 deletions
|
@ -1262,49 +1262,42 @@ sparsemap_merge(sparsemap_t *map, sparsemap_t *other)
|
||||||
{
|
{
|
||||||
uint8_t *src, *dst, *dst_tail;
|
uint8_t *src, *dst, *dst_tail;
|
||||||
size_t src_count = __sm_get_chunk_map_count(other),
|
size_t src_count = __sm_get_chunk_map_count(other),
|
||||||
dst_count = __sm_get_chunk_map_count(map);
|
dst_count = __sm_get_chunk_map_count(map),
|
||||||
|
max_chunk_count = src_count + dst_count;
|
||||||
|
|
||||||
dst = __sm_get_chunk_map_data(map, 0);
|
dst = __sm_get_chunk_map_data(map, 0);
|
||||||
src = __sm_get_chunk_map_data(other, 0);
|
src = __sm_get_chunk_map_data(other, 0);
|
||||||
/* Foreach destination chunk, is there a source chunk with the same starting
|
for (size_t i = 0; i < max_chunk_count && src_count; i++) {
|
||||||
offset? If so, if so let's merge them. */
|
|
||||||
for (size_t i = 0; i < dst_count + src_count; i++) {
|
|
||||||
next_iteration:;
|
|
||||||
__sm_chunk_t dst_chunk;
|
__sm_chunk_t dst_chunk;
|
||||||
sm_idx_t dst_start = *(sm_idx_t *)dst;
|
sm_idx_t dst_start = *(sm_idx_t *)dst;
|
||||||
__sm_chunk_map_init(&dst_chunk, dst + sizeof(sm_idx_t));
|
__sm_chunk_map_init(&dst_chunk, dst + sizeof(sm_idx_t));
|
||||||
if (i < dst_count) {
|
|
||||||
size_t j = 0;
|
|
||||||
while (j < src_count) {
|
|
||||||
__sm_chunk_t src_chunk;
|
|
||||||
sm_idx_t src_start = *(sm_idx_t *)src;
|
|
||||||
__sm_chunk_map_init(&src_chunk, src + sizeof(sm_idx_t));
|
|
||||||
if (src_start == dst_start) {
|
|
||||||
/* Chunks overlap, merge them. */
|
|
||||||
__sm_chunk_map_merge(map, src_start, src_chunk);
|
|
||||||
src = SM_NEXT_CHUNK_ADDR(src);
|
|
||||||
dst = SM_NEXT_CHUNK_ADDR(dst);
|
|
||||||
i++;
|
|
||||||
goto next_iteration;
|
|
||||||
}
|
|
||||||
src = __sm_get_chunk_map_data(other, 0);
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
__sm_chunk_t src_chunk;
|
__sm_chunk_t src_chunk;
|
||||||
sm_idx_t src_start = *(sm_idx_t *)src;
|
sm_idx_t src_start = *(sm_idx_t *)src;
|
||||||
__sm_chunk_map_init(&src_chunk, src + sizeof(sm_idx_t));
|
__sm_chunk_map_init(&src_chunk, src + sizeof(sm_idx_t));
|
||||||
|
|
||||||
/* Copy the chunk data to the buffer. */
|
if (dst_count > 0 && src_start == dst_start) {
|
||||||
dst_tail = __sm_get_chunk_map_end(map);
|
/* Chunks overlap, merge them. */
|
||||||
*(sm_idx_t *)dst_tail = src_start;
|
__sm_chunk_map_merge(map, src_start, src_chunk);
|
||||||
size_t size = __sm_chunk_map_get_size(&src_chunk);
|
src = SM_NEXT_CHUNK_ADDR(src);
|
||||||
memcpy(dst_tail + sizeof(sm_idx_t), src + sizeof(sm_idx_t), size);
|
dst = SM_NEXT_CHUNK_ADDR(dst);
|
||||||
|
dst_count--;
|
||||||
|
src_count--;
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
/* Copy the chunk data directly into the buffer. */
|
||||||
|
// TODO capacity check? ENOMEM
|
||||||
|
dst_tail = __sm_get_chunk_map_end(map);
|
||||||
|
*(sm_idx_t *)dst_tail = src_start;
|
||||||
|
size_t size = __sm_chunk_map_get_size(&src_chunk);
|
||||||
|
memcpy(dst_tail + sizeof(sm_idx_t), src + sizeof(sm_idx_t), size);
|
||||||
|
|
||||||
/* Update the chunk count and data_used. */
|
/* Update the chunk count and data_used. */
|
||||||
map->m_data_used = 0;
|
map->m_data_used = 0;
|
||||||
__sm_set_chunk_map_count(map, __sm_get_chunk_map_count(map) + 1);
|
__sm_set_chunk_map_count(map, __sm_get_chunk_map_count(map) + 1);
|
||||||
src = SM_NEXT_CHUNK_ADDR(src);
|
src = SM_NEXT_CHUNK_ADDR(src);
|
||||||
|
src_count--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue