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(¶ms); 271a9de470cSBruce Richardson 272a9de470cSBruce Richardson params.name = "test_member_cache"; 273a9de470cSBruce Richardson params.is_cache = 1; 274a9de470cSBruce Richardson setsum_cache = rte_member_create(¶ms); 275a9de470cSBruce Richardson 276a9de470cSBruce Richardson params.name = "test_member_vbf"; 277a9de470cSBruce Richardson params.type = RTE_MEMBER_TYPE_VBF; 278a9de470cSBruce Richardson setsum_vbf = rte_member_create(¶ms); 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(¶ms); 634a9de470cSBruce Richardson 635a9de470cSBruce Richardson params.name = "test_member_cache"; 636a9de470cSBruce Richardson params.is_cache = 1; 637a9de470cSBruce Richardson setsum_cache = rte_member_create(¶ms); 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(¶ms); 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