diff --git a/include/sparsemap.h b/include/sparsemap.h index 641dca2..f2ac2c7 100644 --- a/include/sparsemap.h +++ b/include/sparsemap.h @@ -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] other The bitmap to merge into \b map. - * @returns 0 on success, -1 and sets errno to ENOSPC when the merge might - * require more space than available. + * @returns 0 on success, or sets errno to ENOSPC and returns the amount of + * additional space required to successfully merge the maps. */ int sparsemap_merge(sparsemap_t *map, sparsemap_t *other); diff --git a/src/sparsemap.c b/src/sparsemap.c index 0520da9..b423bdc 100644 --- a/src/sparsemap.c +++ b/src/sparsemap.c @@ -975,6 +975,19 @@ sparsemap(size_t size) 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_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 dst_count = __sm_get_chunk_map_count(map); 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. */ - if (map->m_data_used + src_count * (sizeof(sm_idx_t) + sizeof(sm_bitvec_t) * 2) > map->m_capacity) { + if (difference <= 0) { errno = ENOSPC; - return -1; + return -difference; } dst = __sm_get_chunk_map_data(map, 0);