2024-04-03 00:41:55 +00:00
|
|
|
#include <assert.h>
|
2024-04-24 20:32:09 +00:00
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdint.h>
|
2024-04-03 00:41:55 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
|
2024-07-16 10:20:28 +00:00
|
|
|
#include <sparsemap.h>
|
2024-04-04 19:58:06 +00:00
|
|
|
|
|
|
|
#pragma GCC diagnostic push
|
|
|
|
#pragma GCC diagnostic ignored "-Wvariadic-macros"
|
2024-04-05 14:34:59 +00:00
|
|
|
#define __diag(...) \
|
|
|
|
do { \
|
|
|
|
fprintf(stderr, "%s:%d:%s(): ", __FILE__, __LINE__, __func__); \
|
|
|
|
fprintf(stderr, __VA_ARGS__); \
|
|
|
|
} while (0)
|
2024-04-04 19:58:06 +00:00
|
|
|
#pragma GCC diagnostic pop
|
|
|
|
|
2024-04-10 19:34:19 +00:00
|
|
|
/* !!! Duplicated here for testing purposes. Keep in sync, or suffer. !!! */
|
|
|
|
struct sparsemap {
|
|
|
|
size_t m_capacity;
|
|
|
|
size_t m_data_used;
|
2024-04-24 20:32:09 +00:00
|
|
|
uint8_t *m_data;
|
2024-04-10 19:34:19 +00:00
|
|
|
};
|
|
|
|
|
2024-04-05 14:34:59 +00:00
|
|
|
int
|
|
|
|
main()
|
|
|
|
{
|
2024-04-04 23:56:31 +00:00
|
|
|
size_t size = 4;
|
2024-04-24 20:32:09 +00:00
|
|
|
setvbuf(stdout, NULL, _IONBF, 0); // Disable buffering for stdout
|
|
|
|
setvbuf(stderr, NULL, _IONBF, 0); // Disable buffering for stdout
|
|
|
|
|
2024-04-04 19:58:06 +00:00
|
|
|
__diag("Please wait a moment...");
|
2024-04-04 23:56:31 +00:00
|
|
|
sparsemap_t mmap, *map = &mmap;
|
2024-04-03 00:41:55 +00:00
|
|
|
uint8_t buffer[1024];
|
|
|
|
uint8_t buffer2[1024];
|
2024-04-10 19:34:19 +00:00
|
|
|
sparsemap_init(map, buffer, sizeof(buffer));
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_get_size(map) == size);
|
2024-07-29 09:31:55 +00:00
|
|
|
sparsemap_set(map, 0);
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_get_size(map) == size + 4 + 8 + 8);
|
|
|
|
assert(sparsemap_is_set(map, 0) == true);
|
|
|
|
assert(sparsemap_get_size(map) == size + 4 + 8 + 8);
|
|
|
|
assert(sparsemap_is_set(map, 1) == false);
|
2024-07-29 09:31:55 +00:00
|
|
|
sparsemap_unset(map, 0);
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_get_size(map) == size);
|
|
|
|
|
|
|
|
sparsemap_clear(map);
|
2024-07-29 09:31:55 +00:00
|
|
|
sparsemap_set(map, 64);
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_is_set(map, 64) == true);
|
|
|
|
assert(sparsemap_get_size(map) == size + 4 + 8 + 8);
|
|
|
|
|
|
|
|
sparsemap_clear(map);
|
2024-04-04 23:56:31 +00:00
|
|
|
fprintf(stderr, ".");
|
2024-04-03 00:41:55 +00:00
|
|
|
|
|
|
|
// set [0..100000]
|
|
|
|
for (int i = 0; i < 100000; i++) {
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_is_set(map, i) == false);
|
2024-07-29 09:31:55 +00:00
|
|
|
sparsemap_set(map, i);
|
2024-04-03 00:41:55 +00:00
|
|
|
if (i > 5) {
|
2024-04-04 19:58:06 +00:00
|
|
|
for (int j = i - 5; j <= i; j++) {
|
|
|
|
assert(sparsemap_is_set(map, j) == true);
|
|
|
|
}
|
2024-04-03 00:41:55 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_is_set(map, i) == true);
|
2024-04-03 00:41:55 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 23:56:31 +00:00
|
|
|
fprintf(stderr, ".");
|
2024-04-03 00:41:55 +00:00
|
|
|
|
2024-04-04 19:58:06 +00:00
|
|
|
for (int i = 0; i < 100000; i++) {
|
|
|
|
assert(sparsemap_is_set(map, i) == true);
|
|
|
|
}
|
2024-04-03 00:41:55 +00:00
|
|
|
|
|
|
|
// unset [0..10000]
|
|
|
|
for (int i = 0; i < 10000; i++) {
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_is_set(map, i) == true);
|
2024-07-29 09:31:55 +00:00
|
|
|
sparsemap_unset(map, i);
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_is_set(map, i) == false);
|
2024-04-03 00:41:55 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 19:58:06 +00:00
|
|
|
for (int i = 0; i < 10000; i++) {
|
|
|
|
assert(sparsemap_is_set(map, i) == false);
|
|
|
|
}
|
2024-04-03 00:41:55 +00:00
|
|
|
|
2024-04-04 19:58:06 +00:00
|
|
|
sparsemap_clear(map);
|
2024-04-04 23:56:31 +00:00
|
|
|
fprintf(stderr, ".");
|
2024-04-03 00:41:55 +00:00
|
|
|
|
|
|
|
// set [10000..0]
|
|
|
|
for (int i = 10000; i >= 0; i--) {
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_is_set(map, i) == false);
|
2024-07-29 09:31:55 +00:00
|
|
|
sparsemap_set(map, i);
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_is_set(map, i) == true);
|
2024-04-03 00:41:55 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 19:58:06 +00:00
|
|
|
for (int i = 10000; i >= 0; i--) {
|
|
|
|
assert(sparsemap_is_set(map, i) == true);
|
2024-04-04 23:56:31 +00:00
|
|
|
fprintf(stderr, ".");
|
2024-04-04 19:58:06 +00:00
|
|
|
}
|
2024-04-03 00:41:55 +00:00
|
|
|
|
|
|
|
// open and compare
|
2024-04-05 14:34:59 +00:00
|
|
|
sparsemap_t _sm3, *sm3 = &_sm3;
|
|
|
|
sparsemap_open(sm3, buffer, sizeof(buffer));
|
2024-04-04 19:58:06 +00:00
|
|
|
for (int i = 0; i < 10000; i++) {
|
2024-04-05 14:34:59 +00:00
|
|
|
assert(sparsemap_is_set(sm3, i) == sparsemap_is_set(map, i));
|
2024-04-04 19:58:06 +00:00
|
|
|
}
|
2024-04-03 00:41:55 +00:00
|
|
|
|
|
|
|
// unset [10000..0]
|
|
|
|
for (int i = 10000; i >= 0; i--) {
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_is_set(map, i) == true);
|
2024-07-29 09:31:55 +00:00
|
|
|
sparsemap_unset(map, i);
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_is_set(map, i) == false);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 10000; i >= 0; i--) {
|
|
|
|
assert(sparsemap_is_set(map, i) == false);
|
|
|
|
}
|
|
|
|
|
2024-04-04 23:56:31 +00:00
|
|
|
fprintf(stderr, ".");
|
2024-04-04 19:58:06 +00:00
|
|
|
sparsemap_clear(map);
|
|
|
|
|
2024-07-29 09:31:55 +00:00
|
|
|
sparsemap_set(map, 0);
|
|
|
|
sparsemap_set(map, 2048 * 2 + 1);
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_is_set(map, 0) == true);
|
|
|
|
assert(sparsemap_is_set(map, 2048 * 2 + 0) == false);
|
|
|
|
assert(sparsemap_is_set(map, 2048 * 2 + 1) == true);
|
|
|
|
assert(sparsemap_is_set(map, 2048 * 2 + 2) == false);
|
2024-07-29 09:31:55 +00:00
|
|
|
sparsemap_set(map, 2048);
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_is_set(map, 0) == true);
|
|
|
|
assert(sparsemap_is_set(map, 2047) == false);
|
|
|
|
assert(sparsemap_is_set(map, 2048) == true);
|
|
|
|
assert(sparsemap_is_set(map, 2049) == false);
|
|
|
|
assert(sparsemap_is_set(map, 2048 * 2 + 2) == false);
|
|
|
|
assert(sparsemap_is_set(map, 2048 * 2 + 0) == false);
|
|
|
|
assert(sparsemap_is_set(map, 2048 * 2 + 1) == true);
|
|
|
|
assert(sparsemap_is_set(map, 2048 * 2 + 2) == false);
|
|
|
|
|
|
|
|
sparsemap_clear(map);
|
2024-04-04 23:56:31 +00:00
|
|
|
fprintf(stderr, ".");
|
2024-04-04 19:58:06 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < 100000; i++) {
|
2024-07-29 09:31:55 +00:00
|
|
|
sparsemap_set(map, i);
|
2024-04-04 19:58:06 +00:00
|
|
|
}
|
|
|
|
for (int i = 0; i < 100000; i++) {
|
2024-04-24 20:32:09 +00:00
|
|
|
assert(sparsemap_select(map, i, true) == (unsigned)i);
|
2024-04-04 19:58:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sparsemap_clear(map);
|
2024-04-04 23:56:31 +00:00
|
|
|
fprintf(stderr, ".");
|
2024-04-04 19:58:06 +00:00
|
|
|
|
|
|
|
for (int i = 1; i < 513; i++) {
|
2024-07-29 09:31:55 +00:00
|
|
|
sparsemap_set(map, i);
|
2024-04-04 19:58:06 +00:00
|
|
|
}
|
|
|
|
for (int i = 1; i < 513; i++) {
|
2024-04-24 20:32:09 +00:00
|
|
|
assert(sparsemap_select(map, i - 1, true) == (unsigned)i);
|
2024-04-04 19:58:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sparsemap_clear(map);
|
2024-04-04 23:56:31 +00:00
|
|
|
fprintf(stderr, ".");
|
2024-04-04 19:58:06 +00:00
|
|
|
|
|
|
|
for (size_t i = 0; i < 8; i++) {
|
2024-07-29 09:31:55 +00:00
|
|
|
sparsemap_set(map, i * 10);
|
2024-04-04 19:58:06 +00:00
|
|
|
}
|
|
|
|
for (size_t i = 0; i < 8; i++) {
|
2024-04-24 20:32:09 +00:00
|
|
|
assert(sparsemap_select(map, i, true) == (sparsemap_idx_t)i * 10);
|
2024-04-04 19:58:06 +00:00
|
|
|
}
|
2024-04-03 00:41:55 +00:00
|
|
|
|
|
|
|
// split and move, aligned to MiniMap capacity
|
2024-04-05 14:34:59 +00:00
|
|
|
sparsemap_t _sm2, *sm2 = &_sm2;
|
2024-04-10 19:34:19 +00:00
|
|
|
sparsemap_init(sm2, buffer2, sizeof(buffer2));
|
2024-04-04 19:58:06 +00:00
|
|
|
sparsemap_clear(sm2);
|
|
|
|
for (int i = 0; i < 2048 * 2; i++) {
|
2024-07-29 09:31:55 +00:00
|
|
|
sparsemap_set(map, i);
|
2024-04-04 19:58:06 +00:00
|
|
|
}
|
|
|
|
sparsemap_split(map, 2048, sm2);
|
2024-04-03 00:41:55 +00:00
|
|
|
for (int i = 0; i < 2048; i++) {
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_is_set(map, i) == true);
|
|
|
|
assert(sparsemap_is_set(sm2, i) == false);
|
2024-04-03 00:41:55 +00:00
|
|
|
}
|
|
|
|
for (int i = 2048; i < 2048 * 2; i++) {
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_is_set(map, i) == false);
|
|
|
|
assert(sparsemap_is_set(sm2, i) == true);
|
2024-04-03 00:41:55 +00:00
|
|
|
}
|
2024-04-04 23:56:31 +00:00
|
|
|
fprintf(stderr, ".");
|
2024-04-03 00:41:55 +00:00
|
|
|
|
|
|
|
// split and move, aligned to BitVector capacity
|
2024-04-10 19:34:19 +00:00
|
|
|
sparsemap_init(sm2, buffer2, sizeof(buffer2));
|
2024-04-04 19:58:06 +00:00
|
|
|
sparsemap_clear(map);
|
|
|
|
for (int i = 0; i < 2048 * 3; i++) {
|
2024-07-29 09:31:55 +00:00
|
|
|
sparsemap_set(map, i);
|
2024-04-04 19:58:06 +00:00
|
|
|
assert(sparsemap_is_set(map, i) == true);
|
2024-04-03 00:41:55 +00:00
|
|
|
}
|
2024-05-16 16:00:09 +00:00
|
|
|
sparsemap_split(map, 64, sm2);
|
|
|
|
for (int i = 0; i < 2048 * 3; i++) {
|
|
|
|
if (i < 64) {
|
|
|
|
assert(sparsemap_is_set(map, i) == true);
|
|
|
|
assert(sparsemap_is_set(sm2, i) == false);
|
|
|
|
} else {
|
|
|
|
assert(sparsemap_is_set(map, i) == false);
|
|
|
|
assert(sparsemap_is_set(sm2, i) == true);
|
|
|
|
}
|
2024-04-03 00:41:55 +00:00
|
|
|
}
|
|
|
|
|
2024-04-04 23:56:31 +00:00
|
|
|
fprintf(stderr, " ok\n");
|
2024-04-05 14:34:59 +00:00
|
|
|
}
|