WIP
This commit is contained in:
parent
5e83f660ea
commit
d42126054f
7 changed files with 430 additions and 166 deletions
7
Makefile
7
Makefile
|
@ -5,11 +5,12 @@ SHARED_LIB = libsparsemap.so
|
||||||
|
|
||||||
#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 -DSPARSEMAP_ASSERT -Wall -Wextra -Wpedantic -Og -g -std=c11 -Iinclude/ -fPIC
|
#CFLAGS = -DSPARSEMAP_DIAGNOSTIC -DDEBUG -Wall -Wextra -Wpedantic -Og -g -std=c11 -Iinclude/ -fPIC
|
||||||
#CFLAGS = -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 = -Wall -Wextra -Wpedantic -Og -g -std=c11 -Iinclude/ -Itests/ -fPIC
|
#TEST_FLAGS = -DDEBUG -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
|
||||||
|
|
||||||
TESTS = tests/test
|
TESTS = tests/test
|
||||||
TEST_OBJS = tests/test.o tests/munit.o tests/tdigest.o tests/common.o
|
TEST_OBJS = tests/test.o tests/munit.o tests/tdigest.o tests/common.o
|
||||||
|
|
|
@ -160,7 +160,7 @@ main()
|
||||||
sparsemap_set(map, i * 10, true);
|
sparsemap_set(map, i * 10, true);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < 8; i++) {
|
for (size_t i = 0; i < 8; i++) {
|
||||||
assert(sparsemap_select(map, i, true) == (sm_loc_t)i * 10);
|
assert(sparsemap_select(map, i, true) == (sparsemap_idx_t)i * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
// split and move, aligned to MiniMap capacity
|
// split and move, aligned to MiniMap capacity
|
||||||
|
|
|
@ -88,9 +88,10 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct sparsemap sparsemap_t;
|
typedef struct sparsemap sparsemap_t;
|
||||||
typedef long sm_loc_t;
|
typedef long int sparsemap_idx_t;
|
||||||
#define SM_LOC_MAX LONG_MAX
|
#define SPARSEMAP_IDX_MAX ((1UL << (sizeof(long) * CHAR_BIT - 1)) - 1)
|
||||||
#define SM_LOC_MIN LONG_MIN
|
#define SPARSEMAP_IDX_MIN (-(SPARSEMAP_IDX_MAX)-1)
|
||||||
|
#define SPARSEMAP_NOT_FOUND(_x) ((_x) == SPARSEMAP_IDX_MAX || (_x) == SPARSEMAP_IDX_MIN)
|
||||||
typedef uint32_t sm_idx_t;
|
typedef uint32_t sm_idx_t;
|
||||||
typedef uint64_t sm_bitvec_t;
|
typedef uint64_t sm_bitvec_t;
|
||||||
|
|
||||||
|
@ -123,9 +124,12 @@ void sparsemap_open(sparsemap_t *, uint8_t *data, size_t data_size);
|
||||||
void sparsemap_clear(sparsemap_t *map);
|
void sparsemap_clear(sparsemap_t *map);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resizes the data range within the limits of the provided buffer.
|
* Resizes the data range within the limits of the provided buffer, the map may
|
||||||
|
* move to a new address returned iff the map was created with the sparsemap() API.
|
||||||
|
* Take care to use the new reference (think: realloc()). NOTE: If the returned
|
||||||
|
* value equals NULL then the map was not resized.
|
||||||
*/
|
*/
|
||||||
void sparsemap_set_data_size(sparsemap_t *map, size_t data_size);
|
sparsemap_t *sparsemap_set_data_size(sparsemap_t *map, size_t data_size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate remaining capacity, approaches 0 when full.
|
* Calculate remaining capacity, approaches 0 when full.
|
||||||
|
@ -141,13 +145,14 @@ size_t sparsemap_get_capacity(sparsemap_t *map);
|
||||||
* Returns the value of a bit at index |idx|, either on/true/1 or off/false/0.
|
* Returns the value of a bit at index |idx|, either on/true/1 or off/false/0.
|
||||||
* When |idx| is negative it is an error.
|
* When |idx| is negative it is an error.
|
||||||
*/
|
*/
|
||||||
bool sparsemap_is_set(sparsemap_t *map, sm_loc_t idx);
|
bool sparsemap_is_set(sparsemap_t *map, sparsemap_idx_t idx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the bit at index |idx| to true or false, depending on |value|.
|
* Sets the bit at index |idx| to true or false, depending on |value|.
|
||||||
* When |idx| is negative is it an error.
|
* When |idx| is negative is it an error. Returns the |idx| supplied or
|
||||||
|
* SPARSEMAP_IDX_MAX on error with |errno| set to ENOSP when the map is full.
|
||||||
*/
|
*/
|
||||||
void sparsemap_set(sparsemap_t *map, sm_loc_t idx, bool value);
|
sparsemap_idx_t sparsemap_set(sparsemap_t *map, sparsemap_idx_t idx, bool value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the offset of the very first/last bit in the map.
|
* Returns the offset of the very first/last bit in the map.
|
||||||
|
@ -171,15 +176,15 @@ void sparsemap_scan(sparsemap_t *map, void (*scanner)(sm_idx_t vec[], size_t n),
|
||||||
* Appends all chunk maps from |map| starting at |offset| to |other|, then
|
* Appends all chunk maps from |map| starting at |offset| to |other|, then
|
||||||
* reduces the chunk map-count appropriately.
|
* reduces the chunk map-count appropriately.
|
||||||
*/
|
*/
|
||||||
void sparsemap_split(sparsemap_t *map, sm_loc_t offset, sparsemap_t *other);
|
void sparsemap_split(sparsemap_t *map, sparsemap_idx_t offset, sparsemap_t *other);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the offset of the n'th bit either set (|value| is true) or unset
|
* Finds the offset of the n'th bit either set (|value| is true) or unset
|
||||||
* (|value| is false) from the start (positive |n|), or end (negative |n|),
|
* (|value| is false) from the start (positive |n|), or end (negative |n|),
|
||||||
* of the bitmap and returns that (uses a 0-based index). Returns -inf or +inf
|
* of the bitmap and returns that (uses a 0-based index). Returns -inf or +inf
|
||||||
* if not found (where "inf" is SM_LOC_MAX and "-inf" is SM_LOC_MIN).
|
* if not found (where "inf" is SPARSEMAP_IDX_MAX and "-inf" is SPARSEMAP_IDX_MIN).
|
||||||
*/
|
*/
|
||||||
sm_loc_t sparsemap_select(sparsemap_t *map, sm_loc_t n, bool value);
|
sparsemap_idx_t sparsemap_select(sparsemap_t *map, sparsemap_idx_t n, bool value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Counts the set (|value| is true) or unset (|value| is false) bits starting
|
* Counts the set (|value| is true) or unset (|value| is false) bits starting
|
||||||
|
@ -192,7 +197,7 @@ size_t sparsemap_rank(sparsemap_t *map, size_t x, size_t y, bool value);
|
||||||
* are set (|value| is true) or unset (|value| is false) and returns the
|
* are set (|value| is true) or unset (|value| is false) and returns the
|
||||||
* starting offset for the span (0-based).
|
* starting offset for the span (0-based).
|
||||||
*/
|
*/
|
||||||
size_t sparsemap_span(sparsemap_t *map, sm_loc_t idx, size_t len, bool value);
|
size_t sparsemap_span(sparsemap_t *map, sparsemap_idx_t idx, size_t len, bool value);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
|
151
src/sparsemap.c
151
src/sparsemap.c
|
@ -23,14 +23,15 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <popcount.h>
|
#include <popcount.h>
|
||||||
#include <sparsemap.h>
|
#include <sparsemap.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef SPARSEMAP_DIAGNOSTIC
|
#ifdef SPARSEMAP_DIAGNOSTIC
|
||||||
|
@ -48,19 +49,24 @@ void __attribute__((format(printf, 4, 5))) __sm_diag_(const char *file, int line
|
||||||
vfprintf(stderr, format, args);
|
vfprintf(stderr, format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#define __sm_diag(file, line, func, format, ...) ((void)0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SPARSEMAP_ASSERT
|
|
||||||
#define SPARSEMAP_ASSERT
|
|
||||||
#define __sm_assert(expr) \
|
#define __sm_assert(expr) \
|
||||||
if (!(expr)) \
|
if (!(expr)) \
|
||||||
fprintf(stderr, "%s:%d:%s(): assertion failed! %s", __FILE__, __LINE__, __func__, #expr)
|
fprintf(stderr, "%s:%d:%s(): assertion failed! %s", __FILE__, __LINE__, __func__, #expr)
|
||||||
|
|
||||||
|
#define __sm_when_diag(expr) \
|
||||||
|
if (1) \
|
||||||
|
expr
|
||||||
#else
|
#else
|
||||||
|
#define __sm_diag(file, line, func, format, ...) ((void)0)
|
||||||
#define __sm_assert(expr) ((void)0)
|
#define __sm_assert(expr) ((void)0)
|
||||||
|
#define __sm_when_diag(expr) \
|
||||||
|
if (0) \
|
||||||
|
expr
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define IS_8_BYTE_ALIGNED(addr) (((uintptr_t)(addr) & 0x7) == 0)
|
||||||
|
|
||||||
enum __SM_CHUNK_INFO {
|
enum __SM_CHUNK_INFO {
|
||||||
/* metadata overhead: 4 bytes for __sm_chunk_t count */
|
/* metadata overhead: 4 bytes for __sm_chunk_t count */
|
||||||
SM_SIZEOF_OVERHEAD = sizeof(uint32_t),
|
SM_SIZEOF_OVERHEAD = sizeof(uint32_t),
|
||||||
|
@ -398,7 +404,6 @@ __sm_chunk_map_select(__sm_chunk_t *map, size_t n, ssize_t *pnew_n, bool value)
|
||||||
{
|
{
|
||||||
size_t ret = 0;
|
size_t ret = 0;
|
||||||
register uint8_t *p;
|
register uint8_t *p;
|
||||||
(void)value; // TODO
|
|
||||||
|
|
||||||
p = (uint8_t *)map->m_data;
|
p = (uint8_t *)map->m_data;
|
||||||
for (size_t i = 0; i < sizeof(sm_bitvec_t); i++, p++) {
|
for (size_t i = 0; i < sizeof(sm_bitvec_t); i++, p++) {
|
||||||
|
@ -413,22 +418,37 @@ __sm_chunk_map_select(__sm_chunk_t *map, size_t n, ssize_t *pnew_n, bool value)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (flags == SM_PAYLOAD_ZEROS) {
|
if (flags == SM_PAYLOAD_ZEROS) {
|
||||||
|
if (value) {
|
||||||
ret += SM_BITS_PER_VECTOR;
|
ret += SM_BITS_PER_VECTOR;
|
||||||
continue;
|
continue;
|
||||||
}
|
} else {
|
||||||
if (flags == SM_PAYLOAD_ONES) {
|
|
||||||
if (n > SM_BITS_PER_VECTOR) {
|
if (n > SM_BITS_PER_VECTOR) {
|
||||||
n -= SM_BITS_PER_VECTOR;
|
n -= SM_BITS_PER_VECTOR;
|
||||||
ret += SM_BITS_PER_VECTOR;
|
ret += SM_BITS_PER_VECTOR;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
*pnew_n = -1;
|
*pnew_n = -1;
|
||||||
return (ret + n);
|
return (ret + n);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (flags == SM_PAYLOAD_ONES) {
|
||||||
|
if (value) {
|
||||||
|
if (n > SM_BITS_PER_VECTOR) {
|
||||||
|
n -= SM_BITS_PER_VECTOR;
|
||||||
|
ret += SM_BITS_PER_VECTOR;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*pnew_n = -1;
|
||||||
|
return (ret + n);
|
||||||
|
} else {
|
||||||
|
ret += SM_BITS_PER_VECTOR;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (flags == SM_PAYLOAD_MIXED) {
|
if (flags == SM_PAYLOAD_MIXED) {
|
||||||
sm_bitvec_t w = map->m_data[1 + __sm_chunk_map_get_position(map, i * SM_FLAGS_PER_INDEX_BYTE + j)];
|
sm_bitvec_t w = map->m_data[1 + __sm_chunk_map_get_position(map, i * SM_FLAGS_PER_INDEX_BYTE + j)];
|
||||||
for (int k = 0; k < SM_BITS_PER_VECTOR; k++) {
|
for (int k = 0; k < SM_BITS_PER_VECTOR; k++) {
|
||||||
|
if (value) {
|
||||||
if (w & ((sm_bitvec_t)1 << k)) {
|
if (w & ((sm_bitvec_t)1 << k)) {
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
*pnew_n = -1;
|
*pnew_n = -1;
|
||||||
|
@ -437,11 +457,20 @@ __sm_chunk_map_select(__sm_chunk_t *map, size_t n, ssize_t *pnew_n, bool value)
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
ret++;
|
ret++;
|
||||||
|
} else {
|
||||||
|
if (!(w & ((sm_bitvec_t)1 << k))) {
|
||||||
|
if (n == 0) {
|
||||||
|
*pnew_n = -1;
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*pnew_n = (ssize_t)n;
|
*pnew_n = (ssize_t)n;
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -659,7 +688,7 @@ __sm_get_aligned_offset(size_t idx)
|
||||||
* Returns the byte offset of a __sm_chunk_t in m_data.
|
* Returns the byte offset of a __sm_chunk_t in m_data.
|
||||||
*/
|
*/
|
||||||
static ssize_t
|
static ssize_t
|
||||||
__sm_get_chunk_map_offset(sparsemap_t *map, sm_loc_t idx)
|
__sm_get_chunk_map_offset(sparsemap_t *map, sparsemap_idx_t idx)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
|
@ -672,9 +701,9 @@ __sm_get_chunk_map_offset(sparsemap_t *map, sm_loc_t idx)
|
||||||
uint8_t *start = __sm_get_chunk_map_data(map, 0);
|
uint8_t *start = __sm_get_chunk_map_data(map, 0);
|
||||||
uint8_t *p = start;
|
uint8_t *p = start;
|
||||||
|
|
||||||
for (sm_loc_t i = 0; i < count - 1; i++) {
|
for (sparsemap_idx_t i = 0; i < count - 1; i++) {
|
||||||
sm_idx_t s = *(sm_idx_t *)p;
|
sm_idx_t s = *(sm_idx_t *)p;
|
||||||
__sm_assert(s == __sm_get_aligned_offset(start));
|
__sm_assert(s == __sm_get_aligned_offset(s));
|
||||||
__sm_chunk_t chunk;
|
__sm_chunk_t chunk;
|
||||||
__sm_chunk_map_init(&chunk, p + sizeof(sm_idx_t));
|
__sm_chunk_map_init(&chunk, p + sizeof(sm_idx_t));
|
||||||
if (s >= idx || (unsigned long)idx < s + __sm_chunk_map_get_capacity(&chunk)) {
|
if (s >= idx || (unsigned long)idx < s + __sm_chunk_map_get_capacity(&chunk)) {
|
||||||
|
@ -688,9 +717,9 @@ __sm_get_chunk_map_offset(sparsemap_t *map, sm_loc_t idx)
|
||||||
uint8_t *end = __sm_get_chunk_map_data(map, count - 1);
|
uint8_t *end = __sm_get_chunk_map_data(map, count - 1);
|
||||||
uint8_t *p = end;
|
uint8_t *p = end;
|
||||||
|
|
||||||
for (sm_loc_t i = count - 1; i >= 0; i--) {
|
for (sparsemap_idx_t i = count - 1; i >= 0; i--) {
|
||||||
sm_idx_t e = *(sm_idx_t *)p;
|
sm_idx_t e = *(sm_idx_t *)p;
|
||||||
__sm_assert(e == __sm_get_aligned_offset(end));
|
__sm_assert(e == __sm_get_aligned_offset(e));
|
||||||
__sm_chunk_t chunk;
|
__sm_chunk_t chunk;
|
||||||
__sm_chunk_map_init(&chunk, p + sizeof(sm_idx_t));
|
__sm_chunk_map_init(&chunk, p + sizeof(sm_idx_t));
|
||||||
if (e >= idx || (unsigned long)idx < e + __sm_chunk_map_get_capacity(&chunk)) {
|
if (e >= idx || (unsigned long)idx < e + __sm_chunk_map_get_capacity(&chunk)) {
|
||||||
|
@ -779,10 +808,21 @@ sparsemap(size_t size)
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
size = 1024;
|
size = 1024;
|
||||||
}
|
}
|
||||||
sparsemap_t *map = (sparsemap_t *)calloc(1, sizeof(sparsemap_t) + (size * sizeof(uint8_t)));
|
|
||||||
|
size_t data_size = (size * sizeof(uint8_t));
|
||||||
|
|
||||||
|
/* Ensure that m_data is 8-byte aligned. */
|
||||||
|
size_t total_size = sizeof(sparsemap_t) + data_size;
|
||||||
|
size_t padding = total_size % 8 == 0 ? 0 : 8 - (total_size % 8);
|
||||||
|
total_size += padding;
|
||||||
|
|
||||||
|
sparsemap_t *map = (sparsemap_t *)calloc(1, total_size);
|
||||||
if (map) {
|
if (map) {
|
||||||
sparsemap_init(map, (uint8_t *)map + sizeof(sparsemap_t), size);
|
sparsemap_init(map, (uint8_t *)((uintptr_t)map + sizeof(sparsemap_t) + padding), size);
|
||||||
|
__sm_when_diag({ __sm_assert(IS_8_BYTE_ALIGNED(map->m_data)); });
|
||||||
}
|
}
|
||||||
|
sparsemap_clear(map);
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,7 +841,7 @@ sparsemap_init(sparsemap_t *map, uint8_t *data, size_t size)
|
||||||
{
|
{
|
||||||
map->m_data = data;
|
map->m_data = data;
|
||||||
map->m_data_used = 0;
|
map->m_data_used = 0;
|
||||||
map->m_capacity = size == 0 ? UINT64_MAX : size;
|
map->m_capacity = size;
|
||||||
sparsemap_clear(map);
|
sparsemap_clear(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -809,7 +849,7 @@ void
|
||||||
sparsemap_open(sparsemap_t *map, uint8_t *data, size_t data_size)
|
sparsemap_open(sparsemap_t *map, uint8_t *data, size_t data_size)
|
||||||
{
|
{
|
||||||
map->m_data = data;
|
map->m_data = data;
|
||||||
map->m_data_used = 0;
|
map->m_data_used = map->m_data_used > 0 ? map->m_data_used : 0;
|
||||||
map->m_capacity = data_size;
|
map->m_capacity = data_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -817,10 +857,30 @@ sparsemap_open(sparsemap_t *map, uint8_t *data, size_t data_size)
|
||||||
* TODO/NOTE: This is a dangerous operation because we cannot verify that
|
* TODO/NOTE: This is a dangerous operation because we cannot verify that
|
||||||
* data_size is not exceeding the size of the underlying buffer.
|
* data_size is not exceeding the size of the underlying buffer.
|
||||||
*/
|
*/
|
||||||
void
|
sparsemap_t *
|
||||||
sparsemap_set_data_size(sparsemap_t *map, size_t data_size)
|
sparsemap_set_data_size(sparsemap_t *map, size_t size)
|
||||||
{
|
{
|
||||||
map->m_capacity = data_size;
|
if ((uintptr_t)map->m_data == (uintptr_t)map + sizeof(sparsemap_t) && size > map->m_capacity) {
|
||||||
|
/* This sparsemap was allocated by the sparsemap() API, we can resize it. */
|
||||||
|
size_t data_size = (size * sizeof(uint8_t));
|
||||||
|
|
||||||
|
/* Ensure that m_data is 8-byte aligned. */
|
||||||
|
size_t total_size = sizeof(sparsemap_t) + data_size;
|
||||||
|
size_t padding = total_size % 8 == 0 ? 0 : 8 - (total_size % 8);
|
||||||
|
total_size += padding;
|
||||||
|
|
||||||
|
sparsemap_t *m = (sparsemap_t *)realloc(map, total_size);
|
||||||
|
if (!m) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(m + sizeof(sparsemap_t) + (m->m_capacity * sizeof(uint8_t)), 0, total_size - m->m_capacity - padding);
|
||||||
|
m->m_capacity = data_size;
|
||||||
|
m->m_data = (uint8_t *)((uintptr_t)m + sizeof(sparsemap_t) + padding);
|
||||||
|
__sm_when_diag({ __sm_assert(IS_8_BYTE_ALIGNED(m->m_data)); }) return m;
|
||||||
|
} else {
|
||||||
|
map->m_capacity = size;
|
||||||
|
return map;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
|
@ -842,7 +902,7 @@ sparsemap_get_capacity(sparsemap_t *map)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sparsemap_is_set(sparsemap_t *map, sm_loc_t idx)
|
sparsemap_is_set(sparsemap_t *map, sparsemap_idx_t idx)
|
||||||
{
|
{
|
||||||
__sm_assert(sparsemap_get_size(map) >= SM_SIZEOF_OVERHEAD);
|
__sm_assert(sparsemap_get_size(map) >= SM_SIZEOF_OVERHEAD);
|
||||||
|
|
||||||
|
@ -874,15 +934,11 @@ sparsemap_is_set(sparsemap_t *map, sm_loc_t idx)
|
||||||
return (__sm_chunk_map_is_set(&chunk, idx - start));
|
return (__sm_chunk_map_is_set(&chunk, idx - start));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
sparsemap_idx_t
|
||||||
sparsemap_set(sparsemap_t *map, sm_loc_t idx, bool value)
|
sparsemap_set(sparsemap_t *map, sparsemap_idx_t idx, bool value)
|
||||||
{
|
{
|
||||||
__sm_assert(sparsemap_get_size(map) >= SM_SIZEOF_OVERHEAD);
|
__sm_assert(sparsemap_get_size(map) >= SM_SIZEOF_OVERHEAD);
|
||||||
|
|
||||||
if (idx < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the __sm_chunk_t which manages this index */
|
/* Get the __sm_chunk_t which manages this index */
|
||||||
ssize_t offset = __sm_get_chunk_map_offset(map, idx);
|
ssize_t offset = __sm_get_chunk_map_offset(map, idx);
|
||||||
bool dont_grow = false;
|
bool dont_grow = false;
|
||||||
|
@ -891,7 +947,7 @@ sparsemap_set(sparsemap_t *map, sm_loc_t idx, bool value)
|
||||||
immediately; otherwise create an initial __sm_chunk_t. */
|
immediately; otherwise create an initial __sm_chunk_t. */
|
||||||
if (offset == -1) {
|
if (offset == -1) {
|
||||||
if (value == false) {
|
if (value == false) {
|
||||||
return;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t buf[sizeof(sm_idx_t) + sizeof(sm_bitvec_t) * 2] = { 0 };
|
uint8_t buf[sizeof(sm_idx_t) + sizeof(sm_bitvec_t) * 2] = { 0 };
|
||||||
|
@ -917,7 +973,7 @@ sparsemap_set(sparsemap_t *map, sm_loc_t idx, bool value)
|
||||||
if (idx < start) {
|
if (idx < start) {
|
||||||
if (value == false) {
|
if (value == false) {
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
return;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t buf[sizeof(sm_idx_t) + sizeof(sm_bitvec_t) * 2] = { 0 };
|
uint8_t buf[sizeof(sm_idx_t) + sizeof(sm_bitvec_t) * 2] = { 0 };
|
||||||
|
@ -944,10 +1000,10 @@ sparsemap_set(sparsemap_t *map, sm_loc_t idx, bool value)
|
||||||
else {
|
else {
|
||||||
__sm_chunk_t chunk;
|
__sm_chunk_t chunk;
|
||||||
__sm_chunk_map_init(&chunk, p + sizeof(sm_idx_t));
|
__sm_chunk_map_init(&chunk, p + sizeof(sm_idx_t));
|
||||||
if (idx - (unsigned long)start >= __sm_chunk_map_get_capacity(&chunk)) {
|
if (idx - start >= (sparsemap_idx_t)__sm_chunk_map_get_capacity(&chunk)) {
|
||||||
if (value == false) {
|
if (value == false) {
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
return;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size = __sm_chunk_map_get_size(&chunk);
|
size_t size = __sm_chunk_map_get_size(&chunk);
|
||||||
|
@ -958,7 +1014,7 @@ sparsemap_set(sparsemap_t *map, sm_loc_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_map_get_capacity(&chunk);
|
start += __sm_chunk_map_get_capacity(&chunk);
|
||||||
if ((size_t)start + SM_CHUNK_MAX_CAPACITY < (unsigned long)idx) {
|
if ((sparsemap_idx_t)start + SM_CHUNK_MAX_CAPACITY < idx) {
|
||||||
start = __sm_get_fully_aligned_offset(idx);
|
start = __sm_get_fully_aligned_offset(idx);
|
||||||
}
|
}
|
||||||
*(sm_idx_t *)p = start;
|
*(sm_idx_t *)p = start;
|
||||||
|
@ -1009,6 +1065,7 @@ sparsemap_set(sparsemap_t *map, sm_loc_t idx, bool value)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
__sm_assert(sparsemap_get_size(map) >= SM_SIZEOF_OVERHEAD);
|
__sm_assert(sparsemap_get_size(map) >= SM_SIZEOF_OVERHEAD);
|
||||||
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
sm_idx_t
|
sm_idx_t
|
||||||
|
@ -1059,7 +1116,7 @@ sparsemap_scan(sparsemap_t *map, void (*scanner)(sm_idx_t[], size_t), size_t ski
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sparsemap_split(sparsemap_t *map, sm_loc_t offset, sparsemap_t *other)
|
sparsemap_split(sparsemap_t *map, sparsemap_idx_t offset, sparsemap_t *other)
|
||||||
{
|
{
|
||||||
assert(offset % SM_BITS_PER_VECTOR == 0);
|
assert(offset % SM_BITS_PER_VECTOR == 0);
|
||||||
|
|
||||||
|
@ -1132,7 +1189,7 @@ sparsemap_split(sparsemap_t *map, sm_loc_t offset, sparsemap_t *other)
|
||||||
__sm_chunk_map_set_capacity(&d_chunk, capacity - (offset % capacity));
|
__sm_chunk_map_set_capacity(&d_chunk, capacity - (offset % capacity));
|
||||||
|
|
||||||
/* Now copy the bits. */
|
/* Now copy the bits. */
|
||||||
sm_loc_t d = offset;
|
sparsemap_idx_t d = offset;
|
||||||
for (size_t j = offset % capacity; j < capacity; j++, d++) {
|
for (size_t j = offset % capacity; j < capacity; j++, d++) {
|
||||||
if (__sm_chunk_map_is_set(&s_chunk, j)) {
|
if (__sm_chunk_map_is_set(&s_chunk, j)) {
|
||||||
sparsemap_set(other, d, true);
|
sparsemap_set(other, d, true);
|
||||||
|
@ -1177,8 +1234,8 @@ sparsemap_split(sparsemap_t *map, sm_loc_t offset, sparsemap_t *other)
|
||||||
assert(sparsemap_get_size(other) > SM_SIZEOF_OVERHEAD);
|
assert(sparsemap_get_size(other) > SM_SIZEOF_OVERHEAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
sm_loc_t
|
sparsemap_idx_t
|
||||||
sparsemap_select(sparsemap_t *map, sm_loc_t n, bool value)
|
sparsemap_select(sparsemap_t *map, sparsemap_idx_t n, bool value)
|
||||||
{
|
{
|
||||||
assert(sparsemap_get_size(map) >= SM_SIZEOF_OVERHEAD);
|
assert(sparsemap_get_size(map) >= SM_SIZEOF_OVERHEAD);
|
||||||
size_t result;
|
size_t result;
|
||||||
|
@ -1204,16 +1261,16 @@ sparsemap_select(sparsemap_t *map, sm_loc_t n, bool value)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
assert(!"shouldn't be here");
|
assert(!"shouldn't be here");
|
||||||
#endif
|
#endif
|
||||||
return SM_LOC_MAX;
|
return SPARSEMAP_IDX_MAX;
|
||||||
} else {
|
} else {
|
||||||
return SM_LOC_MIN; // TODO... sparsemap_select(map, -n, value);
|
return SPARSEMAP_IDX_MIN; // TODO... sparsemap_select(map, -n, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
sparsemap_rank_vec(sparsemap_t *map, size_t x, size_t y, bool value, sm_bitvec_t *vec)
|
sparsemap_rank_vec(sparsemap_t *map, size_t x, size_t y, bool value, sm_bitvec_t *vec)
|
||||||
{
|
{
|
||||||
(void)value; //TODO
|
(void)value; // TODO
|
||||||
assert(sparsemap_get_size(map) >= SM_SIZEOF_OVERHEAD);
|
assert(sparsemap_get_size(map) >= SM_SIZEOF_OVERHEAD);
|
||||||
size_t result = 0, prev = 0, count = __sm_get_chunk_map_count(map);
|
size_t result = 0, prev = 0, count = __sm_get_chunk_map_count(map);
|
||||||
uint8_t *p = __sm_get_chunk_map_data(map, 0);
|
uint8_t *p = __sm_get_chunk_map_data(map, 0);
|
||||||
|
@ -1244,11 +1301,11 @@ sparsemap_rank(sparsemap_t *map, size_t x, size_t y, bool value)
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
sparsemap_span(sparsemap_t *map, sm_loc_t idx, size_t len, bool value)
|
sparsemap_span(sparsemap_t *map, sparsemap_idx_t idx, size_t len, bool value)
|
||||||
{
|
{
|
||||||
size_t count, nth = 0;
|
size_t count, nth = 0;
|
||||||
sm_bitvec_t vec = 0;
|
sm_bitvec_t vec = 0;
|
||||||
sm_loc_t offset;
|
sparsemap_idx_t offset;
|
||||||
|
|
||||||
offset = sparsemap_select(map, nth++, value);
|
offset = sparsemap_select(map, nth++, value);
|
||||||
if (len == 1) {
|
if (len == 1) {
|
||||||
|
@ -1269,7 +1326,7 @@ sparsemap_span(sparsemap_t *map, sm_loc_t idx, size_t len, bool value)
|
||||||
nth++;
|
nth++;
|
||||||
/* Use select to potentially jump very far forward in the map. */
|
/* Use select to potentially jump very far forward in the map. */
|
||||||
offset = sparsemap_select(map, nth, value);
|
offset = sparsemap_select(map, nth, value);
|
||||||
} while (offset != SM_LOC_MAX);
|
} while (offset != SPARSEMAP_IDX_MAX);
|
||||||
|
|
||||||
return idx > 0 ? SM_LOC_MAX : SM_LOC_MIN;
|
return idx >= 0 ? SPARSEMAP_IDX_MAX : SPARSEMAP_IDX_MIN;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#ifdef X86_INTRIN
|
#ifdef X86_INTRIN
|
||||||
|
#include <errno.h>
|
||||||
#include <x86intrin.h>
|
#include <x86intrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -146,25 +147,25 @@ ensure_sequential_set(int a[], int l, int r)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
sparsemap_idx_t
|
||||||
create_sequential_set_in_empty_map(sparsemap_t *map, int s, int r)
|
sm_add_span(sparsemap_t *map, int map_size, int span_length)
|
||||||
{
|
{
|
||||||
|
int attempts = map_size / span_length;
|
||||||
|
sparsemap_idx_t placed_at;
|
||||||
do {
|
do {
|
||||||
int placed_at;
|
placed_at = random_uint32() % (map_size - span_length - 1);
|
||||||
if (s >= r + 1) {
|
if (sm_occupied(map, placed_at, span_length, true)) {
|
||||||
placed_at = 0;
|
attempts--;
|
||||||
} else {
|
} else {
|
||||||
placed_at = random_uint32() % (s - r - 1);
|
break;
|
||||||
}
|
}
|
||||||
for (int i = placed_at; i < placed_at + r; i++) {
|
} while (attempts);
|
||||||
sparsemap_is_set(map, i);
|
for (int i = placed_at; i < placed_at + span_length; i++) {
|
||||||
continue;
|
if (sparsemap_set(map, i, true) != i) {
|
||||||
|
return placed_at; // TODO error?
|
||||||
}
|
}
|
||||||
for (int i = placed_at; i < placed_at + r; i++) {
|
|
||||||
sparsemap_set(map, i, true);
|
|
||||||
}
|
}
|
||||||
return placed_at;
|
return placed_at;
|
||||||
} while (true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -318,10 +319,10 @@ bitmap_from_uint32(sparsemap_t *map, uint32_t number)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bitmap_from_uint64(sparsemap_t *map, uint64_t number)
|
sm_bitmap_from_uint64(sparsemap_t *map, uint64_t number)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 64; i++) {
|
for (int i = 0; i < 64; i++) {
|
||||||
bool bit = number & (1 << i);
|
bool bit = number & ((uint64_t)1 << i);
|
||||||
sparsemap_set(map, i, bit);
|
sparsemap_set(map, i, bit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -368,7 +369,7 @@ whats_set_uint64(uint64_t number, int pos[64])
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
whats_set(sparsemap_t *map, int m)
|
sm_whats_set(sparsemap_t *map, int m)
|
||||||
{
|
{
|
||||||
logf("what's set in the range [0, %d): ", m);
|
logf("what's set in the range [0, %d): ", m);
|
||||||
for (int i = 0; i < m; i++) {
|
for (int i = 0; i < m; i++) {
|
||||||
|
@ -378,3 +379,25 @@ whats_set(sparsemap_t *map, int m)
|
||||||
}
|
}
|
||||||
logf("\n");
|
logf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
sm_is_span(sparsemap_t *map, sparsemap_idx_t m, size_t len, bool value)
|
||||||
|
{
|
||||||
|
for (sparsemap_idx_t i = m; i < (sparsemap_idx_t)len; i++) {
|
||||||
|
if (sparsemap_is_set(map, i) != value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
sm_occupied(sparsemap_t *map, sparsemap_idx_t m, size_t len, bool value)
|
||||||
|
{
|
||||||
|
for (sparsemap_idx_t i = m; i < (sparsemap_idx_t)len; i++) {
|
||||||
|
if (sparsemap_is_set(map, i) == value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -41,11 +41,14 @@ int is_unique(int a[], int l, int value);
|
||||||
void setup_test_array(int a[], int l, int max_value);
|
void setup_test_array(int a[], int l, int max_value);
|
||||||
void shuffle(int *array, size_t n);
|
void shuffle(int *array, size_t n);
|
||||||
int ensure_sequential_set(int a[], int l, int r);
|
int ensure_sequential_set(int a[], int l, int r);
|
||||||
int create_sequential_set_in_empty_map(sparsemap_t *map, int s, int r);
|
sparsemap_idx_t sm_add_span(sparsemap_t *map, int map_size, int span_length);
|
||||||
|
|
||||||
void bitmap_from_uint32(sparsemap_t *map, uint32_t number);
|
void bitmap_from_uint32(sparsemap_t *map, uint32_t number);
|
||||||
void bitmap_from_uint64(sparsemap_t *map, uint64_t number);
|
void sm_bitmap_from_uint64(sparsemap_t *map, uint64_t number);
|
||||||
uint32_t rank_uint64(uint64_t number, int n, int p);
|
uint32_t rank_uint64(uint64_t number, int n, int p);
|
||||||
int whats_set_uint64(uint64_t number, int bitPositions[64]);
|
int whats_set_uint64(uint64_t number, int bitPositions[64]);
|
||||||
|
|
||||||
void whats_set(sparsemap_t *map, int m);
|
void sm_whats_set(sparsemap_t *map, int m);
|
||||||
|
|
||||||
|
bool sm_is_span(sparsemap_t *map, sparsemap_idx_t m, size_t len, bool value);
|
||||||
|
bool sm_occupied(sparsemap_t *map, sparsemap_idx_t m, size_t len, bool value);
|
||||||
|
|
291
tests/test.c
291
tests/test.c
|
@ -10,6 +10,7 @@
|
||||||
#define MUNIT_NO_FORK (1)
|
#define MUNIT_NO_FORK (1)
|
||||||
#define MUNIT_ENABLE_ASSERT_ALIASES (1)
|
#define MUNIT_ENABLE_ASSERT_ALIASES (1)
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -18,10 +19,14 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "munit.h"
|
#include "munit.h"
|
||||||
|
|
||||||
|
#define munit_free free
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(disable : 4127)
|
#pragma warning(disable : 4127)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define SELECT_FALSE
|
||||||
|
|
||||||
/* !!! Duplicated here for testing purposes. Keep in sync, or suffer. !!! */
|
/* !!! Duplicated here for testing purposes. Keep in sync, or suffer. !!! */
|
||||||
struct sparsemap {
|
struct sparsemap {
|
||||||
uint8_t *m_data;
|
uint8_t *m_data;
|
||||||
|
@ -66,7 +71,7 @@ test_api_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
assert_ptr_not_null(map);
|
assert_ptr_not_null(map);
|
||||||
free(map);
|
munit_free(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------- API Tests */
|
/* -------------------------- API Tests */
|
||||||
|
@ -93,6 +98,7 @@ static void *
|
||||||
test_api_clear_setup(const MunitParameter params[], void *user_data)
|
test_api_clear_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -103,7 +109,8 @@ static void
|
||||||
test_api_clear_tear_down(void *fixture)
|
test_api_clear_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -126,6 +133,7 @@ static void *
|
||||||
test_api_open_setup(const MunitParameter params[], void *user_data)
|
test_api_open_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -137,7 +145,8 @@ static void
|
||||||
test_api_open_tear_down(void *fixture)
|
test_api_open_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -160,6 +169,7 @@ static void *
|
||||||
test_api_set_data_size_setup(const MunitParameter params[], void *user_data)
|
test_api_set_data_size_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -171,7 +181,8 @@ static void
|
||||||
test_api_set_data_size_tear_down(void *fixture)
|
test_api_set_data_size_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -193,6 +204,7 @@ static void *
|
||||||
test_api_remaining_capacity_setup(const MunitParameter params[], void *user_data)
|
test_api_remaining_capacity_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -203,7 +215,8 @@ static void
|
||||||
test_api_remaining_capacity_tear_down(void *fixture)
|
test_api_remaining_capacity_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -241,6 +254,7 @@ static void *
|
||||||
test_api_get_capacity_setup(const MunitParameter params[], void *user_data)
|
test_api_get_capacity_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -252,7 +266,8 @@ static void
|
||||||
test_api_get_capacity_tear_down(void *fixture)
|
test_api_get_capacity_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -274,6 +289,7 @@ static void *
|
||||||
test_api_is_set_setup(const MunitParameter params[], void *user_data)
|
test_api_is_set_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -285,7 +301,8 @@ static void
|
||||||
test_api_is_set_tear_down(void *fixture)
|
test_api_is_set_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -306,6 +323,7 @@ static void *
|
||||||
test_api_set_setup(const MunitParameter params[], void *user_data)
|
test_api_set_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -316,7 +334,8 @@ static void
|
||||||
test_api_set_tear_down(void *fixture)
|
test_api_set_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -345,6 +364,7 @@ static void *
|
||||||
test_api_get_starting_offset_setup(const MunitParameter params[], void *user_data)
|
test_api_get_starting_offset_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -356,7 +376,8 @@ static void
|
||||||
test_api_get_starting_offset_tear_down(void *fixture)
|
test_api_get_starting_offset_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -379,6 +400,7 @@ static void *
|
||||||
test_api_get_size_setup(const MunitParameter params[], void *user_data)
|
test_api_get_size_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -390,7 +412,8 @@ static void
|
||||||
test_api_get_size_tear_down(void *fixture)
|
test_api_get_size_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -411,10 +434,11 @@ static void *
|
||||||
test_api_scan_setup(const MunitParameter params[], void *user_data)
|
test_api_scan_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
bitmap_from_uint64(map, ((uint64_t)0xfeedface << 32) | 0xbadc0ffee);
|
sm_bitmap_from_uint64(map, ((uint64_t)0xfeedface << 32) | 0xbadc0ffee);
|
||||||
|
|
||||||
return (void *)map;
|
return (void *)map;
|
||||||
}
|
}
|
||||||
|
@ -422,7 +446,8 @@ static void
|
||||||
test_api_scan_tear_down(void *fixture)
|
test_api_scan_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
|
@ -441,7 +466,7 @@ test_api_scan(const MunitParameter params[], void *data)
|
||||||
assert_ptr_not_null(map);
|
assert_ptr_not_null(map);
|
||||||
|
|
||||||
sparsemap_set(map, 4200, true);
|
sparsemap_set(map, 4200, true);
|
||||||
assert_true(sparsemap_is_set(map, 42));
|
assert_true(sparsemap_is_set(map, 4200));
|
||||||
sparsemap_scan(map, scan_for_0xfeedfacebadcoffee, 0);
|
sparsemap_scan(map, scan_for_0xfeedfacebadcoffee, 0);
|
||||||
|
|
||||||
return MUNIT_OK;
|
return MUNIT_OK;
|
||||||
|
@ -451,6 +476,7 @@ static void *
|
||||||
test_api_split_setup(const MunitParameter params[], void *user_data)
|
test_api_split_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -463,7 +489,8 @@ static void
|
||||||
test_api_split_tear_down(void *fixture)
|
test_api_split_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -494,10 +521,11 @@ static void *
|
||||||
test_api_select_setup(const MunitParameter params[], void *user_data)
|
test_api_select_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
bitmap_from_uint64(map, ((uint64_t)0xfeedface << 32) | 0xbadc0ffee);
|
sm_bitmap_from_uint64(map, ((uint64_t)0xfeedface << 32) | 0xbadc0ffee);
|
||||||
|
|
||||||
return (void *)map;
|
return (void *)map;
|
||||||
}
|
}
|
||||||
|
@ -505,7 +533,8 @@ static void
|
||||||
test_api_select_tear_down(void *fixture)
|
test_api_select_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -522,22 +551,76 @@ test_api_select(const MunitParameter params[], void *data)
|
||||||
assert_true(sparsemap_select(map, 4, true) == 6);
|
assert_true(sparsemap_select(map, 4, true) == 6);
|
||||||
assert_true(sparsemap_select(map, 17, true) == 26);
|
assert_true(sparsemap_select(map, 17, true) == 26);
|
||||||
|
|
||||||
#if 0 // TODO
|
return MUNIT_OK;
|
||||||
size_t f = sparsemap_select(map, 0, false);
|
}
|
||||||
for (int i = 0; i <= f; i++) {
|
|
||||||
assert_false(sparsemap_is_set(map, i % 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
sparsemap_clear(map);
|
#ifdef SELECT_FALSE
|
||||||
|
static void *
|
||||||
|
test_api_select_false_setup(const MunitParameter params[], void *user_data)
|
||||||
|
{
|
||||||
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
|
sparsemap_init(map, buf, 1024);
|
||||||
|
sm_bitmap_from_uint64(map, ((uint64_t)0xfeedface << 32) | 0xbadc0ffee);
|
||||||
|
|
||||||
|
return (void *)map;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
test_api_select_false_tear_down(void *fixture)
|
||||||
|
{
|
||||||
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
|
test_api_tear_down(fixture);
|
||||||
|
}
|
||||||
|
static MunitResult
|
||||||
|
test_api_select_false(const MunitParameter params[], void *data)
|
||||||
|
{
|
||||||
|
sparsemap_t *map = (sparsemap_t *)data;
|
||||||
|
(void)params;
|
||||||
|
|
||||||
|
assert_ptr_not_null(map);
|
||||||
|
|
||||||
for (int i = 0; i < 1000; i++) {
|
for (int i = 0; i < 1000; i++) {
|
||||||
sparsemap_set(map, i, i % 2 ? true : false);
|
sparsemap_set(map, i, true);
|
||||||
}
|
}
|
||||||
|
sparsemap_idx_t f = sparsemap_select(map, 0, false);
|
||||||
f = sparsemap_select(map, 0, false);
|
|
||||||
assert_true(f == 1000);
|
assert_true(f == 1000);
|
||||||
|
|
||||||
sparsemap_clear(map);
|
return MUNIT_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SELECT_NEG
|
||||||
|
static void *
|
||||||
|
test_api_select_neg_setup(const MunitParameter params[], void *user_data)
|
||||||
|
{
|
||||||
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
|
sparsemap_init(map, buf, 1024);
|
||||||
|
sm_bitmap_from_uint64(map, ((uint64_t)0xfeedface << 32) | 0xbadc0ffee);
|
||||||
|
|
||||||
|
return (void *)map;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
test_api_select_neg_tear_down(void *fixture)
|
||||||
|
{
|
||||||
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
|
test_api_tear_down(fixture);
|
||||||
|
}
|
||||||
|
static MunitResult
|
||||||
|
test_api_select_neg(const MunitParameter params[], void *data)
|
||||||
|
{
|
||||||
|
sparsemap_t *map = (sparsemap_t *)data;
|
||||||
|
(void)params;
|
||||||
|
|
||||||
|
assert_ptr_not_null(map);
|
||||||
|
|
||||||
sparsemap_set(map, 42, true);
|
sparsemap_set(map, 42, true);
|
||||||
sparsemap_set(map, 420, true);
|
sparsemap_set(map, 420, true);
|
||||||
|
@ -552,14 +635,16 @@ test_api_select(const MunitParameter params[], void *data)
|
||||||
assert_true(f == 420);
|
assert_true(f == 420);
|
||||||
f = sparsemap_select(map, -3, true);
|
f = sparsemap_select(map, -3, true);
|
||||||
assert_true(f == 42);
|
assert_true(f == 42);
|
||||||
#endif
|
|
||||||
return MUNIT_OK;
|
return MUNIT_OK;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
test_api_rank_setup(const MunitParameter params[], void *user_data)
|
test_api_rank_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -570,7 +655,8 @@ static void
|
||||||
test_api_rank_tear_down(void *fixture)
|
test_api_rank_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -615,6 +701,7 @@ static void *
|
||||||
test_api_span_setup(const MunitParameter params[], void *user_data)
|
test_api_span_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -625,7 +712,8 @@ static void
|
||||||
test_api_span_tear_down(void *fixture)
|
test_api_span_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -638,26 +726,26 @@ test_api_span(const MunitParameter params[], void *data)
|
||||||
|
|
||||||
int located_at, placed_at, amt = 10000;
|
int located_at, placed_at, amt = 10000;
|
||||||
|
|
||||||
placed_at = create_sequential_set_in_empty_map(map, amt, 1);
|
placed_at = sm_add_span(map, amt, 1);
|
||||||
located_at = sparsemap_span(map, 0, 1, true);
|
located_at = sparsemap_span(map, 0, 1, true);
|
||||||
assert_true(located_at == placed_at);
|
assert_true(located_at == placed_at);
|
||||||
|
|
||||||
sparsemap_clear(map);
|
sparsemap_clear(map);
|
||||||
|
|
||||||
placed_at = create_sequential_set_in_empty_map(map, amt, 50);
|
placed_at = sm_add_span(map, amt, 50);
|
||||||
located_at = sparsemap_span(map, 0, 50, true);
|
located_at = sparsemap_span(map, 0, 50, true);
|
||||||
assert_true(located_at == placed_at);
|
assert_true(located_at == placed_at);
|
||||||
|
|
||||||
sparsemap_clear(map);
|
sparsemap_clear(map);
|
||||||
|
|
||||||
placed_at = create_sequential_set_in_empty_map(map, amt, 50);
|
placed_at = sm_add_span(map, amt, 50);
|
||||||
located_at = sparsemap_span(map, placed_at / 2, 50, true);
|
located_at = sparsemap_span(map, placed_at / 2, 50, true);
|
||||||
assert_true(located_at == placed_at);
|
assert_true(located_at == placed_at);
|
||||||
|
|
||||||
/* TODO
|
/* TODO
|
||||||
sparsemap_clear(map);
|
sparsemap_clear(map);
|
||||||
|
|
||||||
placed_at = create_sequential_set_in_empty_map(map, amt, amt - 1);
|
placed_at = sm_add_span(map, amt, amt - 1);
|
||||||
located_at = sparsemap_span(map, 0, amt - 1, true);
|
located_at = sparsemap_span(map, 0, amt - 1, true);
|
||||||
assert_true(located_at == placed_at);
|
assert_true(located_at == placed_at);
|
||||||
*/
|
*/
|
||||||
|
@ -681,7 +769,13 @@ static MunitTest api_test_suite[] = {
|
||||||
{ (char *)"/get_size", test_api_get_size, test_api_get_size_setup, test_api_get_size_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
{ (char *)"/get_size", test_api_get_size, test_api_get_size_setup, test_api_get_size_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
||||||
{ (char *)"/scan", test_api_scan, test_api_scan_setup, test_api_scan_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
{ (char *)"/scan", test_api_scan, test_api_scan_setup, test_api_scan_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
||||||
{ (char *)"/split", test_api_split, test_api_split_setup, test_api_split_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
{ (char *)"/split", test_api_split, test_api_split_setup, test_api_split_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
||||||
{ (char *)"/select", test_api_select, test_api_select_setup, test_api_select_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
{ (char *)"/select/true", test_api_select, test_api_select_setup, test_api_select_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
||||||
|
#ifdef SELECT_FALSE
|
||||||
|
{ (char *)"/select/false", test_api_select_false, test_api_select_false_setup, test_api_select_false_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
||||||
|
#endif
|
||||||
|
#ifdef SELECT_NEG
|
||||||
|
{ (char *)"/select/neg", test_api_select_neg, test_api_select_neg_setup, test_api_select_neg_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
||||||
|
#endif
|
||||||
{ (char *)"/rank", test_api_rank, test_api_rank_setup, test_api_rank_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
{ (char *)"/rank", test_api_rank, test_api_rank_setup, test_api_rank_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
||||||
{ (char *)"/span", test_api_span, test_api_span_setup, test_api_span_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
{ (char *)"/span", test_api_span, test_api_span_setup, test_api_span_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
||||||
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
|
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
|
||||||
|
@ -693,10 +787,10 @@ static MunitTest api_test_suite[] = {
|
||||||
static void *
|
static void *
|
||||||
test_scale_lots_o_spans_setup(const MunitParameter params[], void *user_data)
|
test_scale_lots_o_spans_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
(void)params;
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
(void)user_data;
|
||||||
|
sparsemap_t *map = sparsemap(1024);
|
||||||
sparsemap_init(map, buf, 1024);
|
assert_ptr_not_null(map);
|
||||||
|
|
||||||
return (void *)map;
|
return (void *)map;
|
||||||
}
|
}
|
||||||
|
@ -704,8 +798,8 @@ static void
|
||||||
test_scale_lots_o_spans_tear_down(void *fixture)
|
test_scale_lots_o_spans_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map);
|
||||||
test_api_tear_down(fixture);
|
munit_free(map);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
test_scale_lots_o_spans(const MunitParameter params[], void *data)
|
test_scale_lots_o_spans(const MunitParameter params[], void *data)
|
||||||
|
@ -717,21 +811,82 @@ test_scale_lots_o_spans(const MunitParameter params[], void *data)
|
||||||
|
|
||||||
for (int i = 0; i < 268435456;) {
|
for (int i = 0; i < 268435456;) {
|
||||||
int l = i % 31 + 16;
|
int l = i % 31 + 16;
|
||||||
create_sequential_set_in_empty_map(map, 268435456, l);
|
sm_add_span(map, 268435456, l);
|
||||||
|
if (errno == ENOSPC) {
|
||||||
|
map = sparsemap_set_data_size(map, sparsemap_get_capacity(map) * 2);
|
||||||
|
errno = 0;
|
||||||
|
}
|
||||||
i += l;
|
i += l;
|
||||||
/* ANSI esc code to clear line, carrage return, then print on the same line */
|
/* ANSI esc code to clear line, carrage return, then print on the same line */
|
||||||
//printf("\033[2K\r%d", i);
|
// printf("\033[2K\r%d", i);
|
||||||
//printf("%d\t%d\n", l, i);
|
// printf("%d\t%d\n", l, i);
|
||||||
//fflush(stdout);
|
// fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
return MUNIT_OK;
|
return MUNIT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
test_scale_ondrej_setup(const MunitParameter params[], void *user_data)
|
||||||
|
{
|
||||||
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
|
sparsemap_init(map, buf, 1024);
|
||||||
|
|
||||||
|
return (void *)map;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
test_scale_ondrej_tear_down(void *fixture)
|
||||||
|
{
|
||||||
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
|
test_api_tear_down(fixture);
|
||||||
|
}
|
||||||
|
static MunitResult
|
||||||
|
test_scale_ondrej(const MunitParameter params[], void *data)
|
||||||
|
{
|
||||||
|
sparsemap_t *map = (sparsemap_t *)data;
|
||||||
|
(void)params;
|
||||||
|
|
||||||
|
assert_ptr_not_null(map);
|
||||||
|
|
||||||
|
sparsemap_idx_t stride = 18;
|
||||||
|
sparsemap_idx_t top = 268435456;
|
||||||
|
sparsemap_idx_t needle = munit_rand_int_range(1, top / stride);
|
||||||
|
for (sparsemap_idx_t i = 0; i < top / stride; i++) {
|
||||||
|
for (sparsemap_idx_t j = 0; j < stride; j++) {
|
||||||
|
bool set = (i != needle) ? (j < 10) : (j < 9);
|
||||||
|
sparsemap_set(map, i, set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
// sm_add_span(map, 268435456, 9);
|
||||||
|
|
||||||
|
size_t b = sparsemap_span(map, 0, 8, true);
|
||||||
|
if (SPARSEMAP_NOT_FOUND(b)) {
|
||||||
|
printf("%ld\n", b);
|
||||||
|
printf("%ld / %ld == %ld %ld\n", b, stride, b / stride, needle);
|
||||||
|
} else {
|
||||||
|
printf("not found\n");
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
size_t b = sparsemap_span(map, 0, 9, false); TODO
|
||||||
|
printf("%ld (%d) / %d == %d", b, (int)b, stride, needle);
|
||||||
|
fflush(stdout);
|
||||||
|
assert_true(((int)b / stride) == needle);
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
return MUNIT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
test_scale_spans_come_spans_go_setup(const MunitParameter params[], void *user_data)
|
test_scale_spans_come_spans_go_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -742,7 +897,8 @@ static void
|
||||||
test_scale_spans_come_spans_go_tear_down(void *fixture)
|
test_scale_spans_come_spans_go_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -753,10 +909,10 @@ test_scale_spans_come_spans_go(const MunitParameter params[], void *data)
|
||||||
|
|
||||||
assert_ptr_not_null(map);
|
assert_ptr_not_null(map);
|
||||||
|
|
||||||
|
/* ~5e7 interations due to 2e9 / avg(l) */
|
||||||
for (int i = 0; i < 268435456;) {
|
for (int i = 0; i < 268435456;) {
|
||||||
int l = i % 31 + 16;
|
int l = i % 31 + 16;
|
||||||
create_sequential_set_in_empty_map(map, 268435456, l);
|
sm_add_span(map, 268435456, l);
|
||||||
i += l;
|
|
||||||
|
|
||||||
/* After 10,000 spans are in there we consume a span every iteration. */
|
/* After 10,000 spans are in there we consume a span every iteration. */
|
||||||
if (l > 10000) {
|
if (l > 10000) {
|
||||||
|
@ -764,7 +920,7 @@ test_scale_spans_come_spans_go(const MunitParameter params[], void *data)
|
||||||
int s = munit_rand_int_range(1, 30);
|
int s = munit_rand_int_range(1, 30);
|
||||||
int o = munit_rand_int_range(1, 268435456 - s - 1);
|
int o = munit_rand_int_range(1, 268435456 - s - 1);
|
||||||
size_t b = sparsemap_span(map, o, s, true);
|
size_t b = sparsemap_span(map, o, s, true);
|
||||||
if (b == SM_LOC_MAX) {
|
if (b == SPARSEMAP_IDX_MAX) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (int j = b; j < s; j++) {
|
for (int j = b; j < s; j++) {
|
||||||
|
@ -779,6 +935,7 @@ test_scale_spans_come_spans_go(const MunitParameter params[], void *data)
|
||||||
break;
|
break;
|
||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
i += l;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MUNIT_OK;
|
return MUNIT_OK;
|
||||||
|
@ -788,6 +945,7 @@ static void *
|
||||||
test_scale_best_case_setup(const MunitParameter params[], void *user_data)
|
test_scale_best_case_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -798,7 +956,8 @@ static void
|
||||||
test_scale_best_case_tear_down(void *fixture)
|
test_scale_best_case_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -818,7 +977,8 @@ test_scale_best_case(const MunitParameter params[], void *data)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Set every bit on, that should be the best case. */
|
/* Set every bit on, that should be the best case. */
|
||||||
for (int i = 0; i < 268435456; i++) {
|
// for (int i = 0; i < 268435456; i++) {
|
||||||
|
for (int i = 0; i < 172032; i++) {
|
||||||
/* ANSI esc code to clear line, carrage return, then print on the same line */
|
/* ANSI esc code to clear line, carrage return, then print on the same line */
|
||||||
// printf("\033[2K\r%d", i);
|
// printf("\033[2K\r%d", i);
|
||||||
// fflush(stdout);
|
// fflush(stdout);
|
||||||
|
@ -832,6 +992,7 @@ static void *
|
||||||
test_scale_worst_case_setup(const MunitParameter params[], void *user_data)
|
test_scale_worst_case_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 1024);
|
sparsemap_init(map, buf, 1024);
|
||||||
|
@ -842,7 +1003,8 @@ static void
|
||||||
test_scale_worst_case_tear_down(void *fixture)
|
test_scale_worst_case_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -862,7 +1024,8 @@ test_scale_worst_case(const MunitParameter params[], void *data)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Set every other bit, that has to be the "worst case" for this index. */
|
/* Set every other bit, that has to be the "worst case" for this index. */
|
||||||
for (int i = 0; i < 8134407; i += 2) {
|
// for (int i = 0; i < 8134407; i += 2) {
|
||||||
|
for (int i = 0; i < 7744; i += 2) {
|
||||||
/* ANSI esc code to clear line, carrage return, then print on the same line */
|
/* ANSI esc code to clear line, carrage return, then print on the same line */
|
||||||
// printf("\033[2K\r%d", i);
|
// printf("\033[2K\r%d", i);
|
||||||
// fflush(stdout);
|
// fflush(stdout);
|
||||||
|
@ -878,6 +1041,7 @@ static void *
|
||||||
test_perf_span_solo_setup(const MunitParameter params[], void *user_data)
|
test_perf_span_solo_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024 * 3, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024 * 3, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 3 * 1024);
|
sparsemap_init(map, buf, 3 * 1024);
|
||||||
|
@ -888,7 +1052,8 @@ static void
|
||||||
test_perf_span_solo_tear_down(void *fixture)
|
test_perf_span_solo_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -904,9 +1069,9 @@ test_perf_span_solo(const MunitParameter params[], void *data)
|
||||||
for (int i = 1; i < amt; i++) {
|
for (int i = 1; i < amt; i++) {
|
||||||
for (int j = 1; j <= 100; j++) {
|
for (int j = 1; j <= 100; j++) {
|
||||||
sparsemap_clear(map);
|
sparsemap_clear(map);
|
||||||
placed_at = create_sequential_set_in_empty_map(map, amt, j);
|
placed_at = sm_add_span(map, amt, j);
|
||||||
// logf("i = %d, j = %d\tplaced_at %d\n", i, j, placed_at);
|
// logf("i = %d, j = %d\tplaced_at %d\n", i, j, placed_at);
|
||||||
// whats_set(map, 5000);
|
// sm_whats_set(map, 5000);
|
||||||
// start = nsts();
|
// start = nsts();
|
||||||
located_at = sparsemap_span(map, 0, j, true);
|
located_at = sparsemap_span(map, 0, j, true);
|
||||||
// stop = nsts();
|
// stop = nsts();
|
||||||
|
@ -925,6 +1090,7 @@ static void *
|
||||||
test_perf_span_tainted_setup(const MunitParameter params[], void *user_data)
|
test_perf_span_tainted_setup(const MunitParameter params[], void *user_data)
|
||||||
{
|
{
|
||||||
uint8_t *buf = munit_calloc(1024 * 3, sizeof(uint8_t));
|
uint8_t *buf = munit_calloc(1024 * 3, sizeof(uint8_t));
|
||||||
|
assert_ptr_not_null(buf);
|
||||||
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
sparsemap_t *map = (sparsemap_t *)test_api_setup(params, user_data);
|
||||||
|
|
||||||
sparsemap_init(map, buf, 3 * 1024);
|
sparsemap_init(map, buf, 3 * 1024);
|
||||||
|
@ -935,7 +1101,8 @@ static void
|
||||||
test_perf_span_tainted_tear_down(void *fixture)
|
test_perf_span_tainted_tear_down(void *fixture)
|
||||||
{
|
{
|
||||||
sparsemap_t *map = (sparsemap_t *)fixture;
|
sparsemap_t *map = (sparsemap_t *)fixture;
|
||||||
free(map->m_data);
|
assert_ptr_not_null(map->m_data);
|
||||||
|
munit_free(map->m_data);
|
||||||
test_api_tear_down(fixture);
|
test_api_tear_down(fixture);
|
||||||
}
|
}
|
||||||
static MunitResult
|
static MunitResult
|
||||||
|
@ -952,7 +1119,7 @@ test_perf_span_tainted(const MunitParameter params[], void *data)
|
||||||
for (int j = 100; j <= 10; j++) {
|
for (int j = 100; j <= 10; j++) {
|
||||||
sparsemap_clear(map);
|
sparsemap_clear(map);
|
||||||
populate_map(map, 1024, 1 * 1024);
|
populate_map(map, 1024, 1 * 1024);
|
||||||
placed_at = create_sequential_set_in_empty_map(map, amt, j);
|
placed_at = sm_add_span(map, amt, j);
|
||||||
// start = nsts();
|
// start = nsts();
|
||||||
located_at = sparsemap_span(map, 0, j, true);
|
located_at = sparsemap_span(map, 0, j, true);
|
||||||
// stop = nsts();
|
// stop = nsts();
|
||||||
|
@ -971,6 +1138,7 @@ test_perf_span_tainted(const MunitParameter params[], void *data)
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static MunitTest scale_test_suite[] = {
|
static MunitTest scale_test_suite[] = {
|
||||||
{ (char *)"/lots-o-spans", test_scale_lots_o_spans, test_scale_lots_o_spans_setup, test_scale_lots_o_spans_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
{ (char *)"/lots-o-spans", test_scale_lots_o_spans, test_scale_lots_o_spans_setup, test_scale_lots_o_spans_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
||||||
|
{ (char *)"/ondrej", test_scale_ondrej, test_scale_ondrej_setup, test_scale_ondrej_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
||||||
{ (char *)"/spans_come_spans_go", test_scale_spans_come_spans_go, test_scale_spans_come_spans_go_setup, test_scale_spans_come_spans_go_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
{ (char *)"/spans_come_spans_go", test_scale_spans_come_spans_go, test_scale_spans_come_spans_go_setup, test_scale_spans_come_spans_go_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
||||||
{ (char *)"/best-case", test_scale_best_case, test_scale_best_case_setup, test_scale_best_case_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
{ (char *)"/best-case", test_scale_best_case, test_scale_best_case_setup, test_scale_best_case_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
||||||
{ (char *)"/worst-case", test_scale_worst_case, test_scale_worst_case_setup, test_scale_worst_case_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
{ (char *)"/worst-case", test_scale_worst_case, test_scale_worst_case_setup, test_scale_worst_case_tear_down, MUNIT_TEST_OPTION_NONE, NULL },
|
||||||
|
@ -986,12 +1154,19 @@ static MunitTest perf_test_suite[] = {
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static MunitSuite other_test_suite[] = {
|
static MunitSuite other_test_suite[] = {
|
||||||
|
{ "/api", api_test_suite, NULL, 1, MUNIT_SUITE_OPTION_NONE },
|
||||||
{ "/perf", perf_test_suite, NULL, 1, MUNIT_SUITE_OPTION_NONE },
|
{ "/perf", perf_test_suite, NULL, 1, MUNIT_SUITE_OPTION_NONE },
|
||||||
{ "/scale", scale_test_suite, NULL, 1, MUNIT_SUITE_OPTION_NONE },
|
{ "/scale", scale_test_suite, NULL, 1, MUNIT_SUITE_OPTION_NONE },
|
||||||
{ NULL, NULL, NULL, 0, MUNIT_SUITE_OPTION_NONE } };
|
{ NULL, NULL, NULL, 0, MUNIT_SUITE_OPTION_NONE } };
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
static const MunitSuite main_test_suite = { (char *)"/api", api_test_suite, other_test_suite, 1, MUNIT_SUITE_OPTION_NONE };
|
// clang-format off
|
||||||
|
static MunitTest sparsemap_test_suite[] = {
|
||||||
|
{ NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
static const MunitSuite main_test_suite = { (char *)"/sparsemap", sparsemap_test_suite, other_test_suite, 1, MUNIT_SUITE_OPTION_NONE };
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[MUNIT_ARRAY_PARAM(argc + 1)])
|
main(int argc, char *argv[MUNIT_ARRAY_PARAM(argc + 1)])
|
||||||
|
|
Loading…
Reference in a new issue