classifier: Add functions and macros for iteration, and use them in ofproto.
[openvswitch] / tests / test-classifier.c
index 1308fa510546967a0563f1a6ec1dcbee5784318d..9af97a4c853b1c929e22b40a23389c24efaf53b3 100644 (file)
@@ -125,19 +125,6 @@ tcls_destroy(struct tcls *tcls)
     }
 }
 
-static int
-tcls_count_exact(const struct tcls *tcls)
-{
-    int n_exact;
-    size_t i;
-
-    n_exact = 0;
-    for (i = 0; i < tcls->n_rules; i++) {
-        n_exact += tcls->rules[i]->cls_rule.wc.wildcards == 0;
-    }
-    return n_exact;
-}
-
 static bool
 tcls_is_empty(const struct tcls *tcls)
 {
@@ -366,7 +353,6 @@ compare_classifiers(struct classifier *cls, struct tcls *tcls)
     unsigned int i;
 
     assert(classifier_count(cls) == tcls->n_rules);
-    assert(classifier_count_exact(cls) == tcls_count_exact(tcls));
     for (i = 0; i < confidence; i++) {
         struct cls_rule *cr0, *cr1;
         struct flow flow;
@@ -407,17 +393,17 @@ compare_classifiers(struct classifier *cls, struct tcls *tcls)
     }
 }
 
-static void
-free_rule(struct cls_rule *cls_rule, void *cls)
-{
-    classifier_remove(cls, cls_rule);
-    free(test_rule_from_cls_rule(cls_rule));
-}
-
 static void
 destroy_classifier(struct classifier *cls)
 {
-    classifier_for_each(cls, free_rule, cls);
+    struct test_rule *rule, *next_rule;
+    struct cls_cursor cursor;
+
+    cls_cursor_init(&cursor, cls, NULL);
+    CLS_CURSOR_FOR_EACH_SAFE (rule, next_rule, cls_rule, &cursor) {
+        classifier_remove(cls, &rule->cls_rule);
+        free(rule);
+    }
     classifier_destroy(cls);
 }
 
@@ -426,17 +412,13 @@ check_tables(const struct classifier *cls,
              int n_tables, int n_rules, int n_dups)
 {
     const struct cls_table *table;
-    const struct test_rule *test_rule;
     struct flow_wildcards exact_wc;
     int found_tables = 0;
     int found_rules = 0;
     int found_dups = 0;
-    int n_exact1 = 0;
-    int n_exact2 = 0;
 
     flow_wildcards_init_exact(&exact_wc);
     HMAP_FOR_EACH (table, hmap_node, &cls->tables) {
-        bool is_exact = flow_wildcards_equal(&table->wc, &exact_wc);
         const struct cls_rule *head;
 
         assert(!hmap_is_empty(&table->rules));
@@ -447,31 +429,20 @@ check_tables(const struct classifier *cls,
             const struct cls_rule *rule;
 
             found_rules++;
-            if (is_exact) {
-                n_exact1++;
-            }
             LIST_FOR_EACH (rule, list, &head->list) {
                 assert(rule->priority < prev_priority);
                 prev_priority = rule->priority;
                 found_rules++;
                 found_dups++;
-                if (is_exact) {
-                    n_exact1++;
-                }
                 assert(classifier_find_rule_exactly(cls, rule) == rule);
             }
         }
     }
 
-    CLASSIFIER_FOR_EACH_EXACT_RULE (test_rule, cls_rule, cls) {
-        n_exact2++;
-    }
-
     assert(found_tables == hmap_count(&cls->tables));
     assert(n_tables == -1 || n_tables == hmap_count(&cls->tables));
     assert(n_rules == -1 || found_rules == n_rules);
     assert(n_dups == -1 || found_dups == n_dups);
-    assert(n_exact1 == n_exact2);
 }
 
 static struct test_rule *
@@ -873,13 +844,22 @@ test_many_rules_in_n_tables(int n_tables)
         }
 
         while (!classifier_is_empty(&cls)) {
-            struct test_rule *rule = xmemdup(tcls.rules[rand() % tcls.n_rules],
-                                             sizeof(struct test_rule));
-            classifier_for_each_match(&cls, &rule->cls_rule, free_rule, &cls);
-            tcls_delete_matches(&tcls, &rule->cls_rule);
+            struct test_rule *rule, *next_rule;
+            struct test_rule *target;
+            struct cls_cursor cursor;
+
+            target = xmemdup(tcls.rules[rand() % tcls.n_rules],
+                             sizeof(struct test_rule));
+
+            cls_cursor_init(&cursor, &cls, &target->cls_rule);
+            CLS_CURSOR_FOR_EACH_SAFE (rule, next_rule, cls_rule, &cursor) {
+                classifier_remove(&cls, &rule->cls_rule);
+                free(rule);
+            }
+            tcls_delete_matches(&tcls, &target->cls_rule);
             compare_classifiers(&cls, &tcls);
             check_tables(&cls, -1, -1, -1);
-            free(rule);
+            free(target);
         }
 
         destroy_classifier(&cls);