From 7335c8e1d881db0dd4a2937d9e55d01ad98a930e Mon Sep 17 00:00:00 2001 From: Greg Burd Date: Thu, 13 Jun 2024 05:58:12 -0400 Subject: [PATCH] find a span of unset bits in an empty map --- CMakeLists.txt | 9 ++++++++- Makefile | 6 ++++++ src/sparsemap.c | 7 +++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 088bb31..3dc0c4a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,4 +84,11 @@ add_executable(soak tests/soak.c lib/common.c lib/tdigest.c lib/roaring.c) target_link_libraries(soak PRIVATE sparsemap) target_include_directories(soak PRIVATE ${HEADER_DIR} lib) target_link_libraries(soak PUBLIC m) -add_custom_target(run_soak COMMAND soak WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) \ No newline at end of file +add_custom_target(run_soak COMMAND soak WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + +# Add fuzzer program +add_executable(fuzzer tests/fuzzer.c) +target_link_libraries(fuzzer PRIVATE sparsemap) +target_include_directories(fuzzer PRIVATE ${HEADER_DIR} lib) +target_link_libraries(fuzzer PUBLIC m) +add_custom_target(run_fuzzer COMMAND fuzzer WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/Makefile b/Makefile index 2c00376..1623914 100644 --- a/Makefile +++ b/Makefile @@ -49,6 +49,9 @@ test: tests soak: tests env ASAN_OPTIONS=detect_leaks=1 LSAN_OPTIONS=verbosity=1:log_threads=1 ./tests/soak +fuzzer: tests + env ASAN_OPTIONS=detect_leaks=1 LSAN_OPTIONS=verbosity=1:log_threads=1 ./tests/fuzzer ./crash.case + tests/test: $(TEST_OBJS) $(LIB_OBJS) $(STATIC_LIB) $(CC) $^ $(LIBS) -o $@ $(TEST_FLAGS) @@ -90,6 +93,9 @@ examples/ex_4: $(LIB_OBJS) examples/ex_4.o $(STATIC_LIB) tests/soak: $(LIB_OBJS) tests/soak.o $(STATIC_LIB) $(CC) $^ $(LIBS) -o $@ $(TEST_FLAGS) +tests/fuzzer: $(LIB_OBJS) tests/fuzzer.o $(STATIC_LIB) + $(CC) $^ $(LIBS) -o $@ $(TEST_FLAGS) -DFUZZ_DEBUG + todo: rg -i 'todo|gsb|abort' diff --git a/src/sparsemap.c b/src/sparsemap.c index da9ad78..4b1d479 100644 --- a/src/sparsemap.c +++ b/src/sparsemap.c @@ -1705,6 +1705,10 @@ sparsemap_select(sparsemap_t *map, sparsemap_idx_t n, bool value) sm_idx_t start; size_t count = __sm_get_chunk_count(map); + if (count == 0 && value == false) { + return n; + } + uint8_t *p = __sm_get_chunk_data(map, 0); for (size_t i = 0; i < count; i++) { @@ -1847,6 +1851,9 @@ sparsemap_span(sparsemap_t *map, sparsemap_idx_t idx, size_t len, bool value) many selects we can avoid by taking the rank of the range and starting at that bit. */ nth = (idx == 0) ? 0 : sparsemap_rank(map, 0, idx - 1, value); + if (SPARSEMAP_NOT_FOUND(nth)) { + return nth; + } /* Find the first bit that matches value, then... */ offset = sparsemap_select(map, nth, value); do {