classifier: Optimize iteration with a catch-all target rule.
authorBen Pfaff <blp@nicira.com>
Fri, 20 Jul 2012 21:46:15 +0000 (14:46 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 4 Sep 2012 19:24:27 +0000 (12:24 -0700)
When cls_cursor_init() is given a NULL target, it can skip an expensive
step comparing the rule against the target for every table and every rule
in the classifier.  collect_rule_loose() and other callers could take
advantage of this optimization, except that they actually pass in a rule
that matches everything instead of a NULL rule (e.g. for "ovs-ofctl
dump-flows <bridge>" without specifying a matching rule).

This optimizes that case.

Signed-off-by: Ben Pfaff <blp@nicira.com>
lib/classifier.c
lib/classifier.h

index f6f7a64..81b05fd 100644 (file)
@@ -111,6 +111,13 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
 {
     match_format(&rule->match, s, rule->priority);
 }
+
+/* Returns true if 'rule' matches every packet, false otherwise. */
+bool
+cls_rule_is_catchall(const struct cls_rule *rule)
+{
+    return flow_wildcards_is_catchall(&rule->match.wc);
+}
 \f
 /* Initializes 'cls' as a classifier that initially contains no classification
  * rules. */
@@ -399,7 +406,7 @@ cls_cursor_init(struct cls_cursor *cursor, const struct classifier *cls,
                 const struct cls_rule *target)
 {
     cursor->cls = cls;
-    cursor->target = target;
+    cursor->target = target && !cls_rule_is_catchall(target) ? target : NULL;
 }
 
 /* Returns the first matching cls_rule in 'cursor''s iteration, or a null
index 341c344..ebb1bba 100644 (file)
@@ -78,6 +78,8 @@ uint32_t cls_rule_hash(const struct cls_rule *, uint32_t basis);
 
 void cls_rule_format(const struct cls_rule *, struct ds *);
 
+bool cls_rule_is_catchall(const struct cls_rule *);
+
 bool cls_rule_is_loose_match(const struct cls_rule *rule,
                              const struct match *criteria);