add max_nr_buckets argument
[urcu.git] / tests / test_urcu_hash.c
index dbacf73a5615c9912a89a9e71a3697ae6da92aa8..043a33a9353105eac57e2363693bdfb41c49f12c 100644 (file)
@@ -41,6 +41,8 @@
 #define DEFAULT_MIN_ALLOC_SIZE 1
 #define DEFAULT_RAND_POOL      1000000
 
+#define TEST_HASH_SEED 0x42UL
+
 /* Make this big enough to include the POWER5+ L3 cacheline size of 256B */
 #define CACHE_LINE_SIZE 4096
 
@@ -107,6 +109,10 @@ struct test_data {
 
 struct lfht_test_node {
        struct cds_lfht_node node;
+       void *key;
+       unsigned int key_len;
+       /* cache-cold for iteration */
+       struct rcu_head head;
 };
 
 static inline struct lfht_test_node *
@@ -119,7 +125,9 @@ static inline
 void lfht_test_node_init(struct lfht_test_node *node, void *key,
                        size_t key_len)
 {
-       cds_lfht_node_init(&node->node, key, key_len);
+       cds_lfht_node_init(&node->node);
+       node->key = key;
+       node->key_len = key_len;
 }
 
 static inline struct lfht_test_node *
@@ -376,7 +384,7 @@ void hashword2(
 
 #if (CAA_BITS_PER_LONG == 32)
 static
-unsigned long test_hash(void *_key, size_t length, unsigned long seed)
+unsigned long test_hash(const void *_key, size_t length, unsigned long seed)
 {
        unsigned int key = (unsigned int) _key;
 
@@ -385,7 +393,7 @@ unsigned long test_hash(void *_key, size_t length, unsigned long seed)
 }
 #else
 static
-unsigned long test_hash(void *_key, size_t length, unsigned long seed)
+unsigned long test_hash(const void *_key, size_t length, unsigned long seed)
 {
        union {
                uint64_t v64;
@@ -405,8 +413,8 @@ unsigned long test_hash(void *_key, size_t length, unsigned long seed)
 #endif
 
 static
-unsigned long test_compare(void *key1, size_t key1_len,
-                           void *key2, size_t key2_len)
+unsigned long test_compare(const void *key1, size_t key1_len,
+                           const void *key2, size_t key2_len)
 {
        if (caa_unlikely(key1_len != key2_len))
                return -1;
@@ -417,6 +425,25 @@ unsigned long test_compare(void *key1, size_t key1_len,
                return 1;
 }
 
+static
+int test_match(struct cds_lfht_node *node, const void *key)
+{
+       struct lfht_test_node *test_node = to_test_node(node);
+
+       return !test_compare(test_node->key, test_node->key_len,
+                       key, sizeof(unsigned long));
+}
+
+static
+void cds_lfht_test_lookup(struct cds_lfht *ht, void *key, size_t key_len,
+               struct cds_lfht_iter *iter)
+{
+       assert(key_len == sizeof(unsigned long));
+
+       cds_lfht_lookup(ht, test_hash(key, key_len, TEST_HASH_SEED),
+                       test_match, key, iter);
+}
+
 void *thr_count(void *arg)
 {
        printf_verbose("thread_begin %s, thread id : %lx, tid %lu\n",
@@ -477,7 +504,7 @@ void *thr_reader(void *_count)
 
        for (;;) {
                rcu_read_lock();
-               cds_lfht_lookup(test_ht,
+               cds_lfht_test_lookup(test_ht,
                        (void *)(((unsigned long) rand_r(&rand_lookup) % lookup_pool_size) + lookup_pool_offset),
                        sizeof(void *), &iter);
                node = cds_lfht_iter_get_test_node(&iter);
@@ -516,7 +543,7 @@ static
 void free_node_cb(struct rcu_head *head)
 {
        struct lfht_test_node *node =
-               caa_container_of(head, struct lfht_test_node, node.head);
+               caa_container_of(head, struct lfht_test_node, head);
        free(node);
 }
 
@@ -549,12 +576,18 @@ void *thr_writer(void *_count)
                                sizeof(void *));
                        rcu_read_lock();
                        if (add_unique) {
-                               ret_node = cds_lfht_add_unique(test_ht, &node->node);
+                               ret_node = cds_lfht_add_unique(test_ht,
+                                       test_hash(node->key, node->key_len, TEST_HASH_SEED),
+                                       test_match, node->key, &node->node);
                        } else {
                                if (add_replace)
-                                       ret_node = cds_lfht_add_replace(test_ht, &node->node);
+                                       ret_node = cds_lfht_add_replace(test_ht,
+                                                       test_hash(node->key, node->key_len, TEST_HASH_SEED),
+                                                       test_match, node->key, &node->node);
                                else
-                                       cds_lfht_add(test_ht, &node->node);
+                                       cds_lfht_add(test_ht,
+                                               test_hash(node->key, node->key_len, TEST_HASH_SEED),
+                                               &node->node);
                        }
                        rcu_read_unlock();
                        if (add_unique && ret_node != &node->node) {
@@ -562,7 +595,7 @@ void *thr_writer(void *_count)
                                nr_addexist++;
                        } else {
                                if (add_replace && ret_node) {
-                                       call_rcu(&to_test_node(ret_node)->node.head,
+                                       call_rcu(&to_test_node(ret_node)->head,
                                                        free_node_cb);
                                        nr_addexist++;
                                } else {
@@ -572,14 +605,14 @@ void *thr_writer(void *_count)
                } else {
                        /* May delete */
                        rcu_read_lock();
-                       cds_lfht_lookup(test_ht,
+                       cds_lfht_test_lookup(test_ht,
                                (void *)(((unsigned long) rand_r(&rand_lookup) % write_pool_size) + write_pool_offset),
                                sizeof(void *), &iter);
                        ret = cds_lfht_del(test_ht, &iter);
                        rcu_read_unlock();
                        if (ret == 0) {
                                node = cds_lfht_iter_get_test_node(&iter);
-                               call_rcu(&node->node.head, free_node_cb);
+                               call_rcu(&node->head, free_node_cb);
                                nr_del++;
                        } else
                                nr_delnoent++;
@@ -640,12 +673,18 @@ static int populate_hash(void)
                        sizeof(void *));
                rcu_read_lock();
                if (add_unique) {
-                       ret_node = cds_lfht_add_unique(test_ht, &node->node);
+                       ret_node = cds_lfht_add_unique(test_ht,
+                               test_hash(node->key, node->key_len, TEST_HASH_SEED),
+                               test_match, node->key, &node->node);
                } else {
                        if (add_replace)
-                               ret_node = cds_lfht_add_replace(test_ht, &node->node);
+                               ret_node = cds_lfht_add_replace(test_ht,
+                                               test_hash(node->key, node->key_len, TEST_HASH_SEED),
+                                               test_match, node->key, &node->node);
                        else
-                               cds_lfht_add(test_ht, &node->node);
+                               cds_lfht_add(test_ht,
+                                       test_hash(node->key, node->key_len, TEST_HASH_SEED),
+                                       &node->node);
                }
                rcu_read_unlock();
                if (add_unique && ret_node != &node->node) {
@@ -653,7 +692,7 @@ static int populate_hash(void)
                        nr_addexist++;
                } else {
                        if (add_replace && ret_node) {
-                               call_rcu(&to_test_node(ret_node)->node.head, free_node_cb);
+                               call_rcu(&to_test_node(ret_node)->head, free_node_cb);
                                nr_addexist++;
                        } else {
                                nr_add++;
@@ -671,14 +710,12 @@ void test_delete_all_nodes(struct cds_lfht *ht)
        struct lfht_test_node *node;
        unsigned long count = 0;
 
-       cds_lfht_first(ht, &iter);
-       while ((node = cds_lfht_iter_get_test_node(&iter)) != NULL) {
+       cds_lfht_for_each_entry(ht, &iter, node, node) {
                int ret;
 
                ret = cds_lfht_del(test_ht, &iter);
                assert(!ret);
-               call_rcu(&node->node.head, free_node_cb);
-               cds_lfht_next(ht, &iter);
+               call_rcu(&node->head, free_node_cb);
                count++;
        }
        printf("deleted %lu nodes.\n", count);
@@ -859,7 +896,7 @@ int main(int argc, char **argv)
                return -1;
        }
 
-       if (min_hash_alloc_size && min_hash_alloc_size * (min_hash_alloc_size - 1)) {
+       if (min_hash_alloc_size && min_hash_alloc_size & (min_hash_alloc_size - 1)) {
                printf("Error: Min hash alloc size %lu is not a power of 2.\n",
                        min_hash_alloc_size);
                return -1;
@@ -930,8 +967,7 @@ int main(int argc, char **argv)
         * thread from the point of view of resize.
         */
        rcu_register_thread();
-       test_ht = cds_lfht_new(test_hash, test_compare, 0x42UL,
-                       init_hash_size, min_hash_alloc_size,
+       test_ht = cds_lfht_new(init_hash_size, min_hash_alloc_size, (1UL << 18),
                        (opt_auto_resize ? CDS_LFHT_AUTO_RESIZE : 0) |
                        CDS_LFHT_ACCOUNTING, NULL);
        ret = populate_hash();
This page took 0.031183 seconds and 4 git commands to generate.