1 /*
2  * Copyright (c) 2022 Meta
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/logging/log.h>
9 #include <zephyr/sys/hash_map.h>
10 #include <zephyr/random/random.h>
11 
12 LOG_MODULE_REGISTER(hashmap_sample);
13 
14 SYS_HASHMAP_DEFINE_STATIC(map);
15 
16 struct _stats {
17 	uint64_t n_insert;
18 	uint64_t n_remove;
19 	uint64_t n_replace;
20 	uint64_t n_error;
21 	uint64_t n_miss;
22 	size_t max_size;
23 };
24 
25 static void print_stats(const struct _stats *stats);
26 
main(void)27 int main(void)
28 {
29 	size_t i;
30 	int ires;
31 	bool bres;
32 	struct _stats stats = {0};
33 
34 	printk("CONFIG_TEST_LIB_HASH_MAP_MAX_ENTRIES: %u\n", CONFIG_TEST_LIB_HASH_MAP_MAX_ENTRIES);
35 
36 	do {
37 		for (i = 0; i < CONFIG_TEST_LIB_HASH_MAP_MAX_ENTRIES; ++i) {
38 
39 			ires = sys_hashmap_insert(&map, i, i, NULL);
40 			if (ires < 0) {
41 				break;
42 			}
43 
44 			__ASSERT(ires == 1, "Expected to insert %zu", i);
45 			++stats.n_insert;
46 			++stats.max_size;
47 
48 			LOG_DBG("Inserted %zu", i);
49 
50 			if (k_uptime_seconds() > CONFIG_TEST_LIB_HASH_MAP_DURATION_S) {
51 				goto out;
52 			}
53 		}
54 
55 		for (i = 0; i < stats.max_size; ++i) {
56 
57 			ires = sys_hashmap_insert(&map, i, stats.max_size - i, NULL);
58 			__ASSERT(ires == 0, "Failed to replace %zu", i);
59 			++stats.n_replace;
60 
61 			LOG_DBG("Replaced %zu", i);
62 
63 			if (k_uptime_seconds() > CONFIG_TEST_LIB_HASH_MAP_DURATION_S) {
64 				goto out;
65 			}
66 		}
67 
68 		for (i = stats.max_size; i > 0; --i) {
69 			bres = sys_hashmap_remove(&map, i - 1, NULL);
70 			__ASSERT(bres, "Failed to remove %zu", i - 1);
71 			++stats.n_remove;
72 
73 			LOG_DBG("Removed %zu", i - 1);
74 
75 			if (k_uptime_seconds() > CONFIG_TEST_LIB_HASH_MAP_DURATION_S) {
76 				goto out;
77 			}
78 		}
79 	/* These architectures / boards seem to have trouble with basic timekeeping atm */
80 	} while (!IS_ENABLED(CONFIG_ARCH_POSIX) && !IS_ENABLED(CONFIG_BOARD_QEMU_NIOS2));
81 
82 out:
83 
84 	print_stats(&stats);
85 
86 	sys_hashmap_clear(&map, NULL, NULL);
87 
88 	LOG_INF("success");
89 
90 	return 0;
91 }
92 
print_stats(const struct _stats * stats)93 static void print_stats(const struct _stats *stats)
94 {
95 	LOG_INF("n_insert: %" PRIu64 " n_remove: %" PRIu64 " n_replace: %" PRIu64
96 		" n_miss: %" PRIu64 " n_error: %" PRIu64 " max_size: %zu",
97 		stats->n_insert, stats->n_remove, stats->n_replace, stats->n_miss, stats->n_error,
98 		stats->max_size);
99 }
100