rculfhash: remove unneeded clear_flag()
[urcu.git] / rculfhash.c
index 5220cd5fd804321cf2b9b725c87b9e54d58296f2..c1ff314bc0d5cc748e1329d8508f72641ae804ad 100644 (file)
@@ -779,9 +779,9 @@ int _cds_lfht_replace(struct cds_lfht *ht, unsigned long size,
                         */
                        return -ENOENT;
                }
-               assert(!is_bucket(old_next));
-               assert(new_node != clear_flag(old_next));
-               new_node->next = clear_flag(old_next);
+               assert(old_next == clear_flag(old_next));
+               assert(new_node != old_next);
+               new_node->next = old_next;
                /*
                 * Here is the whole trick for lock-free replace: we add
                 * the replacement node _after_ the node we want to
@@ -929,8 +929,7 @@ end:
 
 static
 int _cds_lfht_del(struct cds_lfht *ht, unsigned long size,
-               struct cds_lfht_node *node,
-               int bucket_removal)
+               struct cds_lfht_node *node)
 {
        struct cds_lfht_node *bucket, *next;
 
@@ -951,10 +950,7 @@ int _cds_lfht_del(struct cds_lfht *ht, unsigned long size,
        next = rcu_dereference(node->next);
        if (caa_unlikely(is_removed(next)))
                return -ENOENT;
-       if (bucket_removal)
-               assert(is_bucket(next));
-       else
-               assert(!is_bucket(next));
+       assert(!is_bucket(next));
        /*
         * We set the REMOVED_FLAG unconditionally. Note that there may
         * be more than one concurrent thread setting this flag.
@@ -1521,25 +1517,36 @@ struct cds_lfht_node *cds_lfht_add_replace(struct cds_lfht *ht,
        }
 }
 
-int cds_lfht_replace(struct cds_lfht *ht, struct cds_lfht_iter *old_iter,
+int cds_lfht_replace(struct cds_lfht *ht,
+               struct cds_lfht_iter *old_iter,
+               unsigned long hash,
+               cds_lfht_match_fct match,
+               const void *key,
                struct cds_lfht_node *new_node)
 {
        unsigned long size;
 
+       new_node->reverse_hash = bit_reverse_ulong((unsigned long) hash);
+       if (!old_iter->node)
+               return -ENOENT;
+       if (caa_unlikely(old_iter->node->reverse_hash != new_node->reverse_hash))
+               return -EINVAL;
+       if (caa_unlikely(!match(old_iter->node, key)))
+               return -EINVAL;
        size = rcu_dereference(ht->size);
        return _cds_lfht_replace(ht, size, old_iter->node, old_iter->next,
                        new_node);
 }
 
-int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_iter *iter)
+int cds_lfht_del(struct cds_lfht *ht, struct cds_lfht_node *node)
 {
        unsigned long size, hash;
        int ret;
 
        size = rcu_dereference(ht->size);
-       ret = _cds_lfht_del(ht, size, iter->node, 0);
+       ret = _cds_lfht_del(ht, size, node);
        if (!ret) {
-               hash = bit_reverse_ulong(iter->node->reverse_hash);
+               hash = bit_reverse_ulong(node->reverse_hash);
                ht_count_del(ht, size, hash);
        }
        return ret;
@@ -1604,11 +1611,10 @@ int cds_lfht_destroy(struct cds_lfht *ht, pthread_attr_t **attr)
 void cds_lfht_count_nodes(struct cds_lfht *ht,
                long *approx_before,
                unsigned long *count,
-               unsigned long *removed,
                long *approx_after)
 {
        struct cds_lfht_node *node, *next;
-       unsigned long nr_bucket = 0;
+       unsigned long nr_bucket = 0, nr_removed = 0;
 
        *approx_before = 0;
        if (ht->split_count) {
@@ -1621,7 +1627,6 @@ void cds_lfht_count_nodes(struct cds_lfht *ht,
        }
 
        *count = 0;
-       *removed = 0;
 
        /* Count non-bucket nodes in the table */
        node = bucket_at(ht, 0);
@@ -1629,7 +1634,7 @@ void cds_lfht_count_nodes(struct cds_lfht *ht,
                next = rcu_dereference(node->next);
                if (is_removed(next)) {
                        if (!is_bucket(next))
-                               (*removed)++;
+                               (nr_removed)++;
                        else
                                (nr_bucket)++;
                } else if (!is_bucket(next))
@@ -1638,6 +1643,7 @@ void cds_lfht_count_nodes(struct cds_lfht *ht,
                        (nr_bucket)++;
                node = clear_flag(next);
        } while (!is_end(node));
+       dbg_printf("number of logically removed nodes: %lu\n", nr_removed);
        dbg_printf("number of bucket nodes: %lu\n", nr_bucket);
        *approx_after = 0;
        if (ht->split_count) {
This page took 0.024013 seconds and 4 git commands to generate.