diff --git a/Makefile b/Makefile index 805302d..fef99e2 100644 --- a/Makefile +++ b/Makefile @@ -5,13 +5,13 @@ SHARED_LIB = libsparsemap.so #CFLAGS = -Wall -Wextra -Wpedantic -Of -std=c11 -Iinclude/ -fPIC #CFLAGS = -Wall -Wextra -Wpedantic -Og -g -std=c11 -Iinclude/ -fPIC -#CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -O0 -g -std=c11 -Iinclude/ -fPIC -CFLAGS = -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -fPIC +CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -O0 -g -std=c11 -Iinclude/ -fPIC +#CFLAGS = -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -fPIC #CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -Og -g -fsanitize=address,leak,object-size,pointer-compare,pointer-subtract,null,return,bounds,pointer-overflow,undefined -fsanitize-address-use-after-scope -std=c11 -Iinclude/ -fPIC #CFLAGS = -Wall -Wextra -Wpedantic -Og -g -fsanitize=all -fhardened -std=c11 -Iinclude/ -fPIC -#TEST_FLAGS = -DDEBUG -Wall -Wextra -Wpedantic -O0 -g -std=c11 -Iinclude/ -Itests/ -fPIC -TEST_FLAGS = -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -Itests/ -fPIC +TEST_FLAGS = -DDEBUG -Wall -Wextra -Wpedantic -O0 -g -std=c11 -Iinclude/ -Itests/ -fPIC +#TEST_FLAGS = -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -Itests/ -fPIC #TEST_FLAGS = -DDEBUG -Wall -Wextra -Wpedantic -Og -g -fsanitize=address,leak,object-size,pointer-compare,pointer-subtract,null,return,bounds,pointer-overflow,undefined -fsanitize-address-use-after-scope -std=c11 -Iinclude/ -fPIC TESTS = tests/test diff --git a/include/sparsemap.h b/include/sparsemap.h index 4c8dc7c..67b9364 100644 --- a/include/sparsemap.h +++ b/include/sparsemap.h @@ -260,11 +260,22 @@ size_t sparsemap_get_size(sparsemap_t *map); */ void sparsemap_scan(sparsemap_t *map, void (*scanner)(sm_idx_t vec[], size_t n), size_t skip); -/** @brief Splits the bitmap by assigning all bits starting at \b offset to the +/** @brief Merges the values from \b other into the \b map, \b other is unchanged. * \b other bitmap while removing them from \b map. * * @param[in] map The sparsemap reference. - * @param[in] skip Start the scan after "skip" bits. +* @param[in] other The bitmap to merge into \b map. + */ +void sparsemap_merge(sparsemap_t *map, sparsemap_t *other); + +/** @brief Splits the bitmap by assigning all bits starting at \b offset to the + * \b other bitmap while removing them from \b map. + * + * The split must occur on a vector boundary. + * + * @param[in] map The sparsemap reference. + * @param[in] offset The 0-based offset into the bitmap at which to split. + * @param[in] other The bitmap into which we place the split. */ void sparsemap_split(sparsemap_t *map, sparsemap_idx_t offset, sparsemap_t *other); diff --git a/src/sparsemap.c b/src/sparsemap.c index 7d22706..b68549a 100644 --- a/src/sparsemap.c +++ b/src/sparsemap.c @@ -1158,6 +1158,35 @@ sparsemap_scan(sparsemap_t *map, void (*scanner)(sm_idx_t[], size_t), size_t ski } } +void +sparsemap_merge(sparsemap_t *map, sparsemap_t *other) +{ + uint8_t *next_dst, *dst = __sm_get_chunk_map_data(map, 0); + + /* |src| points to the |other| (source) chunk map */ + uint8_t *next_src, *src = __sm_get_chunk_map_data(other, 0); + + size_t i, src_count = __sm_get_chunk_map_count(other), dst_count = __sm_get_chunk_map_count(map); + for (i = 0; i < dst_count; i++) { + sm_idx_t src_start = *(sm_idx_t *)src; + sm_idx_t dst_start = *(sm_idx_t *)dst; + __sm_chunk_t src_chunk, dst_chunk; + __sm_chunk_map_init(&src_chunk, src + sizeof(sm_idx_t)); + __sm_chunk_map_init(&dst_chunk, dst + sizeof(sm_idx_t)); + if (src_start == dst_start) { + __sm_chunk_map_merge(dst, src); + } else { + next_dst = dst + sizeof(sm_idx_t) + __sm_chunk_map_get_size(&dst_chunk); + next_src = dst + sizeof(sm_idx_t) + __sm_chunk_map_get_size(&src_chunk); + if (src_start != next_dst) { + // Copy the chunk. + } else { + + } + } + } +} + void sparsemap_split(sparsemap_t *map, sparsemap_idx_t offset, sparsemap_t *other) {