xref: /dpdk/app/test/test_member.c (revision b5662e6d288762fe2c538551eb03d68854896e0b)
1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson  * Copyright(c) 2017 Intel Corporation
3a9de470cSBruce Richardson  */
4a9de470cSBruce Richardson 
5a9de470cSBruce Richardson /* This test is for membership library's simple feature test */
6a9de470cSBruce Richardson 
7db354bd2SLeyi Rong #include <math.h>
83c60274cSJie Zhou #include "test.h"
93c60274cSJie Zhou 
10a9de470cSBruce Richardson #include <rte_memcpy.h>
11a9de470cSBruce Richardson #include <rte_malloc.h>
123c60274cSJie Zhou 
133c60274cSJie Zhou #ifdef RTE_EXEC_ENV_WINDOWS
143c60274cSJie Zhou static int
153c60274cSJie Zhou test_member(void)
163c60274cSJie Zhou {
173c60274cSJie Zhou 	printf("member not supported on Windows, skipping test\n");
183c60274cSJie Zhou 	return TEST_SKIPPED;
193c60274cSJie Zhou }
203c60274cSJie Zhou 
213c60274cSJie Zhou #else
223c60274cSJie Zhou 
23a9de470cSBruce Richardson #include <rte_member.h>
24a9de470cSBruce Richardson #include <rte_byteorder.h>
25a9de470cSBruce Richardson #include <rte_random.h>
26a9de470cSBruce Richardson #include <rte_debug.h>
27a9de470cSBruce Richardson #include <rte_ip.h>
28a9de470cSBruce Richardson 
29a9de470cSBruce Richardson struct rte_member_setsum *setsum_ht;
30a9de470cSBruce Richardson struct rte_member_setsum *setsum_cache;
31a9de470cSBruce Richardson struct rte_member_setsum *setsum_vbf;
32db354bd2SLeyi Rong struct rte_member_setsum *setsum_sketch;
33a9de470cSBruce Richardson 
34a9de470cSBruce Richardson /* 5-tuple key type */
35*b5662e6dSAndre Muezerie struct __rte_packed_begin flow_key {
36a9de470cSBruce Richardson 	uint32_t ip_src;
37a9de470cSBruce Richardson 	uint32_t ip_dst;
38a9de470cSBruce Richardson 	uint16_t port_src;
39a9de470cSBruce Richardson 	uint16_t port_dst;
40a9de470cSBruce Richardson 	uint8_t proto;
41*b5662e6dSAndre Muezerie } __rte_packed_end;
42a9de470cSBruce Richardson 
43a9de470cSBruce Richardson /* Set ID Macros for multimatch test usage */
44a9de470cSBruce Richardson #define M_MATCH_S 1	/* Not start with 0 since by default 0 means no match */
45a9de470cSBruce Richardson #define M_MATCH_E 15
46a9de470cSBruce Richardson #define M_MATCH_STEP 2
47a9de470cSBruce Richardson #define M_MATCH_CNT \
48a9de470cSBruce Richardson 	(1 + (M_MATCH_E - M_MATCH_S) / M_MATCH_STEP)
49a9de470cSBruce Richardson 
50a9de470cSBruce Richardson 
51a9de470cSBruce Richardson #define NUM_SAMPLES 5
52a9de470cSBruce Richardson #define MAX_MATCH 32
53a9de470cSBruce Richardson 
54a9de470cSBruce Richardson /* Keys used by unit test functions */
55a9de470cSBruce Richardson static struct flow_key keys[NUM_SAMPLES] = {
56a9de470cSBruce Richardson 	{
570c9da755SDavid Marchand 		.ip_src = RTE_IPV4(0x03, 0x02, 0x01, 0x00),
580c9da755SDavid Marchand 		.ip_dst = RTE_IPV4(0x07, 0x06, 0x05, 0x04),
59a9de470cSBruce Richardson 		.port_src = 0x0908,
60a9de470cSBruce Richardson 		.port_dst = 0x0b0a,
61a9de470cSBruce Richardson 		.proto = 0x0c,
62a9de470cSBruce Richardson 	},
63a9de470cSBruce Richardson 	{
640c9da755SDavid Marchand 		.ip_src = RTE_IPV4(0x13, 0x12, 0x11, 0x10),
650c9da755SDavid Marchand 		.ip_dst = RTE_IPV4(0x17, 0x16, 0x15, 0x14),
66a9de470cSBruce Richardson 		.port_src = 0x1918,
67a9de470cSBruce Richardson 		.port_dst = 0x1b1a,
68a9de470cSBruce Richardson 		.proto = 0x1c,
69a9de470cSBruce Richardson 	},
70a9de470cSBruce Richardson 	{
710c9da755SDavid Marchand 		.ip_src = RTE_IPV4(0x23, 0x22, 0x21, 0x20),
720c9da755SDavid Marchand 		.ip_dst = RTE_IPV4(0x27, 0x26, 0x25, 0x24),
73a9de470cSBruce Richardson 		.port_src = 0x2928,
74a9de470cSBruce Richardson 		.port_dst = 0x2b2a,
75a9de470cSBruce Richardson 		.proto = 0x2c,
76a9de470cSBruce Richardson 	},
77a9de470cSBruce Richardson 	{
780c9da755SDavid Marchand 		.ip_src = RTE_IPV4(0x33, 0x32, 0x31, 0x30),
790c9da755SDavid Marchand 		.ip_dst = RTE_IPV4(0x37, 0x36, 0x35, 0x34),
80a9de470cSBruce Richardson 		.port_src = 0x3938,
81a9de470cSBruce Richardson 		.port_dst = 0x3b3a,
82a9de470cSBruce Richardson 		.proto = 0x3c,
83a9de470cSBruce Richardson 	},
84a9de470cSBruce Richardson 	{
850c9da755SDavid Marchand 		.ip_src = RTE_IPV4(0x43, 0x42, 0x41, 0x40),
860c9da755SDavid Marchand 		.ip_dst = RTE_IPV4(0x47, 0x46, 0x45, 0x44),
87a9de470cSBruce Richardson 		.port_src = 0x4948,
88a9de470cSBruce Richardson 		.port_dst = 0x4b4a,
89a9de470cSBruce Richardson 		.proto = 0x4c,
90a9de470cSBruce Richardson 	}
91a9de470cSBruce Richardson };
92a9de470cSBruce Richardson 
93a9de470cSBruce Richardson uint32_t test_set[NUM_SAMPLES] = {1, 2, 3, 4, 5};
94a9de470cSBruce Richardson 
95a9de470cSBruce Richardson #define ITERATIONS  3
96a9de470cSBruce Richardson #define KEY_SIZE  4
97a9de470cSBruce Richardson 
98a9de470cSBruce Richardson #define MAX_ENTRIES (1 << 16)
99a9de470cSBruce Richardson uint8_t generated_keys[MAX_ENTRIES][KEY_SIZE];
100a9de470cSBruce Richardson 
101a9de470cSBruce Richardson static struct rte_member_parameters params = {
102a9de470cSBruce Richardson 		.num_keys = MAX_ENTRIES,	/* Total hash table entries. */
103a9de470cSBruce Richardson 		.key_len = KEY_SIZE,		/* Length of hash key. */
104a9de470cSBruce Richardson 
105a9de470cSBruce Richardson 		/* num_set and false_positive_rate only relevant to vBF */
106a9de470cSBruce Richardson 		.num_set = 16,
107a9de470cSBruce Richardson 		.false_positive_rate = 0.03,
108a9de470cSBruce Richardson 		.prim_hash_seed = 1,
109a9de470cSBruce Richardson 		.sec_hash_seed = 11,
110a9de470cSBruce Richardson 		.socket_id = 0			/* NUMA Socket ID for memory. */
111a9de470cSBruce Richardson };
112a9de470cSBruce Richardson 
113db354bd2SLeyi Rong /* for sketch definitions */
114db354bd2SLeyi Rong #define TOP_K 10
115db354bd2SLeyi Rong #define HH_PKT_SIZE 16
116db354bd2SLeyi Rong #define SKETCH_ERROR_RATE 0.05
117db354bd2SLeyi Rong #define SKETCH_SAMPLE_RATE 0.001
118db354bd2SLeyi Rong #define PRINT_OUT_COUNT 20
119db354bd2SLeyi Rong 
120db354bd2SLeyi Rong #define SKETCH_LARGEST_KEY_SIZE 1000000
121db354bd2SLeyi Rong #define SKETCH_TOTAL_KEY 500
122db354bd2SLeyi Rong #define NUM_OF_KEY(key) {\
123db354bd2SLeyi Rong 	(unsigned int)ceil(SKETCH_LARGEST_KEY_SIZE / (key + 1)) \
124db354bd2SLeyi Rong }
125db354bd2SLeyi Rong 
126db354bd2SLeyi Rong void *heavy_hitters[TOP_K];
127db354bd2SLeyi Rong 
128a9de470cSBruce Richardson /*
129a9de470cSBruce Richardson  * Sequence of operations for find existing setsummary
130a9de470cSBruce Richardson  *
131a9de470cSBruce Richardson  *  - create setsum
132a9de470cSBruce Richardson  *  - find existing setsum: hit
133a9de470cSBruce Richardson  *  - find non-existing setsum: miss
134a9de470cSBruce Richardson  *
135a9de470cSBruce Richardson  */
136a9de470cSBruce Richardson static int
137a9de470cSBruce Richardson test_member_find_existing(void)
138a9de470cSBruce Richardson {
139a9de470cSBruce Richardson 	struct rte_member_setsum *tmp_setsum = NULL, *result = NULL;
140a9de470cSBruce Richardson 	struct rte_member_parameters tmp_params = {
141a9de470cSBruce Richardson 		.name = "member_find_existing",
142a9de470cSBruce Richardson 		.num_keys = MAX_ENTRIES,	/* Total hash table entries. */
143a9de470cSBruce Richardson 		.key_len = KEY_SIZE,		/* Length of hash key. */
144a9de470cSBruce Richardson 		.type = RTE_MEMBER_TYPE_HT,
145a9de470cSBruce Richardson 		.num_set = 32,
146a9de470cSBruce Richardson 		.false_positive_rate = 0.03,
147a9de470cSBruce Richardson 		.prim_hash_seed = 1,
148a9de470cSBruce Richardson 		.sec_hash_seed = 11,
149a9de470cSBruce Richardson 		.socket_id = 0			/* NUMA Socket ID for memory. */
150a9de470cSBruce Richardson 	};
151a9de470cSBruce Richardson 
152a9de470cSBruce Richardson 	/* Create */
153a9de470cSBruce Richardson 	tmp_setsum = rte_member_create(&tmp_params);
154a9de470cSBruce Richardson 	TEST_ASSERT(tmp_setsum != NULL, "setsum creation failed");
155a9de470cSBruce Richardson 
156a9de470cSBruce Richardson 	/* Try to find existing hash table */
157a9de470cSBruce Richardson 	result = rte_member_find_existing("member_find_existing");
158a9de470cSBruce Richardson 	TEST_ASSERT(result == tmp_setsum, "could not find existing setsum");
159a9de470cSBruce Richardson 
160a9de470cSBruce Richardson 	/* Try to find non-existing hash table */
161a9de470cSBruce Richardson 	result = rte_member_find_existing("member_find_non_existing");
162a9de470cSBruce Richardson 	TEST_ASSERT(result == NULL, "found setsum that shouldn't exist");
163a9de470cSBruce Richardson 
164a9de470cSBruce Richardson 	/* Cleanup. */
165a9de470cSBruce Richardson 	rte_member_free(tmp_setsum);
166a9de470cSBruce Richardson 
167a9de470cSBruce Richardson 	return 0;
168a9de470cSBruce Richardson }
169a9de470cSBruce Richardson 
170a9de470cSBruce Richardson /*
171a9de470cSBruce Richardson  * Test for bad creating parameters
172a9de470cSBruce Richardson  */
173a9de470cSBruce Richardson static int
174a9de470cSBruce Richardson test_member_create_bad_param(void)
175a9de470cSBruce Richardson {
176a9de470cSBruce Richardson 	struct rte_member_setsum *bad_setsum = NULL;
177a9de470cSBruce Richardson 	struct rte_member_parameters bad_params = {
178a9de470cSBruce Richardson 		.num_keys = MAX_ENTRIES,	/* Total hash table entries. */
179a9de470cSBruce Richardson 		.key_len = KEY_SIZE,		/* Length of hash key. */
180a9de470cSBruce Richardson 		.type = RTE_MEMBER_TYPE_HT,
181a9de470cSBruce Richardson 		.num_set = 32,
182a9de470cSBruce Richardson 		.false_positive_rate = 0.03,
183a9de470cSBruce Richardson 		.prim_hash_seed = 1,
184a9de470cSBruce Richardson 		.sec_hash_seed = 11,
185a9de470cSBruce Richardson 		.socket_id = 0			/* NUMA Socket ID for memory. */
186a9de470cSBruce Richardson 	};
187a9de470cSBruce Richardson 
188a9de470cSBruce Richardson 	printf("Expected error section begin...\n");
189a9de470cSBruce Richardson 	bad_params.name = "bad_param1";
190a9de470cSBruce Richardson 	bad_params.num_set = 0;
191a9de470cSBruce Richardson 	bad_params.type = RTE_MEMBER_TYPE_VBF;
192a9de470cSBruce Richardson 	/* Test with 0 set for vBF should fail */
193a9de470cSBruce Richardson 	bad_setsum = rte_member_create(&bad_params);
194a9de470cSBruce Richardson 	if (bad_setsum != NULL) {
195a9de470cSBruce Richardson 		rte_member_free(bad_setsum);
196a9de470cSBruce Richardson 		printf("Impossible creating setsum successfully with invalid "
197a9de470cSBruce Richardson 			"number of set for vBF\n");
198a9de470cSBruce Richardson 		return -1;
199a9de470cSBruce Richardson 	}
200a9de470cSBruce Richardson 
201a9de470cSBruce Richardson 	bad_params.name = "bad_param2";
202a9de470cSBruce Richardson 	bad_params.false_positive_rate = 0;
203a9de470cSBruce Richardson 	bad_params.num_set = 32;
204a9de470cSBruce Richardson 	/* Test with 0 false positive for vBF should fail */
205a9de470cSBruce Richardson 	bad_setsum = rte_member_create(&bad_params);
206a9de470cSBruce Richardson 	if (bad_setsum != NULL) {
207a9de470cSBruce Richardson 		rte_member_free(bad_setsum);
208a9de470cSBruce Richardson 		printf("Impossible creating setsum successfully with invalid "
209a9de470cSBruce Richardson 			"false positive rate for vBF\n");
210a9de470cSBruce Richardson 		return -1;
211a9de470cSBruce Richardson 	}
212a9de470cSBruce Richardson 
213a9de470cSBruce Richardson 	bad_params.name = "bad_param3";
214a9de470cSBruce Richardson 	bad_params.false_positive_rate = 0.03;
215a9de470cSBruce Richardson 	bad_params.num_keys = 0;
216a9de470cSBruce Richardson 	/* Test with 0 key per BF for vBF should fail */
217a9de470cSBruce Richardson 	bad_setsum = rte_member_create(&bad_params);
218a9de470cSBruce Richardson 	if (bad_setsum != NULL) {
219a9de470cSBruce Richardson 		rte_member_free(bad_setsum);
220a9de470cSBruce Richardson 		printf("Impossible creating setsum successfully with invalid "
221a9de470cSBruce Richardson 			"num_keys for vBF\n");
222a9de470cSBruce Richardson 		return -1;
223a9de470cSBruce Richardson 	}
224a9de470cSBruce Richardson 
225a9de470cSBruce Richardson 	bad_params.name = "bad_param4";
226a9de470cSBruce Richardson 	bad_params.type = RTE_MEMBER_TYPE_HT;
227a9de470cSBruce Richardson 	bad_params.num_keys = RTE_MEMBER_BUCKET_ENTRIES / 2;
228a9de470cSBruce Richardson 	/* Test with less than 1 bucket for HTSS should fail */
229a9de470cSBruce Richardson 	bad_setsum = rte_member_create(&bad_params);
230a9de470cSBruce Richardson 	if (bad_setsum != NULL) {
231a9de470cSBruce Richardson 		rte_member_free(bad_setsum);
232a9de470cSBruce Richardson 		printf("Impossible creating setsum successfully with too few "
233a9de470cSBruce Richardson 			"number of keys(entries) for HT\n");
234a9de470cSBruce Richardson 		return -1;
235a9de470cSBruce Richardson 	}
236a9de470cSBruce Richardson 
237a9de470cSBruce Richardson 	bad_params.name = "bad_param5";
238a9de470cSBruce Richardson 	bad_params.num_keys = RTE_MEMBER_ENTRIES_MAX + 1;
239a9de470cSBruce Richardson 	/* Test with more than maximum entries for HTSS should fail */
240a9de470cSBruce Richardson 	bad_setsum = rte_member_create(&bad_params);
241a9de470cSBruce Richardson 	if (bad_setsum != NULL) {
242a9de470cSBruce Richardson 		rte_member_free(bad_setsum);
243a9de470cSBruce Richardson 		printf("Impossible creating setsum successfully with to many "
244a9de470cSBruce Richardson 			"number of keys(entries) for HT\n");
245a9de470cSBruce Richardson 		return -1;
246a9de470cSBruce Richardson 	}
247a9de470cSBruce Richardson 
248a9de470cSBruce Richardson 	bad_params.name = "bad_param5";
249a9de470cSBruce Richardson 	/* Test with same name should fail */
250a9de470cSBruce Richardson 	bad_setsum = rte_member_create(&bad_params);
251a9de470cSBruce Richardson 	if (bad_setsum != NULL) {
252a9de470cSBruce Richardson 		rte_member_free(bad_setsum);
253a9de470cSBruce Richardson 		printf("Impossible creating setsum successfully with existed "
254a9de470cSBruce Richardson 			"name\n");
255a9de470cSBruce Richardson 		return -1;
256a9de470cSBruce Richardson 	}
257a9de470cSBruce Richardson 	printf("Expected error section end...\n");
258a9de470cSBruce Richardson 	rte_member_free(bad_setsum);
259a9de470cSBruce Richardson 	return 0;
260a9de470cSBruce Richardson }
261a9de470cSBruce Richardson 
262a9de470cSBruce Richardson /* Create test setsummaries. */
263a9de470cSBruce Richardson static int test_member_create(void)
264a9de470cSBruce Richardson {
265a9de470cSBruce Richardson 	params.key_len = sizeof(struct flow_key);
266a9de470cSBruce Richardson 
267a9de470cSBruce Richardson 	params.name = "test_member_ht";
268a9de470cSBruce Richardson 	params.is_cache = 0;
269a9de470cSBruce Richardson 	params.type = RTE_MEMBER_TYPE_HT;
270a9de470cSBruce Richardson 	setsum_ht = rte_member_create(&params);
271a9de470cSBruce Richardson 
272a9de470cSBruce Richardson 	params.name = "test_member_cache";
273a9de470cSBruce Richardson 	params.is_cache = 1;
274a9de470cSBruce Richardson 	setsum_cache = rte_member_create(&params);
275a9de470cSBruce Richardson 
276a9de470cSBruce Richardson 	params.name = "test_member_vbf";
277a9de470cSBruce Richardson 	params.type = RTE_MEMBER_TYPE_VBF;
278a9de470cSBruce Richardson 	setsum_vbf = rte_member_create(&params);
279a9de470cSBruce Richardson 
280a9de470cSBruce Richardson 	if (setsum_ht == NULL || setsum_cache == NULL || setsum_vbf == NULL) {
281a9de470cSBruce Richardson 		printf("Creation of setsums fail\n");
282a9de470cSBruce Richardson 		return -1;
283a9de470cSBruce Richardson 	}
284a9de470cSBruce Richardson 	printf("Creation of setsums success\n");
285a9de470cSBruce Richardson 	return 0;
286a9de470cSBruce Richardson }
287a9de470cSBruce Richardson 
288a9de470cSBruce Richardson static int test_member_insert(void)
289a9de470cSBruce Richardson {
290a9de470cSBruce Richardson 	int ret_ht, ret_cache, ret_vbf, i;
291a9de470cSBruce Richardson 
292a9de470cSBruce Richardson 	for (i = 0; i < NUM_SAMPLES; i++) {
293a9de470cSBruce Richardson 		ret_ht = rte_member_add(setsum_ht, &keys[i], test_set[i]);
294a9de470cSBruce Richardson 		ret_cache = rte_member_add(setsum_cache, &keys[i],
295a9de470cSBruce Richardson 						test_set[i]);
296a9de470cSBruce Richardson 		ret_vbf = rte_member_add(setsum_vbf, &keys[i], test_set[i]);
297a9de470cSBruce Richardson 		TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0 && ret_vbf >= 0,
298a9de470cSBruce Richardson 				"insert error");
299a9de470cSBruce Richardson 	}
300a9de470cSBruce Richardson 	printf("insert key success\n");
301a9de470cSBruce Richardson 	return 0;
302a9de470cSBruce Richardson }
303a9de470cSBruce Richardson 
304a9de470cSBruce Richardson static int test_member_lookup(void)
305a9de470cSBruce Richardson {
306a9de470cSBruce Richardson 	int ret_ht, ret_cache, ret_vbf, i;
307a9de470cSBruce Richardson 	uint16_t set_ht, set_cache, set_vbf;
308a9de470cSBruce Richardson 	member_set_t set_ids_ht[NUM_SAMPLES] = {0};
309a9de470cSBruce Richardson 	member_set_t set_ids_cache[NUM_SAMPLES] = {0};
310a9de470cSBruce Richardson 	member_set_t set_ids_vbf[NUM_SAMPLES] = {0};
311a9de470cSBruce Richardson 
312a9de470cSBruce Richardson 	uint32_t num_key_ht = NUM_SAMPLES;
313a9de470cSBruce Richardson 	uint32_t num_key_cache = NUM_SAMPLES;
314a9de470cSBruce Richardson 	uint32_t num_key_vbf = NUM_SAMPLES;
315a9de470cSBruce Richardson 
316a9de470cSBruce Richardson 	const void *key_array[NUM_SAMPLES];
317a9de470cSBruce Richardson 
318a9de470cSBruce Richardson 	/* Single lookup test */
319a9de470cSBruce Richardson 	for (i = 0; i < NUM_SAMPLES; i++) {
320a9de470cSBruce Richardson 		ret_ht = rte_member_lookup(setsum_ht, &keys[i], &set_ht);
321a9de470cSBruce Richardson 		ret_cache = rte_member_lookup(setsum_cache, &keys[i],
322a9de470cSBruce Richardson 							&set_cache);
323a9de470cSBruce Richardson 		ret_vbf = rte_member_lookup(setsum_vbf, &keys[i], &set_vbf);
324a9de470cSBruce Richardson 		TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0 && ret_vbf >= 0,
325a9de470cSBruce Richardson 				"single lookup function error");
326a9de470cSBruce Richardson 
327a9de470cSBruce Richardson 		TEST_ASSERT(set_ht == test_set[i] &&
328a9de470cSBruce Richardson 				set_cache == test_set[i] &&
329a9de470cSBruce Richardson 				set_vbf == test_set[i],
330a9de470cSBruce Richardson 				"single lookup set value error");
331a9de470cSBruce Richardson 	}
332a9de470cSBruce Richardson 	printf("lookup single key success\n");
333a9de470cSBruce Richardson 
334a9de470cSBruce Richardson 	/* Bulk lookup test */
335a9de470cSBruce Richardson 	for (i = 0; i < NUM_SAMPLES; i++)
336a9de470cSBruce Richardson 		key_array[i] = &keys[i];
337a9de470cSBruce Richardson 
338a9de470cSBruce Richardson 	ret_ht = rte_member_lookup_bulk(setsum_ht, key_array,
339a9de470cSBruce Richardson 			num_key_ht, set_ids_ht);
340a9de470cSBruce Richardson 
341a9de470cSBruce Richardson 	ret_cache = rte_member_lookup_bulk(setsum_cache, key_array,
342a9de470cSBruce Richardson 			num_key_cache, set_ids_cache);
343a9de470cSBruce Richardson 
344a9de470cSBruce Richardson 	ret_vbf = rte_member_lookup_bulk(setsum_vbf, key_array,
345a9de470cSBruce Richardson 			num_key_vbf, set_ids_vbf);
346a9de470cSBruce Richardson 
347a9de470cSBruce Richardson 	TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0 && ret_vbf >= 0,
348a9de470cSBruce Richardson 			"bulk lookup function error");
349a9de470cSBruce Richardson 
350a9de470cSBruce Richardson 	for (i = 0; i < NUM_SAMPLES; i++) {
351a9de470cSBruce Richardson 		TEST_ASSERT((set_ids_ht[i] == test_set[i]) &&
352a9de470cSBruce Richardson 				(set_ids_cache[i] == test_set[i]) &&
353a9de470cSBruce Richardson 				(set_ids_vbf[i] == test_set[i]),
354a9de470cSBruce Richardson 				"bulk lookup result error");
355a9de470cSBruce Richardson 	}
356a9de470cSBruce Richardson 
357a9de470cSBruce Richardson 	return 0;
358a9de470cSBruce Richardson }
359a9de470cSBruce Richardson 
360a9de470cSBruce Richardson static int test_member_delete(void)
361a9de470cSBruce Richardson {
362a9de470cSBruce Richardson 	int ret_ht, ret_cache, ret_vbf, i;
363a9de470cSBruce Richardson 	uint16_t set_ht, set_cache, set_vbf;
364a9de470cSBruce Richardson 	const void *key_array[NUM_SAMPLES];
365a9de470cSBruce Richardson 	member_set_t set_ids_ht[NUM_SAMPLES] = {0};
366a9de470cSBruce Richardson 	member_set_t set_ids_cache[NUM_SAMPLES] = {0};
367a9de470cSBruce Richardson 	member_set_t set_ids_vbf[NUM_SAMPLES] = {0};
368a9de470cSBruce Richardson 	uint32_t num_key_ht = NUM_SAMPLES;
369a9de470cSBruce Richardson 	uint32_t num_key_cache = NUM_SAMPLES;
370a9de470cSBruce Richardson 	uint32_t num_key_vbf = NUM_SAMPLES;
371a9de470cSBruce Richardson 
372a9de470cSBruce Richardson 	/* Delete part of all inserted keys */
373a9de470cSBruce Richardson 	for (i = 0; i < NUM_SAMPLES / 2; i++) {
374a9de470cSBruce Richardson 		ret_ht = rte_member_delete(setsum_ht, &keys[i], test_set[i]);
375a9de470cSBruce Richardson 		ret_cache = rte_member_delete(setsum_cache, &keys[i],
376a9de470cSBruce Richardson 						test_set[i]);
377a9de470cSBruce Richardson 		ret_vbf = rte_member_delete(setsum_vbf, &keys[i], test_set[i]);
378a9de470cSBruce Richardson 		/* VBF does not support delete yet, so return error code */
379a9de470cSBruce Richardson 		TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0,
380a9de470cSBruce Richardson 				"key deletion function error");
381a9de470cSBruce Richardson 		TEST_ASSERT(ret_vbf < 0,
382a9de470cSBruce Richardson 				"vbf does not support deletion, error");
383a9de470cSBruce Richardson 	}
384a9de470cSBruce Richardson 
385a9de470cSBruce Richardson 	for (i = 0; i < NUM_SAMPLES; i++)
386a9de470cSBruce Richardson 		key_array[i] = &keys[i];
387a9de470cSBruce Richardson 
388a9de470cSBruce Richardson 	ret_ht = rte_member_lookup_bulk(setsum_ht, key_array,
389a9de470cSBruce Richardson 			num_key_ht, set_ids_ht);
390a9de470cSBruce Richardson 
391a9de470cSBruce Richardson 	ret_cache = rte_member_lookup_bulk(setsum_cache, key_array,
392a9de470cSBruce Richardson 			num_key_cache, set_ids_cache);
393a9de470cSBruce Richardson 
394a9de470cSBruce Richardson 	ret_vbf = rte_member_lookup_bulk(setsum_vbf, key_array,
395a9de470cSBruce Richardson 			num_key_vbf, set_ids_vbf);
396a9de470cSBruce Richardson 
397a9de470cSBruce Richardson 	TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0 && ret_vbf >= 0,
398a9de470cSBruce Richardson 			"bulk lookup function error");
399a9de470cSBruce Richardson 
400a9de470cSBruce Richardson 	for (i = 0; i < NUM_SAMPLES / 2; i++) {
401a9de470cSBruce Richardson 		TEST_ASSERT((set_ids_ht[i] == RTE_MEMBER_NO_MATCH) &&
402a9de470cSBruce Richardson 				(set_ids_cache[i] == RTE_MEMBER_NO_MATCH),
403a9de470cSBruce Richardson 				"bulk lookup result error");
404a9de470cSBruce Richardson 	}
405a9de470cSBruce Richardson 
406a9de470cSBruce Richardson 	for (i = NUM_SAMPLES / 2; i < NUM_SAMPLES; i++) {
407a9de470cSBruce Richardson 		TEST_ASSERT((set_ids_ht[i] == test_set[i]) &&
408a9de470cSBruce Richardson 				(set_ids_cache[i] == test_set[i]) &&
409a9de470cSBruce Richardson 				(set_ids_vbf[i] == test_set[i]),
410a9de470cSBruce Richardson 				"bulk lookup result error");
411a9de470cSBruce Richardson 	}
412a9de470cSBruce Richardson 
413a9de470cSBruce Richardson 	/* Delete the left of inserted keys */
414a9de470cSBruce Richardson 	for (i = NUM_SAMPLES / 2; i < NUM_SAMPLES; i++) {
415a9de470cSBruce Richardson 		ret_ht = rte_member_delete(setsum_ht, &keys[i], test_set[i]);
416a9de470cSBruce Richardson 		ret_cache = rte_member_delete(setsum_cache, &keys[i],
417a9de470cSBruce Richardson 						test_set[i]);
418a9de470cSBruce Richardson 		ret_vbf = rte_member_delete(setsum_vbf, &keys[i], test_set[i]);
419a9de470cSBruce Richardson 		/* VBF does not support delete yet, so return error code */
420a9de470cSBruce Richardson 		TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0,
421a9de470cSBruce Richardson 				"key deletion function error");
422a9de470cSBruce Richardson 		TEST_ASSERT(ret_vbf < 0,
423a9de470cSBruce Richardson 				"vbf does not support deletion, error");
424a9de470cSBruce Richardson 	}
425a9de470cSBruce Richardson 
426a9de470cSBruce Richardson 	for (i = 0; i < NUM_SAMPLES; i++) {
427a9de470cSBruce Richardson 		ret_ht = rte_member_lookup(setsum_ht, &keys[i], &set_ht);
428a9de470cSBruce Richardson 		ret_cache = rte_member_lookup(setsum_cache, &keys[i],
429a9de470cSBruce Richardson 						&set_cache);
430a9de470cSBruce Richardson 		ret_vbf = rte_member_lookup(setsum_vbf, &keys[i], &set_vbf);
431a9de470cSBruce Richardson 		TEST_ASSERT(ret_ht >= 0 && ret_cache >= 0,
432a9de470cSBruce Richardson 				"key lookup function error");
433a9de470cSBruce Richardson 		TEST_ASSERT(set_ht == RTE_MEMBER_NO_MATCH &&
434a9de470cSBruce Richardson 				ret_cache == RTE_MEMBER_NO_MATCH,
435a9de470cSBruce Richardson 				"key deletion failed");
436a9de470cSBruce Richardson 	}
437a9de470cSBruce Richardson 	/* Reset vbf for other following tests */
438a9de470cSBruce Richardson 	rte_member_reset(setsum_vbf);
439a9de470cSBruce Richardson 
440a9de470cSBruce Richardson 	printf("delete success\n");
441a9de470cSBruce Richardson 	return 0;
442a9de470cSBruce Richardson }
443a9de470cSBruce Richardson 
444a9de470cSBruce Richardson static int test_member_multimatch(void)
445a9de470cSBruce Richardson {
446a9de470cSBruce Richardson 	int ret_ht, ret_vbf, ret_cache;
447a9de470cSBruce Richardson 	member_set_t set_ids_ht[MAX_MATCH] = {0};
448a9de470cSBruce Richardson 	member_set_t set_ids_vbf[MAX_MATCH] = {0};
449a9de470cSBruce Richardson 	member_set_t set_ids_cache[MAX_MATCH] = {0};
450a9de470cSBruce Richardson 
451a9de470cSBruce Richardson 	member_set_t set_ids_ht_m[NUM_SAMPLES][MAX_MATCH] = {{0} };
452a9de470cSBruce Richardson 	member_set_t set_ids_vbf_m[NUM_SAMPLES][MAX_MATCH] = {{0} };
453a9de470cSBruce Richardson 	member_set_t set_ids_cache_m[NUM_SAMPLES][MAX_MATCH] = {{0} };
454a9de470cSBruce Richardson 
455a9de470cSBruce Richardson 	uint32_t match_count_ht[NUM_SAMPLES];
456a9de470cSBruce Richardson 	uint32_t match_count_vbf[NUM_SAMPLES];
457a9de470cSBruce Richardson 	uint32_t match_count_cache[NUM_SAMPLES];
458a9de470cSBruce Richardson 
459a9de470cSBruce Richardson 	uint32_t num_key_ht = NUM_SAMPLES;
460a9de470cSBruce Richardson 	uint32_t num_key_vbf = NUM_SAMPLES;
461a9de470cSBruce Richardson 	uint32_t num_key_cache = NUM_SAMPLES;
462a9de470cSBruce Richardson 
463a9de470cSBruce Richardson 	const void *key_array[NUM_SAMPLES];
464a9de470cSBruce Richardson 
465a9de470cSBruce Richardson 	uint32_t i, j;
466a9de470cSBruce Richardson 
467a9de470cSBruce Richardson 	/* Same key at most inserted 2*entry_per_bucket times for HT mode */
468a9de470cSBruce Richardson 	for (i = M_MATCH_S; i <= M_MATCH_E; i += M_MATCH_STEP) {
469a9de470cSBruce Richardson 		for (j = 0; j < NUM_SAMPLES; j++) {
470a9de470cSBruce Richardson 			ret_ht = rte_member_add(setsum_ht, &keys[j], i);
471a9de470cSBruce Richardson 			ret_vbf = rte_member_add(setsum_vbf, &keys[j], i);
472a9de470cSBruce Richardson 			ret_cache = rte_member_add(setsum_cache, &keys[j], i);
473a9de470cSBruce Richardson 
474a9de470cSBruce Richardson 			TEST_ASSERT(ret_ht >= 0 && ret_vbf >= 0 &&
475a9de470cSBruce Richardson 					ret_cache >= 0,
476a9de470cSBruce Richardson 					"insert function error");
477a9de470cSBruce Richardson 		}
478a9de470cSBruce Richardson 	}
479a9de470cSBruce Richardson 
480a9de470cSBruce Richardson 	/* Single multimatch test */
481a9de470cSBruce Richardson 	for (i = 0; i < NUM_SAMPLES; i++) {
482a9de470cSBruce Richardson 		ret_vbf = rte_member_lookup_multi(setsum_vbf, &keys[i],
483a9de470cSBruce Richardson 							MAX_MATCH, set_ids_vbf);
484a9de470cSBruce Richardson 		ret_ht = rte_member_lookup_multi(setsum_ht, &keys[i],
485a9de470cSBruce Richardson 							MAX_MATCH, set_ids_ht);
486a9de470cSBruce Richardson 		ret_cache = rte_member_lookup_multi(setsum_cache, &keys[i],
487a9de470cSBruce Richardson 						MAX_MATCH, set_ids_cache);
488a9de470cSBruce Richardson 		/*
489a9de470cSBruce Richardson 		 * For cache mode, keys overwrite when signature same.
4907be78d02SJosh Soref 		 * the multimatch should work like single match.
491a9de470cSBruce Richardson 		 */
492a9de470cSBruce Richardson 		TEST_ASSERT(ret_ht == M_MATCH_CNT && ret_vbf == M_MATCH_CNT &&
493a9de470cSBruce Richardson 				ret_cache == 1,
494a9de470cSBruce Richardson 				"single lookup_multi error");
495a9de470cSBruce Richardson 		TEST_ASSERT(set_ids_cache[0] == M_MATCH_E,
496a9de470cSBruce Richardson 				"single lookup_multi cache error");
497a9de470cSBruce Richardson 
498a9de470cSBruce Richardson 		for (j = 1; j <= M_MATCH_CNT; j++) {
499a9de470cSBruce Richardson 			TEST_ASSERT(set_ids_ht[j-1] == j * M_MATCH_STEP - 1 &&
500a9de470cSBruce Richardson 					set_ids_vbf[j-1] ==
501a9de470cSBruce Richardson 							j * M_MATCH_STEP - 1,
502a9de470cSBruce Richardson 					"single multimatch lookup error");
503a9de470cSBruce Richardson 		}
504a9de470cSBruce Richardson 	}
505a9de470cSBruce Richardson 	printf("lookup single key for multimatch success\n");
506a9de470cSBruce Richardson 
507a9de470cSBruce Richardson 	/* Bulk multimatch test */
508a9de470cSBruce Richardson 	for (i = 0; i < NUM_SAMPLES; i++)
509a9de470cSBruce Richardson 		key_array[i] = &keys[i];
510a9de470cSBruce Richardson 	ret_vbf = rte_member_lookup_multi_bulk(setsum_vbf,
511a9de470cSBruce Richardson 			&key_array[0], num_key_ht, MAX_MATCH, match_count_vbf,
512a9de470cSBruce Richardson 			(member_set_t *)set_ids_vbf_m);
513a9de470cSBruce Richardson 
514a9de470cSBruce Richardson 	ret_ht = rte_member_lookup_multi_bulk(setsum_ht,
515a9de470cSBruce Richardson 			&key_array[0], num_key_vbf, MAX_MATCH, match_count_ht,
516a9de470cSBruce Richardson 			(member_set_t *)set_ids_ht_m);
517a9de470cSBruce Richardson 
518a9de470cSBruce Richardson 	ret_cache = rte_member_lookup_multi_bulk(setsum_cache,
519a9de470cSBruce Richardson 			&key_array[0], num_key_cache, MAX_MATCH,
520a9de470cSBruce Richardson 			match_count_cache, (member_set_t *)set_ids_cache_m);
521a9de470cSBruce Richardson 
522a9de470cSBruce Richardson 
523a9de470cSBruce Richardson 	for (j = 0; j < NUM_SAMPLES; j++) {
524a9de470cSBruce Richardson 		TEST_ASSERT(match_count_ht[j] == M_MATCH_CNT,
525a9de470cSBruce Richardson 			"bulk multimatch lookup HT match count error");
526a9de470cSBruce Richardson 		TEST_ASSERT(match_count_vbf[j] == M_MATCH_CNT,
527a9de470cSBruce Richardson 			"bulk multimatch lookup vBF match count error");
528a9de470cSBruce Richardson 		TEST_ASSERT(match_count_cache[j] == 1,
529a9de470cSBruce Richardson 			"bulk multimatch lookup CACHE match count error");
530a9de470cSBruce Richardson 		TEST_ASSERT(set_ids_cache_m[j][0] == M_MATCH_E,
531a9de470cSBruce Richardson 			"bulk multimatch lookup CACHE set value error");
532a9de470cSBruce Richardson 
533a9de470cSBruce Richardson 		for (i = 1; i <= M_MATCH_CNT; i++) {
534a9de470cSBruce Richardson 			TEST_ASSERT(set_ids_ht_m[j][i-1] ==
535a9de470cSBruce Richardson 							i * M_MATCH_STEP - 1,
536a9de470cSBruce Richardson 				"bulk multimatch lookup HT set value error");
537a9de470cSBruce Richardson 			TEST_ASSERT(set_ids_vbf_m[j][i-1] ==
538a9de470cSBruce Richardson 							i * M_MATCH_STEP - 1,
539a9de470cSBruce Richardson 				"bulk multimatch lookup vBF set value error");
540a9de470cSBruce Richardson 		}
541a9de470cSBruce Richardson 	}
542a9de470cSBruce Richardson 
543a9de470cSBruce Richardson 	printf("lookup for bulk multimatch success\n");
544a9de470cSBruce Richardson 
545a9de470cSBruce Richardson 	return 0;
546a9de470cSBruce Richardson }
547a9de470cSBruce Richardson 
548a9de470cSBruce Richardson static int key_compare(const void *key1, const void *key2)
549a9de470cSBruce Richardson {
550a9de470cSBruce Richardson 	return memcmp(key1, key2, KEY_SIZE);
551a9de470cSBruce Richardson }
552a9de470cSBruce Richardson 
553a9de470cSBruce Richardson static void
554a9de470cSBruce Richardson setup_keys_and_data(void)
555a9de470cSBruce Richardson {
556a9de470cSBruce Richardson 	unsigned int i, j;
557a9de470cSBruce Richardson 	int num_duplicates;
558a9de470cSBruce Richardson 
559a9de470cSBruce Richardson 	/* Reset all arrays */
560a9de470cSBruce Richardson 	for (i = 0; i < KEY_SIZE; i++)
561a9de470cSBruce Richardson 		generated_keys[0][i] = 0;
562a9de470cSBruce Richardson 
563a9de470cSBruce Richardson 	/* Generate a list of keys, some of which may be duplicates */
564a9de470cSBruce Richardson 	for (i = 0; i < MAX_ENTRIES; i++) {
565a9de470cSBruce Richardson 		for (j = 0; j < KEY_SIZE; j++)
566a9de470cSBruce Richardson 			generated_keys[i][j] = rte_rand() & 0xFF;
567a9de470cSBruce Richardson 	}
568a9de470cSBruce Richardson 
569a9de470cSBruce Richardson 	/* Remove duplicates from the keys array */
570a9de470cSBruce Richardson 	do {
571a9de470cSBruce Richardson 		num_duplicates = 0;
572a9de470cSBruce Richardson 		/* Sort the list of keys to make it easier to find duplicates */
573a9de470cSBruce Richardson 		qsort(generated_keys, MAX_ENTRIES, KEY_SIZE, key_compare);
574a9de470cSBruce Richardson 
575a9de470cSBruce Richardson 		/* Sift through the list of keys and look for duplicates */
576a9de470cSBruce Richardson 		for (i = 0; i < MAX_ENTRIES - 1; i++) {
577a9de470cSBruce Richardson 			if (memcmp(generated_keys[i], generated_keys[i + 1],
578a9de470cSBruce Richardson 					KEY_SIZE) == 0) {
579a9de470cSBruce Richardson 				/* This key already exists, try again */
580a9de470cSBruce Richardson 				num_duplicates++;
581a9de470cSBruce Richardson 				for (j = 0; j < KEY_SIZE; j++)
582a9de470cSBruce Richardson 					generated_keys[i][j] =
583a9de470cSBruce Richardson 							rte_rand() & 0xFF;
584a9de470cSBruce Richardson 			}
585a9de470cSBruce Richardson 		}
586a9de470cSBruce Richardson 	} while (num_duplicates != 0);
587a9de470cSBruce Richardson }
588a9de470cSBruce Richardson 
589a9de470cSBruce Richardson static inline int
590a9de470cSBruce Richardson add_generated_keys(struct rte_member_setsum *setsum, unsigned int *added_keys)
591a9de470cSBruce Richardson {
592a9de470cSBruce Richardson 	int ret = 0;
593a9de470cSBruce Richardson 
594a9de470cSBruce Richardson 	for (*added_keys = 0; ret >= 0 && *added_keys < MAX_ENTRIES;
595a9de470cSBruce Richardson 			(*added_keys)++) {
596a9de470cSBruce Richardson 		uint16_t set = (rte_rand() & 0xf) + 1;
597a9de470cSBruce Richardson 		ret = rte_member_add(setsum, &generated_keys[*added_keys], set);
598a9de470cSBruce Richardson 	}
599a9de470cSBruce Richardson 	return ret;
600a9de470cSBruce Richardson }
601a9de470cSBruce Richardson 
602a9de470cSBruce Richardson static inline int
603a9de470cSBruce Richardson add_generated_keys_cache(struct rte_member_setsum *setsum,
604a9de470cSBruce Richardson 				unsigned int *added_keys)
605a9de470cSBruce Richardson {
606a9de470cSBruce Richardson 	int ret = 0;
607a9de470cSBruce Richardson 
608a9de470cSBruce Richardson 	for (*added_keys = 0; ret == 0 && *added_keys < MAX_ENTRIES;
609a9de470cSBruce Richardson 			(*added_keys)++) {
610a9de470cSBruce Richardson 		uint16_t set = (rte_rand() & 0xf) + 1;
611a9de470cSBruce Richardson 		ret = rte_member_add(setsum, &generated_keys[*added_keys], set);
612a9de470cSBruce Richardson 	}
613a9de470cSBruce Richardson 	return ret;
614a9de470cSBruce Richardson }
615a9de470cSBruce Richardson 
616a9de470cSBruce Richardson static int
617a9de470cSBruce Richardson test_member_loadfactor(void)
618a9de470cSBruce Richardson {
619a9de470cSBruce Richardson 	unsigned  int j;
620a9de470cSBruce Richardson 	unsigned int added_keys, average_keys_added = 0;
621a9de470cSBruce Richardson 	int ret;
622a9de470cSBruce Richardson 
623a9de470cSBruce Richardson 	setup_keys_and_data();
624a9de470cSBruce Richardson 
625a9de470cSBruce Richardson 	rte_member_free(setsum_ht);
626a9de470cSBruce Richardson 	rte_member_free(setsum_cache);
627a9de470cSBruce Richardson 	rte_member_free(setsum_vbf);
628a9de470cSBruce Richardson 
629a9de470cSBruce Richardson 	params.key_len = KEY_SIZE;
630a9de470cSBruce Richardson 	params.name = "test_member_ht";
631a9de470cSBruce Richardson 	params.is_cache = 0;
632a9de470cSBruce Richardson 	params.type = RTE_MEMBER_TYPE_HT;
633a9de470cSBruce Richardson 	setsum_ht = rte_member_create(&params);
634a9de470cSBruce Richardson 
635a9de470cSBruce Richardson 	params.name = "test_member_cache";
636a9de470cSBruce Richardson 	params.is_cache = 1;
637a9de470cSBruce Richardson 	setsum_cache = rte_member_create(&params);
638a9de470cSBruce Richardson 
639a9de470cSBruce Richardson 
640a9de470cSBruce Richardson 	if (setsum_ht == NULL || setsum_cache == NULL) {
641a9de470cSBruce Richardson 		printf("Creation of setsums fail\n");
642a9de470cSBruce Richardson 		return -1;
643a9de470cSBruce Richardson 	}
644a9de470cSBruce Richardson 	/* Test HT non-cache mode */
645a9de470cSBruce Richardson 	for (j = 0; j < ITERATIONS; j++) {
646a9de470cSBruce Richardson 		/* Add random entries until key cannot be added */
647a9de470cSBruce Richardson 		ret = add_generated_keys(setsum_ht, &added_keys);
648a9de470cSBruce Richardson 		if (ret != -ENOSPC) {
649a9de470cSBruce Richardson 			printf("Unexpected error when adding keys\n");
650a9de470cSBruce Richardson 			return -1;
651a9de470cSBruce Richardson 		}
652a9de470cSBruce Richardson 		average_keys_added += added_keys;
653a9de470cSBruce Richardson 
654a9de470cSBruce Richardson 		/* Reset the table */
655a9de470cSBruce Richardson 		rte_member_reset(setsum_ht);
656a9de470cSBruce Richardson 
657a9de470cSBruce Richardson 		/* Print a dot to show progress on operations */
658a9de470cSBruce Richardson 		printf(".");
659a9de470cSBruce Richardson 		fflush(stdout);
660a9de470cSBruce Richardson 	}
661a9de470cSBruce Richardson 
662a9de470cSBruce Richardson 	average_keys_added /= ITERATIONS;
663a9de470cSBruce Richardson 
664a9de470cSBruce Richardson 	printf("\nKeys inserted when no space(non-cache) = %.2f%% (%u/%u)\n",
665a9de470cSBruce Richardson 		((double) average_keys_added / params.num_keys * 100),
666a9de470cSBruce Richardson 		average_keys_added, params.num_keys);
667a9de470cSBruce Richardson 
668a9de470cSBruce Richardson 	/* Test cache mode */
669a9de470cSBruce Richardson 	added_keys = average_keys_added = 0;
670a9de470cSBruce Richardson 	for (j = 0; j < ITERATIONS; j++) {
671a9de470cSBruce Richardson 		/* Add random entries until key cannot be added */
672a9de470cSBruce Richardson 		ret = add_generated_keys_cache(setsum_cache, &added_keys);
673a9de470cSBruce Richardson 		if (ret != 1) {
674a9de470cSBruce Richardson 			printf("Unexpected error when adding keys\n");
675a9de470cSBruce Richardson 			return -1;
676a9de470cSBruce Richardson 		}
677a9de470cSBruce Richardson 		average_keys_added += added_keys;
678a9de470cSBruce Richardson 
679a9de470cSBruce Richardson 		/* Reset the table */
680a9de470cSBruce Richardson 		rte_member_reset(setsum_cache);
681a9de470cSBruce Richardson 
682a9de470cSBruce Richardson 		/* Print a dot to show progress on operations */
683a9de470cSBruce Richardson 		printf(".");
684a9de470cSBruce Richardson 		fflush(stdout);
685a9de470cSBruce Richardson 	}
686a9de470cSBruce Richardson 
687a9de470cSBruce Richardson 	average_keys_added /= ITERATIONS;
688a9de470cSBruce Richardson 
689a9de470cSBruce Richardson 	printf("\nKeys inserted when eviction happens(cache)= %.2f%% (%u/%u)\n",
690a9de470cSBruce Richardson 		((double) average_keys_added / params.num_keys * 100),
691a9de470cSBruce Richardson 		average_keys_added, params.num_keys);
692a9de470cSBruce Richardson 	return 0;
693a9de470cSBruce Richardson }
694a9de470cSBruce Richardson 
695a9de470cSBruce Richardson static void
696a9de470cSBruce Richardson perform_free(void)
697a9de470cSBruce Richardson {
698a9de470cSBruce Richardson 	rte_member_free(setsum_ht);
699a9de470cSBruce Richardson 	rte_member_free(setsum_cache);
700a9de470cSBruce Richardson 	rte_member_free(setsum_vbf);
701a9de470cSBruce Richardson }
702a9de470cSBruce Richardson 
703db354bd2SLeyi Rong static void
704db354bd2SLeyi Rong print_out_sketch_results(uint64_t *count_result, member_set_t *heavy_set,
705db354bd2SLeyi Rong 			 uint32_t print_num, bool count_byte)
706db354bd2SLeyi Rong {
707db354bd2SLeyi Rong 	uint32_t i;
708db354bd2SLeyi Rong 
709db354bd2SLeyi Rong 	for (i = 0; i < print_num; i++) {
710db354bd2SLeyi Rong 		if (count_byte)
711db354bd2SLeyi Rong 			printf("key %2u, count %8"PRIu64", real count %8u, "
712db354bd2SLeyi Rong 				"heavy_set %u, deviation rate [%.04f]\n",
713db354bd2SLeyi Rong 				i, count_result[i],
714fe61babeSLeyi Rong 				(unsigned int)ceil((double)SKETCH_LARGEST_KEY_SIZE / (i + 1)) *
715db354bd2SLeyi Rong 				HH_PKT_SIZE,
716db354bd2SLeyi Rong 				heavy_set[i],
717fe61babeSLeyi Rong 				fabs((double)count_result[i] - (double)NUM_OF_KEY(i) * HH_PKT_SIZE) /
718fe61babeSLeyi Rong 				((double)NUM_OF_KEY(i) * HH_PKT_SIZE));
719db354bd2SLeyi Rong 		else
720db354bd2SLeyi Rong 			printf("key %2u, count %8"PRIu64", real count %8u, "
721db354bd2SLeyi Rong 				"heavy_set %u, deviation rate [%.04f]\n",
722db354bd2SLeyi Rong 				i, count_result[i],
723fe61babeSLeyi Rong 				(unsigned int)ceil((double)SKETCH_LARGEST_KEY_SIZE / (i + 1)),
724db354bd2SLeyi Rong 				heavy_set[i],
725fe61babeSLeyi Rong 				fabs((double)count_result[i] - (double)NUM_OF_KEY(i)) /
726fe61babeSLeyi Rong 				(double)NUM_OF_KEY(i));
727db354bd2SLeyi Rong 	}
728db354bd2SLeyi Rong }
729db354bd2SLeyi Rong 
730db354bd2SLeyi Rong static int
731db354bd2SLeyi Rong sketch_test(uint32_t *keys, uint32_t total_pkt, int count_byte, int reset_test)
732db354bd2SLeyi Rong {
733db354bd2SLeyi Rong 	uint32_t i;
734db354bd2SLeyi Rong 	uint64_t result_count[SKETCH_TOTAL_KEY];
735db354bd2SLeyi Rong 	member_set_t heavy_set[SKETCH_TOTAL_KEY];
736db354bd2SLeyi Rong 	uint64_t count[TOP_K];
737db354bd2SLeyi Rong 	int ret;
738db354bd2SLeyi Rong 	int hh_cnt;
739db354bd2SLeyi Rong 
740db354bd2SLeyi Rong 	setsum_sketch = rte_member_create(&params);
741db354bd2SLeyi Rong 	if (setsum_sketch == NULL) {
742db354bd2SLeyi Rong 		printf("Creation of setsums fail\n");
743db354bd2SLeyi Rong 		return -1;
744db354bd2SLeyi Rong 	}
745db354bd2SLeyi Rong 
746db354bd2SLeyi Rong 	for (i = 0; i < total_pkt; i++) {
747db354bd2SLeyi Rong 		if (count_byte)
748db354bd2SLeyi Rong 			ret = rte_member_add_byte_count(setsum_sketch, &keys[i], HH_PKT_SIZE);
749db354bd2SLeyi Rong 		else
750db354bd2SLeyi Rong 			ret = rte_member_add(setsum_sketch, &keys[i], 1);
751db354bd2SLeyi Rong 
752db354bd2SLeyi Rong 		if (ret < 0) {
753db354bd2SLeyi Rong 			printf("rte_member_add Failed! Error [%d]\n", ret);
754db354bd2SLeyi Rong 			rte_member_free(setsum_sketch);
755db354bd2SLeyi Rong 
756db354bd2SLeyi Rong 			return -1;
757db354bd2SLeyi Rong 		}
758db354bd2SLeyi Rong 	}
759db354bd2SLeyi Rong 
760db354bd2SLeyi Rong 	for (i = 0; i < SKETCH_TOTAL_KEY; i++) {
761db354bd2SLeyi Rong 		uint32_t tmp_key = i;
762db354bd2SLeyi Rong 
763db354bd2SLeyi Rong 		rte_member_query_count(setsum_sketch, (void *)&tmp_key, &result_count[i]);
764db354bd2SLeyi Rong 		rte_member_lookup(setsum_sketch, (void *)&tmp_key, &heavy_set[i]);
765db354bd2SLeyi Rong 	}
766db354bd2SLeyi Rong 
767db354bd2SLeyi Rong 	print_out_sketch_results(result_count, heavy_set, PRINT_OUT_COUNT, count_byte);
768db354bd2SLeyi Rong 
769db354bd2SLeyi Rong 	hh_cnt = rte_member_report_heavyhitter(setsum_sketch, heavy_hitters, count);
770db354bd2SLeyi Rong 	if (hh_cnt < 0) {
771db354bd2SLeyi Rong 		printf("sketch report heavy hitter error!");
772db354bd2SLeyi Rong 		rte_member_free(setsum_sketch);
773db354bd2SLeyi Rong 
774db354bd2SLeyi Rong 		return -1;
775db354bd2SLeyi Rong 	}
776db354bd2SLeyi Rong 
777db354bd2SLeyi Rong 	printf("Report heavy hitters:");
778db354bd2SLeyi Rong 	for (i = 0; i < (unsigned int)hh_cnt; i++) {
779db354bd2SLeyi Rong 		printf("%u: %"PRIu64"\t",
780db354bd2SLeyi Rong 			*((uint32_t *)heavy_hitters[i]), count[i]);
781db354bd2SLeyi Rong 	}
782db354bd2SLeyi Rong 	printf("\n");
783db354bd2SLeyi Rong 
784db354bd2SLeyi Rong 	if (reset_test) {
785db354bd2SLeyi Rong 		printf("\nEntering Sketch Reset Test Process!\n");
786db354bd2SLeyi Rong 		rte_member_reset(setsum_sketch);
787db354bd2SLeyi Rong 
788db354bd2SLeyi Rong 		/* after reset, check some key's count */
789db354bd2SLeyi Rong 		for (i = 0; i < SKETCH_TOTAL_KEY; i++) {
790db354bd2SLeyi Rong 			uint32_t tmp_key = i;
791db354bd2SLeyi Rong 
792db354bd2SLeyi Rong 			rte_member_query_count(setsum_sketch, (void *)&tmp_key, &result_count[i]);
793db354bd2SLeyi Rong 			rte_member_lookup(setsum_sketch, (void *)&tmp_key, &heavy_set[i]);
794db354bd2SLeyi Rong 		}
795db354bd2SLeyi Rong 
796db354bd2SLeyi Rong 		print_out_sketch_results(result_count, heavy_set, PRINT_OUT_COUNT, count_byte);
797db354bd2SLeyi Rong 
798db354bd2SLeyi Rong 		printf("\nReinsert keys after Sketch Reset!\n");
799db354bd2SLeyi Rong 		for (i = 0; i < total_pkt; i++) {
800db354bd2SLeyi Rong 			if (count_byte)
801db354bd2SLeyi Rong 				ret = rte_member_add_byte_count
802db354bd2SLeyi Rong 					(setsum_sketch, &keys[i], HH_PKT_SIZE);
803db354bd2SLeyi Rong 			else
804db354bd2SLeyi Rong 				ret = rte_member_add(setsum_sketch, &keys[i], 1);
805db354bd2SLeyi Rong 
806db354bd2SLeyi Rong 			if (ret < 0) {
807db354bd2SLeyi Rong 				printf("rte_member_add Failed! Error [%d]\n", ret);
808db354bd2SLeyi Rong 				rte_member_free(setsum_sketch);
809db354bd2SLeyi Rong 
810db354bd2SLeyi Rong 				return -1;
811db354bd2SLeyi Rong 			}
812db354bd2SLeyi Rong 		}
813db354bd2SLeyi Rong 
814db354bd2SLeyi Rong 		for (i = 0; i < SKETCH_TOTAL_KEY; i++) {
815db354bd2SLeyi Rong 			uint32_t tmp_key = i;
816db354bd2SLeyi Rong 
817db354bd2SLeyi Rong 			rte_member_query_count(setsum_sketch, (void *)&tmp_key, &result_count[i]);
818db354bd2SLeyi Rong 			rte_member_lookup(setsum_sketch, (void *)&tmp_key, &heavy_set[i]);
819db354bd2SLeyi Rong 		}
820db354bd2SLeyi Rong 
821db354bd2SLeyi Rong 		print_out_sketch_results(result_count, heavy_set, PRINT_OUT_COUNT, count_byte);
822db354bd2SLeyi Rong 
823db354bd2SLeyi Rong 		hh_cnt = rte_member_report_heavyhitter(setsum_sketch, heavy_hitters, count);
824db354bd2SLeyi Rong 		if (hh_cnt < 0) {
825db354bd2SLeyi Rong 			printf("sketch report heavy hitter error!");
826db354bd2SLeyi Rong 			rte_member_free(setsum_sketch);
827db354bd2SLeyi Rong 
828db354bd2SLeyi Rong 			return -1;
829db354bd2SLeyi Rong 		}
830db354bd2SLeyi Rong 		printf("Report heavy hitters:");
831db354bd2SLeyi Rong 		for (i = 0; i < (unsigned int)hh_cnt; i++) {
832db354bd2SLeyi Rong 			printf("%u: %"PRIu64"\t",
833db354bd2SLeyi Rong 				*((uint32_t *)heavy_hitters[i]), count[i]);
834db354bd2SLeyi Rong 		}
835db354bd2SLeyi Rong 		printf("\n");
836db354bd2SLeyi Rong 
837db354bd2SLeyi Rong 		printf("\nDelete some keys!\n");
838db354bd2SLeyi Rong 		uint32_t tmp_key = 0;
839db354bd2SLeyi Rong 
840db354bd2SLeyi Rong 		rte_member_delete(setsum_sketch, (void *)&tmp_key, 0);
841db354bd2SLeyi Rong 		tmp_key = 1;
842db354bd2SLeyi Rong 		rte_member_delete(setsum_sketch, (void *)&tmp_key, 0);
843db354bd2SLeyi Rong 
844db354bd2SLeyi Rong 		for (i = 0; i < SKETCH_TOTAL_KEY; i++) {
845db354bd2SLeyi Rong 			uint32_t tmp_key = i;
846db354bd2SLeyi Rong 
847db354bd2SLeyi Rong 			rte_member_query_count(setsum_sketch, (void *)&tmp_key, &result_count[i]);
848db354bd2SLeyi Rong 			rte_member_lookup(setsum_sketch, (void *)&tmp_key, &heavy_set[i]);
849db354bd2SLeyi Rong 		}
850db354bd2SLeyi Rong 
851db354bd2SLeyi Rong 		print_out_sketch_results(result_count, heavy_set, PRINT_OUT_COUNT, count_byte);
852db354bd2SLeyi Rong 
853db354bd2SLeyi Rong 		hh_cnt = rte_member_report_heavyhitter(setsum_sketch, heavy_hitters, count);
854db354bd2SLeyi Rong 		if (hh_cnt < 0) {
855db354bd2SLeyi Rong 			printf("sketch report heavy hitter error!");
856db354bd2SLeyi Rong 			rte_member_free(setsum_sketch);
857db354bd2SLeyi Rong 
858db354bd2SLeyi Rong 			return -1;
859db354bd2SLeyi Rong 		}
860db354bd2SLeyi Rong 		printf("Report heavy hitters:");
861db354bd2SLeyi Rong 		for (i = 0; i < (unsigned int)hh_cnt; i++) {
862db354bd2SLeyi Rong 			printf("%u: %"PRIu64"\t",
863db354bd2SLeyi Rong 				*((uint32_t *)heavy_hitters[i]), count[i]);
864db354bd2SLeyi Rong 		}
865db354bd2SLeyi Rong 		printf("\n");
866db354bd2SLeyi Rong 	}
867db354bd2SLeyi Rong 
868db354bd2SLeyi Rong 	rte_member_free(setsum_sketch);
869db354bd2SLeyi Rong 	return 0;
870db354bd2SLeyi Rong }
871db354bd2SLeyi Rong 
872db354bd2SLeyi Rong static int
873db354bd2SLeyi Rong test_member_sketch(void)
874db354bd2SLeyi Rong {
875db354bd2SLeyi Rong 	unsigned int i, j, index;
876db354bd2SLeyi Rong 	uint32_t total_pkt = 0;
877db354bd2SLeyi Rong 	uint32_t *keys;
878db354bd2SLeyi Rong 	int count_byte = 0;
879db354bd2SLeyi Rong 
880db354bd2SLeyi Rong 	for (i = 0; i < SKETCH_TOTAL_KEY; i++)
881fe61babeSLeyi Rong 		total_pkt += ceil((double)SKETCH_LARGEST_KEY_SIZE / (i + 1));
882db354bd2SLeyi Rong 
883db354bd2SLeyi Rong 	printf("\nTotal key count [%u] in Sketch Autotest\n", total_pkt);
884db354bd2SLeyi Rong 
885db354bd2SLeyi Rong 	keys = rte_zmalloc(NULL, sizeof(uint32_t) * total_pkt, 0);
886db354bd2SLeyi Rong 
887db354bd2SLeyi Rong 	if (keys == NULL) {
888db354bd2SLeyi Rong 		printf("RTE_ZMALLOC failed\n");
889db354bd2SLeyi Rong 		return -1;
890db354bd2SLeyi Rong 	}
891db354bd2SLeyi Rong 
892db354bd2SLeyi Rong 	index = 0;
893db354bd2SLeyi Rong 	for (i = 0; i < SKETCH_TOTAL_KEY; i++) {
894fe61babeSLeyi Rong 		for (j = 0; j < ceil((double)SKETCH_LARGEST_KEY_SIZE / (i + 1)); j++)
895db354bd2SLeyi Rong 			keys[index++] = i;
896db354bd2SLeyi Rong 	}
897db354bd2SLeyi Rong 
898db354bd2SLeyi Rong 	/* shuffle the keys */
899db354bd2SLeyi Rong 	for (i = index - 1; i > 0; i--) {
900db354bd2SLeyi Rong 		uint32_t swap_idx = rte_rand() % i;
901db354bd2SLeyi Rong 		uint32_t tmp_key = keys[i];
902db354bd2SLeyi Rong 
903db354bd2SLeyi Rong 		keys[i] = keys[swap_idx];
904db354bd2SLeyi Rong 		keys[swap_idx] = tmp_key;
905db354bd2SLeyi Rong 	}
906db354bd2SLeyi Rong 
907db354bd2SLeyi Rong 	params.key_len = 4;
908db354bd2SLeyi Rong 	params.name = "test_member_sketch";
909db354bd2SLeyi Rong 	params.type = RTE_MEMBER_TYPE_SKETCH;
910db354bd2SLeyi Rong 	params.error_rate = SKETCH_ERROR_RATE;
911db354bd2SLeyi Rong 	params.sample_rate = SKETCH_SAMPLE_RATE;
912db354bd2SLeyi Rong 	params.extra_flag = 0;
913db354bd2SLeyi Rong 	params.top_k = TOP_K;
914db354bd2SLeyi Rong 	params.prim_hash_seed = rte_rdtsc();
915db354bd2SLeyi Rong 	int reset_test = 0;
916db354bd2SLeyi Rong 
917db354bd2SLeyi Rong 	printf("Default sketching params: Error Rate: [%f]\tSample Rate: [%f]\tTopK: [%d]\n",
918db354bd2SLeyi Rong 			SKETCH_ERROR_RATE, SKETCH_SAMPLE_RATE, TOP_K);
919db354bd2SLeyi Rong 
920db354bd2SLeyi Rong 	printf("\n[Sketch with Fixed Sampling Rate Mode]\n");
921db354bd2SLeyi Rong 	if (sketch_test(keys, total_pkt, count_byte, reset_test) < 0) {
922db354bd2SLeyi Rong 		rte_free(keys);
923db354bd2SLeyi Rong 		return -1;
924db354bd2SLeyi Rong 	}
925db354bd2SLeyi Rong 
926db354bd2SLeyi Rong 	params.extra_flag |= RTE_MEMBER_SKETCH_ALWAYS_BOUNDED;
927db354bd2SLeyi Rong 	printf("\n[Sketch with Always Bounded Mode]\n");
928db354bd2SLeyi Rong 	if (sketch_test(keys, total_pkt, count_byte, reset_test) < 0) {
929db354bd2SLeyi Rong 		rte_free(keys);
930db354bd2SLeyi Rong 		return -1;
931db354bd2SLeyi Rong 	}
932db354bd2SLeyi Rong 
933db354bd2SLeyi Rong 	count_byte = 1;
934db354bd2SLeyi Rong 	params.extra_flag |= RTE_MEMBER_SKETCH_COUNT_BYTE;
935db354bd2SLeyi Rong 	printf("\n[Sketch with Packet Size Mode]\n");
936db354bd2SLeyi Rong 	if (sketch_test(keys, total_pkt, count_byte, reset_test) < 0) {
937db354bd2SLeyi Rong 		rte_free(keys);
938db354bd2SLeyi Rong 		return -1;
939db354bd2SLeyi Rong 	}
940db354bd2SLeyi Rong 
941db354bd2SLeyi Rong 	count_byte = 0;
942db354bd2SLeyi Rong 	params.extra_flag = 0;
943db354bd2SLeyi Rong 	reset_test = 1;
944db354bd2SLeyi Rong 	printf("\nreset sketch test\n");
945db354bd2SLeyi Rong 	if (sketch_test(keys, total_pkt, count_byte, reset_test) < 0) {
946db354bd2SLeyi Rong 		rte_free(keys);
947db354bd2SLeyi Rong 		return -1;
948db354bd2SLeyi Rong 	}
949db354bd2SLeyi Rong 
950db354bd2SLeyi Rong 	rte_free(keys);
951db354bd2SLeyi Rong 	return 0;
952db354bd2SLeyi Rong }
953db354bd2SLeyi Rong 
954a9de470cSBruce Richardson static int
955a9de470cSBruce Richardson test_member(void)
956a9de470cSBruce Richardson {
957a9de470cSBruce Richardson 	if (test_member_create_bad_param() < 0)
958a9de470cSBruce Richardson 		return -1;
959a9de470cSBruce Richardson 
960a9de470cSBruce Richardson 	if (test_member_find_existing() < 0)
961a9de470cSBruce Richardson 		return -1;
962a9de470cSBruce Richardson 
963a9de470cSBruce Richardson 	if (test_member_create() < 0) {
964a9de470cSBruce Richardson 		perform_free();
965a9de470cSBruce Richardson 		return -1;
966a9de470cSBruce Richardson 	}
967a9de470cSBruce Richardson 	if (test_member_insert() < 0) {
968a9de470cSBruce Richardson 		perform_free();
969a9de470cSBruce Richardson 		return -1;
970a9de470cSBruce Richardson 	}
971a9de470cSBruce Richardson 	if (test_member_lookup() < 0) {
972a9de470cSBruce Richardson 		perform_free();
973a9de470cSBruce Richardson 		return -1;
974a9de470cSBruce Richardson 	}
975a9de470cSBruce Richardson 	if (test_member_delete() < 0) {
976a9de470cSBruce Richardson 		perform_free();
977a9de470cSBruce Richardson 		return -1;
978a9de470cSBruce Richardson 	}
979a9de470cSBruce Richardson 	if (test_member_multimatch() < 0) {
980a9de470cSBruce Richardson 		perform_free();
981a9de470cSBruce Richardson 		return -1;
982a9de470cSBruce Richardson 	}
983a9de470cSBruce Richardson 	if (test_member_loadfactor() < 0) {
984a9de470cSBruce Richardson 		rte_member_free(setsum_ht);
985a9de470cSBruce Richardson 		rte_member_free(setsum_cache);
986a9de470cSBruce Richardson 		return -1;
987a9de470cSBruce Richardson 	}
988a9de470cSBruce Richardson 
989db354bd2SLeyi Rong 	if (test_member_sketch() < 0) {
990db354bd2SLeyi Rong 		perform_free();
991db354bd2SLeyi Rong 		return -1;
992db354bd2SLeyi Rong 	}
993a9de470cSBruce Richardson 	perform_free();
994a9de470cSBruce Richardson 	return 0;
995a9de470cSBruce Richardson }
996a9de470cSBruce Richardson 
9973c60274cSJie Zhou #endif /* !RTE_EXEC_ENV_WINDOWS */
9983c60274cSJie Zhou 
999e0a8442cSBruce Richardson REGISTER_FAST_TEST(member_autotest, true, true, test_member);
1000