merge when out of space

This commit is contained in:
Gregory Burd 2024-05-04 09:38:26 -04:00
parent 40de89bd8a
commit cbd53976f9
2 changed files with 18 additions and 4 deletions

View file

@ -263,8 +263,8 @@ void sparsemap_scan(sparsemap_t *map, void (*scanner)(sm_idx_t vec[], size_t n,
* *
* @param[in] map The sparsemap reference. * @param[in] map The sparsemap reference.
* @param[in] other The bitmap to merge into \b map. * @param[in] other The bitmap to merge into \b map.
* @returns 0 on success, -1 and sets errno to ENOSPC when the merge might * @returns 0 on success, or sets errno to ENOSPC and returns the amount of
* require more space than available. * additional space required to successfully merge the maps.
*/ */
int sparsemap_merge(sparsemap_t *map, sparsemap_t *other); int sparsemap_merge(sparsemap_t *map, sparsemap_t *other);

View file

@ -975,6 +975,19 @@ sparsemap(size_t size)
return map; return map;
} }
sparsemap_t *
sparsemap_copy(sparsemap_t *other)
{
size_t cap = sparsemap_get_capacity(other);
sparsemap_t *map = sparsemap(cap);
if (map) {
map->m_capacity = other->m_capacity;
map->m_data_used = other->m_data_used;
memcpy(map->m_data, other->m_data, cap);
}
return map;
}
sparsemap_t * sparsemap_t *
sparsemap_wrap(uint8_t *data, size_t size) sparsemap_wrap(uint8_t *data, size_t size)
{ {
@ -1273,11 +1286,12 @@ sparsemap_merge(sparsemap_t *map, sparsemap_t *other)
size_t src_count = __sm_get_chunk_map_count(other); size_t src_count = __sm_get_chunk_map_count(other);
size_t dst_count = __sm_get_chunk_map_count(map); size_t dst_count = __sm_get_chunk_map_count(map);
size_t max_chunk_count = src_count + dst_count; size_t max_chunk_count = src_count + dst_count;
ssize_t difference = map->m_capacity - (other->m_data_used + src_count * (sizeof(sm_idx_t) + sizeof(sm_bitvec_t) * 2));
/* Estimate worst-case overhead required for merge. */ /* Estimate worst-case overhead required for merge. */
if (map->m_data_used + src_count * (sizeof(sm_idx_t) + sizeof(sm_bitvec_t) * 2) > map->m_capacity) { if (difference <= 0) {
errno = ENOSPC; errno = ENOSPC;
return -1; return -difference;
} }
dst = __sm_get_chunk_map_data(map, 0); dst = __sm_get_chunk_map_data(map, 0);