File: mhash.c

package info (click to toggle)
tarantool 2.6.0-1.4
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 85,412 kB
  • sloc: ansic: 513,775; cpp: 69,493; sh: 25,650; python: 19,190; perl: 14,973; makefile: 4,178; yacc: 1,329; sql: 1,074; pascal: 620; ruby: 190; awk: 18; lisp: 7
file content (158 lines) | stat: -rw-r--r-- 3,451 bytes parent folder | download | duplicates (3)
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;
}