find a span of unset bits in an empty map

This commit is contained in:
Gregory Burd 2024-06-13 05:58:12 -04:00
parent f7fd8eed9a
commit 7335c8e1d8
3 changed files with 21 additions and 1 deletions

View file

@ -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_link_libraries(soak PRIVATE sparsemap)
target_include_directories(soak PRIVATE ${HEADER_DIR} lib) target_include_directories(soak PRIVATE ${HEADER_DIR} lib)
target_link_libraries(soak PUBLIC m) target_link_libraries(soak PUBLIC m)
add_custom_target(run_soak COMMAND soak WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) 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})

View file

@ -49,6 +49,9 @@ test: tests
soak: tests soak: tests
env ASAN_OPTIONS=detect_leaks=1 LSAN_OPTIONS=verbosity=1:log_threads=1 ./tests/soak 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) tests/test: $(TEST_OBJS) $(LIB_OBJS) $(STATIC_LIB)
$(CC) $^ $(LIBS) -o $@ $(TEST_FLAGS) $(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) tests/soak: $(LIB_OBJS) tests/soak.o $(STATIC_LIB)
$(CC) $^ $(LIBS) -o $@ $(TEST_FLAGS) $(CC) $^ $(LIBS) -o $@ $(TEST_FLAGS)
tests/fuzzer: $(LIB_OBJS) tests/fuzzer.o $(STATIC_LIB)
$(CC) $^ $(LIBS) -o $@ $(TEST_FLAGS) -DFUZZ_DEBUG
todo: todo:
rg -i 'todo|gsb|abort' rg -i 'todo|gsb|abort'

View file

@ -1705,6 +1705,10 @@ sparsemap_select(sparsemap_t *map, sparsemap_idx_t n, bool value)
sm_idx_t start; sm_idx_t start;
size_t count = __sm_get_chunk_count(map); size_t count = __sm_get_chunk_count(map);
if (count == 0 && value == false) {
return n;
}
uint8_t *p = __sm_get_chunk_data(map, 0); uint8_t *p = __sm_get_chunk_data(map, 0);
for (size_t i = 0; i < count; i++) { 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 many selects we can avoid by taking the rank of the range and starting
at that bit. */ at that bit. */
nth = (idx == 0) ? 0 : sparsemap_rank(map, 0, idx - 1, value); 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... */ /* Find the first bit that matches value, then... */
offset = sparsemap_select(map, nth, value); offset = sparsemap_select(map, nth, value);
do { do {