1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include "unit.h"
#ifndef bytemap
#define bytemap 0
#endif
#define MH_SOURCE 1
#define mh_name _i32
struct mh_i32_node_t {
int32_t key;
int32_t val;
};
#define mh_node_t struct mh_i32_node_t
#define mh_arg_t void *
#define mh_hash(a, arg) (a->key)
#define mh_cmp(a, b, arg) ((a->key) != (b->key))
#define mh_bytemap bytemap
#include "salad/mhash.h"
#define mh_name _i32_collision
struct mh_i32_collision_node_t {
int32_t key;
int32_t val;
};
#define mh_node_t struct mh_i32_collision_node_t
#define mh_arg_t void *
#define mh_hash(a, arg) 42
#define mh_cmp(a, b, arg) ((a->key) != (b->key))
#define mh_bytemap bytemap
#include "salad/mhash.h"
#undef MH_SOURCE
static void mhash_int32_id_test()
{
header();
plan(0);
int k;
struct mh_i32_t *h;
#define init() ({ mh_i32_new(); })
#define clear(x) ({ mh_i32_clear((x)); })
#define destroy(x) ({ mh_i32_delete((x)); })
#define get(x) ({ \
const struct mh_i32_node_t _node = { .key = (x) }; \
mh_i32_get(h, &_node, NULL); \
})
#define put(x) ({ \
const struct mh_i32_node_t _node = { .key = (x) }; \
mh_i32_put(h, &_node, NULL, NULL); \
})
#define key(k) (mh_i32_node(h, k)->key)
#define val(k) (mh_i32_node(h, k)->val)
#define del(k) ({ \
mh_i32_del(h, k, NULL); \
})
#include "mhash_body.c"
footer();
check_plan();
}
static void mhash_int32_collision_test()
{
header();
plan(0);
int k;
struct mh_i32_collision_t *h;
#define init() ({ mh_i32_collision_new(); })
#define clear(x) ({ mh_i32_collision_clear((x)); })
#define destroy(x) ({ mh_i32_collision_delete((x)); })
#define get(x) ({ \
const struct mh_i32_collision_node_t _node = { .key = (x) }; \
mh_i32_collision_get(h, &_node, NULL); \
})
#define put(x) ({ \
const struct mh_i32_collision_node_t _node = { .key = (x) }; \
mh_i32_collision_put(h, &_node, NULL, NULL); \
})
#define key(k) (mh_i32_collision_node(h, k)->key)
#define val(k) (mh_i32_collision_node(h, k)->val)
#define del(k) ({ \
mh_i32_collision_del(h, k, NULL); \
})
#include "mhash_body.c"
footer();
check_plan();
}
static void
mhash_random_test(void)
{
header();
plan(3);
struct mh_i32_t *h = mh_i32_new();
const int end = 100;
int i, size;
bool is_found[end], all_is_found[end];
memset(all_is_found, 1, sizeof(all_is_found));
for (i = 0; i < end; ++i) {
if (mh_i32_random(h, i) != mh_end(h))
break;
}
is(i, end, "empty random is always 'end'");
for (i = 0; i < end; ++i) {
struct mh_i32_node_t node = {i, i};
mh_int_t rc = mh_i32_put(h, &node, NULL, NULL);
int j;
for (j = 0; j < end; ++j) {
if (mh_i32_random(h, j) != rc)
break;
}
mh_i32_del(h, rc, NULL);
if (j != end)
break;
}
is(i, end, "one element is always found");
for (i = 0, size = sizeof(bool); i < end; ++i, size += sizeof(bool)) {
struct mh_i32_node_t *n, node = {i, i};
mh_i32_put(h, &node, NULL, NULL);
memset(is_found, 0, sizeof(is_found));
for (int j = 0; j < end; ++j) {
mh_int_t rc = mh_i32_random(h, j);
n = mh_i32_node(h, rc);
is_found[n->key] = true;
}
if (memcmp(is_found, all_is_found, size) != 0)
break;
}
is(i, end, "incremental random from mutable hash");
mh_i32_delete(h);
check_plan();
footer();
}
int main(void)
{
header();
plan(3);
mhash_int32_id_test();
mhash_int32_collision_test();
mhash_random_test();
int rc = check_plan();
footer();
return rc;
}
|