+ elements[i].value = i;
+ cmap_insert(&cmap, &elements[i].node, hash_int(i, 0));
+ }
+ printf("cmap insert: %5d ms\n", elapsed(&start));
+
+ /* Iteration. */
+ xgettimeofday(&start);
+ CMAP_FOR_EACH (e, node, &cmap) {
+ ignore(e);
+ }
+ printf("cmap iterate: %5d ms\n", elapsed(&start));
+
+ /* Search and mutation. */
+ xgettimeofday(&start);
+ aux.cmap = &cmap;
+ ovs_mutex_init(&aux.mutex);
+ threads = xmalloc(n_threads * sizeof *threads);
+ for (i = 0; i < n_threads; i++) {
+ threads[i] = ovs_thread_create("search", search_cmap, &aux);
+ }
+ for (i = 0; i < n_threads; i++) {
+ xpthread_join(threads[i], NULL);
+ }
+ free(threads);
+ printf("cmap search: %5d ms\n", elapsed(&start));
+
+ /* Destruction. */
+ xgettimeofday(&start);
+ CMAP_FOR_EACH (e, node, &cmap) {
+ cmap_remove(&cmap, &e->node, hash_int(e->value, 0));
+ }
+ cmap_destroy(&cmap);
+ printf("cmap destroy: %5d ms\n", elapsed(&start));
+
+ free(elements);
+}
+
+static size_t
+find_batch(const struct cmap *cmap, const int value)
+{
+ size_t i, ret;
+ const size_t end = MIN(n_batch, n_elems - value);
+ unsigned long map = ~0;
+ uint32_t hashes[N_BATCH_MAX];
+ const struct cmap_node *nodes[N_BATCH_MAX];
+
+ if (mutation_frac) {
+ for (i = 0; i < end; i++) {
+ if (random_uint32() < mutation_frac) {
+ break;
+ }
+ hashes[i] = hash_int(value + i, 0);
+ }
+ } else {
+ for (i = 0; i < end; i++) {
+ hashes[i] = hash_int(value + i, 0);
+ }
+ }
+
+ ret = i;
+
+ map >>= BITMAP_ULONG_BITS - i; /* Clear excess bits. */
+ map = cmap_find_batch(cmap, map, hashes, nodes);
+
+ ULLONG_FOR_EACH_1(i, map) {