dynarray: no longer _dynarray_fix() function, _dynarray_arr() "instead"

This commit is contained in:
Libor Peltan 2017-06-05 15:52:51 +02:00 committed by Daniel Salzman
parent 16d4c8ce88
commit 4792b4cbdd
4 changed files with 79 additions and 47 deletions

View file

@ -42,43 +42,56 @@
typedef struct prefix ## _dynarray { \
ssize_t capacity; \
ssize_t size; \
ntype *(*arr)(struct prefix ## _dynarray *dynarray); \
ntype init[initial_capacity]; \
ntype *arr; \
ntype *_arr; \
} prefix ## _dynarray_t; \
\
visibility void prefix ## _dynarray_fix(prefix ## _dynarray_t *dynarray); \
visibility ntype *prefix ## _dynarray_arr(prefix ## _dynarray_t *dynarray); \
visibility void prefix ## _dynarray_add(prefix ## _dynarray_t *dynarray, \
ntype const *to_add); \
visibility void prefix ## _dynarray_free(prefix ## _dynarray_t *dynarray);
#define dynarray_foreach(prefix, ntype, ptr, array) \
for (ntype *ptr = (prefix ## _dynarray_fix(&(array)), (array).arr); \
ptr < (array).arr + (array).size; ptr++)
for (ntype *ptr = prefix ## _dynarray_arr(&(array)); \
ptr < prefix ## _dynarray_arr(&(array)) + (array).size; ptr++)
#define dynarray_define(prefix, ntype, visibility, initial_capacity) \
\
static void prefix ## _dynarray_free__(struct prefix ## _dynarray *dynarray) \
{ \
if (dynarray->capacity > initial_capacity) { \
free(dynarray->arr); \
if (dynarray->capacity > (initial_capacity)) { \
free(dynarray->_arr); \
} \
} \
\
__attribute__((unused)) \
visibility void prefix ## _dynarray_fix(struct prefix ## _dynarray *dynarray) \
visibility ntype *prefix ## _dynarray_arr(struct prefix ## _dynarray *dynarray) \
{ \
assert(dynarray->size <= dynarray->capacity); \
if (dynarray->capacity <= initial_capacity) { \
dynarray->capacity = initial_capacity; \
dynarray->arr = dynarray->init; \
} \
return (dynarray->capacity <= (initial_capacity) ? dynarray->init : dynarray->_arr); \
} \
\
static ntype *prefix ## _dynarray_arr_init__(struct prefix ## _dynarray *dynarray) \
{ \
assert(dynarray->capacity == (initial_capacity)); \
return dynarray->init; \
} \
\
static ntype *prefix ## _dynarray_arr_arr__(struct prefix ## _dynarray *dynarray) \
{ \
assert(dynarray->capacity > (initial_capacity)); \
return dynarray->_arr; \
} \
\
__attribute__((unused)) \
visibility void prefix ## _dynarray_add(struct prefix ## _dynarray *dynarray, \
ntype const *to_add) \
{ \
prefix ## _dynarray_fix(dynarray); \
if (dynarray->capacity == 0) { \
dynarray->capacity = (initial_capacity); \
dynarray->arr = prefix ## _dynarray_arr_init__; \
} \
if (dynarray->size >= dynarray->capacity) { \
ssize_t new_capacity = dynarray->capacity * 2 + 1; \
ntype *new_arr = calloc(new_capacity, sizeof(ntype)); \
@ -88,14 +101,15 @@
return; \
} \
if (dynarray->capacity > 0) { \
memcpy(new_arr, dynarray->arr, \
memcpy(new_arr, prefix ## _dynarray_arr(dynarray), \
dynarray->capacity * sizeof(ntype)); \
} \
prefix ## _dynarray_free__(dynarray); \
dynarray->arr = new_arr; \
dynarray->_arr = new_arr; \
dynarray->capacity = new_capacity; \
dynarray->arr = prefix ## _dynarray_arr_arr__; \
} \
dynarray->arr[dynarray->size++] = *to_add; \
prefix ## _dynarray_arr(dynarray)[dynarray->size++] = *to_add; \
} \
\
__attribute__((unused)) \

View file

@ -289,7 +289,7 @@ void conf_mod_load_purge(
// Switch the current temporary schema with the initial one.
if (temporary && conf->old_schemas.size > 0) {
yp_item_t **current_schema = &conf->schema;
yp_item_t **initial = &(conf->old_schemas.arr)[0];
yp_item_t **initial = &(conf->old_schemas.arr(&conf->old_schemas))[0];
yp_item_t *old_schema = rcu_xchg_pointer(current_schema, *initial);
synchronize_rcu();

View file

@ -685,14 +685,13 @@ static bool is_from_keyset(zone_keyset_t *keyset,
bool found = false;
struct keyptr_dynarray keys = get_zone_keys(keyset, tag);
keyptr_dynarray_fix(&keys);
for (size_t i = 0; i < keys.size; i++) {
bool usekey = (is_cds_cdnskey ? (keys.arr[i]->is_ready && !keys.arr[i]->is_active) : keys.arr[i]->is_public);
if (usekey && match_fce(keys.arr[i], &rdata)) {
bool usekey = (is_cds_cdnskey ? (keys.arr(&keys)[i]->is_ready && !keys.arr(&keys)[i]->is_active) : keys.arr(&keys)[i]->is_public);
if (usekey && match_fce(keys.arr(&keys)[i], &rdata)) {
found = true;
if (matching_key != NULL) {
*matching_key = keys.arr[i];
*matching_key = keys.arr(&keys)[i];
}
break;
}

View file

@ -19,42 +19,61 @@
#include "contrib/dynarray.h"
#define test_capacity 2
#define test_capacity 5
// minimum 3
#define test_type(type, prefix) \
dynarray_declare(prefix, type, DYNARRAY_VISIBILITY_STATIC, test_capacity) \
dynarray_define(prefix, type, DYNARRAY_VISIBILITY_STATIC, test_capacity) \
static void prefix ## _test(type const first, type const second) { \
struct prefix ## _dynarray array = { 0 }; \
prefix ## _dynarray_fix(&array); \
ok(array.capacity == test_capacity && array.size == 0 && array.init == array.arr, \
"%s: Fix - initial capacity set", #prefix); \
prefix ## _dynarray_add(&array, &first); \
ok(array.capacity == test_capacity && array.size == 1 && array.arr[0] == first && \
array.init == array.arr, "%s: Add item", #prefix); \
prefix ## _dynarray_add(&array, &second); \
ok(array.capacity == test_capacity && array.size == 2 && array.arr[1] == second && \
array.init == array.arr, "%s: Array filled (size not changed yet)", #prefix); \
prefix ## _dynarray_add(&array, &first); \
ok(array.capacity == 2 * test_capacity + 1 && array.size == 3 && array.arr[2] == first && \
array.init != array.arr, "%s: Array extended", #prefix); \
prefix ## _dynarray_free(&array); \
prefix ## _dynarray_add(&array, &first); \
ok(array.capacity == test_capacity && array.size == 1 && array.arr[0] == first && \
array.init == array.arr, "%s: Free & add first- initial capacity set", #prefix); \
typedef struct {
int x;
int x2;
} quadrate_t;
dynarray_declare(q, quadrate_t, DYNARRAY_VISIBILITY_STATIC, test_capacity);
dynarray_define(q, quadrate_t, DYNARRAY_VISIBILITY_STATIC, test_capacity);
static q_dynarray_t q_fill(size_t howmany)
{
quadrate_t q = { 0 };
q_dynarray_t qd = { 0 };
for (size_t i = 0; i < howmany; i++) {
q.x2 = q.x * q.x;
q_dynarray_add(&qd, &q);
q.x++;
}
return qd;
}
test_type(int, int)
test_type(char *, string)
static void check_arr(q_dynarray_t *q, size_t index, const char *msg)
{
quadrate_t *arr = q->arr(q);
ok(arr[index].x == index && arr[index].x2 == index * index,
"%s check: index %zu", msg, index);
size_t i = 0;
dynarray_foreach(q, quadrate_t, p, *q) {
ok(p->x == i && p->x2 == i * i, "%s foreach: index %zu", msg, i);
i++;
}
}
int main(int argc, char *argv[])
{
plan_lazy();
int_test(4, 2);
// first fill
q_dynarray_t q = q_fill(test_capacity - 1);
check_arr(&q, test_capacity - 3, "initial");
q_dynarray_free(&q);
char a = 'a', b = 'b';
string_test(&a, &b);
// second fill
q = q_fill(test_capacity + 3);
check_arr(&q, test_capacity + 1, "second");
q_dynarray_free(&q);
// third fill
q = q_fill(test_capacity * 5);
check_arr(&q, test_capacity * 4, "third");
q_dynarray_free(&q);
return 0;
}