split
This commit is contained in:
parent
604d48617e
commit
f5b500087d
3 changed files with 48 additions and 40 deletions
8
Makefile
8
Makefile
|
@ -6,16 +6,16 @@ SHARED_LIB = libsparsemap.so
|
||||||
LIBS = -lm
|
LIBS = -lm
|
||||||
#CFLAGS = -Wall -Wextra -Wpedantic -Of -std=c11 -Iinclude/ -fPIC
|
#CFLAGS = -Wall -Wextra -Wpedantic -Of -std=c11 -Iinclude/ -fPIC
|
||||||
#CFLAGS = -Wall -Wextra -Wpedantic -Og -g -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 = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -O0 -g -std=c11 -Iinclude/ -fPIC
|
||||||
#CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -fPIC
|
CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -fPIC
|
||||||
#CFLAGS = -Wall -Wextra -Wpedantic -Og -g -std=c11 -Iinclude/ -fPIC
|
#CFLAGS = -Wall -Wextra -Wpedantic -Og -g -std=c11 -Iinclude/ -fPIC
|
||||||
#CFLAGS = -Wall -Wextra -Wpedantic -Ofast -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 = -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
|
#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 = -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 = -Wall -Wextra -Wpedantic -Ofast -g -std=c11 -Iinclude/ -Itests/ -fPIC
|
||||||
TEST_FLAGS = -Wall -Wextra -Wpedantic -Og -g -std=c11 -Iinclude/ -Itests/ -fPIC
|
#TEST_FLAGS = -Wall -Wextra -Wpedantic -Og -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
|
#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 tests/soak
|
TESTS = tests/test tests/soak
|
||||||
|
|
|
@ -228,7 +228,7 @@ static void
|
||||||
__sm_chunk_reduce_capacity(__sm_chunk_t *chunk, size_t capacity)
|
__sm_chunk_reduce_capacity(__sm_chunk_t *chunk, size_t capacity)
|
||||||
{
|
{
|
||||||
__sm_assert(capacity % SM_BITS_PER_VECTOR == 0);
|
__sm_assert(capacity % SM_BITS_PER_VECTOR == 0);
|
||||||
__sm_assert(capacity < SM_CHUNK_MAX_CAPACITY);
|
__sm_assert(capacity <= SM_CHUNK_MAX_CAPACITY);
|
||||||
|
|
||||||
if (capacity >= SM_CHUNK_MAX_CAPACITY) {
|
if (capacity >= SM_CHUNK_MAX_CAPACITY) {
|
||||||
return;
|
return;
|
||||||
|
@ -1251,7 +1251,7 @@ sparsemap_set(sparsemap_t *map, sparsemap_idx_t idx, bool value)
|
||||||
__sm_insert_data(map, offset, &buf[0], sizeof(buf));
|
__sm_insert_data(map, offset, &buf[0], sizeof(buf));
|
||||||
|
|
||||||
start += __sm_chunk_get_capacity(&chunk);
|
start += __sm_chunk_get_capacity(&chunk);
|
||||||
if ((sparsemap_idx_t)start + SM_CHUNK_MAX_CAPACITY < idx) {
|
if ((sparsemap_idx_t)start + SM_CHUNK_MAX_CAPACITY <= idx) {
|
||||||
start = __sm_get_chunk_aligned_offset(idx);
|
start = __sm_get_chunk_aligned_offset(idx);
|
||||||
}
|
}
|
||||||
*(sm_idx_t *)p = start;
|
*(sm_idx_t *)p = start;
|
||||||
|
@ -1610,7 +1610,7 @@ sparsemap_merge(sparsemap_t *destination, sparsemap_t *source)
|
||||||
sparsemap_idx_t
|
sparsemap_idx_t
|
||||||
sparsemap_split(sparsemap_t *map, sparsemap_idx_t offset, sparsemap_t *other)
|
sparsemap_split(sparsemap_t *map, sparsemap_idx_t offset, sparsemap_t *other)
|
||||||
{
|
{
|
||||||
if (offset == 0) {
|
if (!(offset == SPARSEMAP_IDX_MAX) && (offset < 0 || offset >= sparsemap_get_ending_offset(map))) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1631,10 +1631,6 @@ sparsemap_split(sparsemap_t *map, sparsemap_idx_t offset, sparsemap_t *other)
|
||||||
/* |src| points to the source-chunk */
|
/* |src| points to the source-chunk */
|
||||||
uint8_t *src = __sm_get_chunk_data(map, 0);
|
uint8_t *src = __sm_get_chunk_data(map, 0);
|
||||||
|
|
||||||
/* |offset| is relative to the beginning of this sparsemap_t; best
|
|
||||||
make it absolute. */
|
|
||||||
offset += *(sm_idx_t *)src;
|
|
||||||
|
|
||||||
bool in_middle = false;
|
bool in_middle = false;
|
||||||
uint8_t *prev = src;
|
uint8_t *prev = src;
|
||||||
size_t i, count = __sm_get_chunk_count(map);
|
size_t i, count = __sm_get_chunk_count(map);
|
||||||
|
@ -1688,14 +1684,17 @@ sparsemap_split(sparsemap_t *map, sparsemap_idx_t offset, sparsemap_t *other)
|
||||||
|
|
||||||
__sm_chunk_t d_chunk;
|
__sm_chunk_t d_chunk;
|
||||||
__sm_chunk_init(&d_chunk, dst);
|
__sm_chunk_init(&d_chunk, dst);
|
||||||
__sm_chunk_reduce_capacity(&d_chunk, capacity - (offset % capacity));
|
__sm_chunk_reduce_capacity(&d_chunk, __sm_get_vector_aligned_offset(capacity - (offset % capacity)));
|
||||||
|
|
||||||
/* Now copy the bits. */
|
/* Now copy the bits. */
|
||||||
sparsemap_idx_t d = offset;
|
sparsemap_idx_t d = offset;
|
||||||
|
sparsemap_idx_t b = __sm_get_vector_aligned_offset(offset % capacity);
|
||||||
for (size_t j = offset % capacity; j < capacity; j++, d++) {
|
for (size_t j = offset % capacity; j < capacity; j++, d++) {
|
||||||
if (__sm_chunk_is_set(&s_chunk, j)) {
|
if (__sm_chunk_is_set(&s_chunk, j)) {
|
||||||
sparsemap_set(other, d, true);
|
assert(sparsemap_set(other, d, true) == d);
|
||||||
sparsemap_set(map, d, false); // TODO remove, and fix reduce_capacity below
|
if (j > b && (j - b) % capacity < SM_BITS_PER_VECTOR) {
|
||||||
|
sparsemap_set(map, d, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1705,7 +1704,7 @@ sparsemap_split(sparsemap_t *map, sparsemap_idx_t offset, sparsemap_t *other)
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
/* Reduce the capacity of the source-chunk effectively erases bits. */
|
/* Reduce the capacity of the source-chunk effectively erases bits. */
|
||||||
// TODO: __sm_chunk_reduce_capacity(&s_chunk, offset % capacity);
|
__sm_chunk_reduce_capacity(&s_chunk, b + SM_BITS_PER_VECTOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now continue with all remaining chunks. */
|
/* Now continue with all remaining chunks. */
|
||||||
|
|
59
tests/test.c
59
tests/test.c
|
@ -720,35 +720,43 @@ test_api_split(const MunitParameter params[], void *data)
|
||||||
|
|
||||||
sparsemap_init(&portion, buf, 1024);
|
sparsemap_init(&portion, buf, 1024);
|
||||||
|
|
||||||
for (int i = 0; i < 1024; i++) {
|
for (sparsemap_idx_t off = 0; off < 1024; off++) {
|
||||||
sparsemap_set(map, i, true);
|
for (sparsemap_idx_t seg = 0; seg < 10 * 1024; seg += 1024) {
|
||||||
}
|
|
||||||
for (int i = 0; i < 1024; i++) {
|
for (sparsemap_idx_t i = 0; i < 1024; i++) {
|
||||||
assert_true(sparsemap_is_set(map, i));
|
assert_true(sparsemap_set(map, i + seg, true) == i + seg);
|
||||||
assert_false(sparsemap_is_set(&portion, i));
|
}
|
||||||
}
|
for (sparsemap_idx_t i = 0; i < 1024; i++) {
|
||||||
sparsemap_split(map, 512, &portion);
|
assert_true(sparsemap_is_set(map, i + seg));
|
||||||
for (int i = 0; i < 512; i++) {
|
assert_false(sparsemap_is_set(&portion, i + seg));
|
||||||
assert_true(sparsemap_is_set(map, i));
|
}
|
||||||
assert_false(sparsemap_is_set(&portion, i));
|
|
||||||
}
|
sparsemap_split(map, seg + off, &portion);
|
||||||
for (int i = 513; i < 1024; i++) {
|
|
||||||
assert_false(sparsemap_is_set(map, i));
|
for (sparsemap_idx_t i = 0; i < off; i++) {
|
||||||
assert_true(sparsemap_is_set(&portion, i));
|
assert_true(sparsemap_is_set(map, i + seg));
|
||||||
|
assert_false(sparsemap_is_set(&portion, i + seg));
|
||||||
|
}
|
||||||
|
for (sparsemap_idx_t i = off + 1; i < 1024; i++) {
|
||||||
|
assert_false(sparsemap_is_set(map, i + seg));
|
||||||
|
assert_true(sparsemap_is_set(&portion, i + seg));
|
||||||
|
}
|
||||||
|
|
||||||
|
sparsemap_clear(map);
|
||||||
|
sparsemap_clear(&portion);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sparsemap_clear(map);
|
for (sparsemap_idx_t i = 0; i < 100; i++) {
|
||||||
sparsemap_clear(&portion);
|
assert_true(sparsemap_set(map, i, true) == i);
|
||||||
|
|
||||||
for (int i = 0; i < 100; i++) {
|
|
||||||
sparsemap_set(map, i, true);
|
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 100; i++) {
|
for (sparsemap_idx_t i = 0; i < 100; i++) {
|
||||||
assert_true(sparsemap_is_set(map, i));
|
assert_true(sparsemap_is_set(map, i));
|
||||||
assert_false(sparsemap_is_set(&portion, i));
|
assert_false(sparsemap_is_set(&portion, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
sparsemap_idx_t offset = sparsemap_split(map, SPARSEMAP_IDX_MAX, &portion);
|
sparsemap_idx_t offset = sparsemap_split(map, SPARSEMAP_IDX_MAX, &portion);
|
||||||
|
|
||||||
for (size_t i = 0; i < offset; i++) {
|
for (size_t i = 0; i < offset; i++) {
|
||||||
assert_true(sparsemap_is_set(map, i));
|
assert_true(sparsemap_is_set(map, i));
|
||||||
assert_false(sparsemap_is_set(&portion, i));
|
assert_false(sparsemap_is_set(&portion, i));
|
||||||
|
@ -762,16 +770,17 @@ test_api_split(const MunitParameter params[], void *data)
|
||||||
sparsemap_clear(map);
|
sparsemap_clear(map);
|
||||||
|
|
||||||
sparsemap_init(&portion, buf, 1024);
|
sparsemap_init(&portion, buf, 1024);
|
||||||
for (int i = 0; i < 13; i++) {
|
for (sparsemap_idx_t i = 0; i < 13; i++) {
|
||||||
sparsemap_set(map, i + 24, true);
|
assert_true(sparsemap_set(map, i + 24, true) == i + 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = sparsemap_split(map, SPARSEMAP_IDX_MAX, &portion);
|
offset = sparsemap_split(map, SPARSEMAP_IDX_MAX, &portion);
|
||||||
for (size_t i = 0; i < offset - 24; i++) {
|
|
||||||
|
for (sparsemap_idx_t i = 0; i < offset - 24; i++) {
|
||||||
assert_true(sparsemap_is_set(map, i + 24));
|
assert_true(sparsemap_is_set(map, i + 24));
|
||||||
assert_false(sparsemap_is_set(&portion, i + 24));
|
assert_false(sparsemap_is_set(&portion, i + 24));
|
||||||
}
|
}
|
||||||
for (int i = offset - 24; i < 13; i++) {
|
for (sparsemap_idx_t i = offset - 24; i < 13; i++) {
|
||||||
assert_false(sparsemap_is_set(map, i + 24));
|
assert_false(sparsemap_is_set(map, i + 24));
|
||||||
assert_true(sparsemap_is_set(&portion, i + 24));
|
assert_true(sparsemap_is_set(&portion, i + 24));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue