The conditional replication code had hardly any comments.  This adds some.

This commit also fixes a number of style problems, factors out some code
into a helper function, and moves some struct declarations from a public
header, that were not used by client code, into more private locations.

Signed-off-by: Ben Pfaff <b...@ovn.org>
---
 lib/ovsdb-idl-provider.h |   7 ++-
 lib/ovsdb-idl.c          | 112 ++++++++++++++++++++++++++++++++---------------
 lib/ovsdb-idl.h          |  26 +++++------
 3 files changed, 94 insertions(+), 51 deletions(-)

diff --git a/lib/ovsdb-idl-provider.h b/lib/ovsdb-idl-provider.h
index 55ed793..e0221d0 100644
--- a/lib/ovsdb-idl-provider.h
+++ b/lib/ovsdb-idl-provider.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
+/* Copyright (c) 2009, 2010, 2011, 2012, 2016 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -63,6 +63,11 @@ struct ovsdb_idl_table_class {
     void (*row_init)(struct ovsdb_idl_row *);
 };
 
+struct ovsdb_idl_condition {
+    const struct ovsdb_idl_table_class *tc;
+    struct ovs_list clauses;
+};
+
 struct ovsdb_idl_table {
     const struct ovsdb_idl_table_class *class;
     unsigned char *modes;    /* OVSDB_IDL_* bitmasks, indexed by column. */
diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c
index 7da25a5..df4193b 100644
--- a/lib/ovsdb-idl.c
+++ b/lib/ovsdb-idl.c
@@ -710,6 +710,13 @@ ovsdb_idl_add_table(struct ovsdb_idl *idl,
 
     OVS_NOT_REACHED();
 }
+
+struct ovsdb_idl_clause {
+    struct ovs_list node;
+    enum ovsdb_function function;
+    const struct ovsdb_idl_column *column;
+    struct ovsdb_datum arg;
+};
 
 static struct json *
 ovsdb_idl_clause_to_json(const struct ovsdb_idl_clause *clause)
@@ -740,6 +747,10 @@ ovsdb_idl_clause_free(struct ovsdb_idl_clause *clause)
     free(clause);
 }
 
+/* Clears all of the conditional clauses from table 'tc', so that all of the
+ * rows in the table will be replicated.  (This is the default, so this
+ * function has an effect only if some clauses were added to 'tc' using
+ * ovsdb_idl_condition_add_clause().) */
 void
 ovsdb_idl_condition_reset(struct ovsdb_idl *idl,
                           const struct ovsdb_idl_table_class *tc)
@@ -761,59 +772,90 @@ ovsdb_idl_condition_init(struct ovsdb_idl_condition *cnd,
     ovs_list_init(&cnd->clauses);
 }
 
-void ovsdb_idl_condition_add_clause(struct ovsdb_idl *idl,
-                                    const struct ovsdb_idl_table_class *tc,
-                                    enum ovsdb_function function,
-                                    const struct ovsdb_idl_column *column,
-                                    struct ovsdb_datum *arg)
+static struct ovsdb_idl_clause *
+ovsdb_idl_condition_find_clause(struct ovsdb_idl_table *table,
+                                enum ovsdb_function function,
+                                const struct ovsdb_idl_column *column,
+                                const struct ovsdb_datum *arg)
 {
-    struct ovsdb_idl_table *table = ovsdb_idl_table_from_class(idl, tc);
-    const struct ovsdb_type *type = NULL;
     struct ovsdb_idl_clause *c;
-
-    LIST_FOR_EACH(c, node, &table->condition.clauses) {
+    LIST_FOR_EACH (c, node, &table->condition.clauses) {
         if (c->function == function &&
             (!column || (c->column == column &&
                          ovsdb_datum_equals(&c->arg,
                                              arg, &column->type)))) {
-            return;
+            return c;
         }
     }
+    return NULL;
+}
+
+/* Adds a clause to the condition for replicating the table with class 'tc' in
+ * 'idl'.
+ *
+ * By default, a table has no clauses, and in that case the IDL replicates all
+ * its rows.  When a table has one or more clauses, the IDL replicates only
+ * rows that satisfy at least one clause.
+ *
+ * Two distinct of clauses can be added:
+ *
+ *    - A 'function' of OVSDB_F_FALSE or OVSDB_F_TRUE adds a Boolean clause.  A
+ *      "false" clause by itself prevents any rows from being replicated; in
+ *      combination with other clauses it has no effect.  A "true" clause
+ *      causes every row to be replicated, regardless of whether other clauses
+ *      exist (thus, a condition that includes "true" is like a condition
+ *      without any clauses at all).
+ *
+ *      'column' should be NULL and 'arg' should be an empty datum (initialized
+ *      with ovsdb_datum_init_empty()).
+ *
+ *    - Other 'functions' add a clause of the form "<column> <function> <arg>",
+ *      e.g. "column == 5" or "column <= 10".  In this case, 'arg' must have a
+ *      type that is compatible with 'column'.
+ */
+void
+ovsdb_idl_condition_add_clause(struct ovsdb_idl *idl,
+                               const struct ovsdb_idl_table_class *tc,
+                               enum ovsdb_function function,
+                               const struct ovsdb_idl_column *column,
+                               const struct ovsdb_datum *arg)
+{
+    struct ovsdb_idl_table *table = ovsdb_idl_table_from_class(idl, tc);
+
+    /* Return without doing anything, if this would be a duplicate clause. */
+    if (ovsdb_idl_condition_find_clause(table, function, column, arg)) {
+        return;
+    }
 
     struct ovsdb_idl_clause *clause = xzalloc(sizeof *clause);
     ovs_list_init(&clause->node);
     clause->function = function;
     clause->column = column;
-    if (column) {
-        type = &column->type;
-    } else {
-        type = &ovsdb_type_boolean;
-    }
-    ovsdb_datum_clone(&clause->arg, arg, type);
+    ovsdb_datum_clone(&clause->arg, arg,
+                      column ? &column->type : &ovsdb_type_boolean);
     ovs_list_push_back(&table->condition.clauses, &clause->node);
     idl->cond_changed = table->cond_changed = true;
     poll_immediate_wake();
 }
 
-void ovsdb_idl_condition_remove_clause(struct ovsdb_idl *idl,
-                                       const struct ovsdb_idl_table_class *tc,
-                                       enum ovsdb_function function,
-                                       const struct ovsdb_idl_column *column,
-                                       struct ovsdb_datum *arg)
+/* If a clause matching (function, column, arg) is included in the condition
+ * for 'tc' within 'idl', removes it.  (If this was the last clause included in
+ * the table's condition, then this means that the IDL will begin replicating
+ * every row in the table.) */
+void
+ovsdb_idl_condition_remove_clause(struct ovsdb_idl *idl,
+                                  const struct ovsdb_idl_table_class *tc,
+                                  enum ovsdb_function function,
+                                  const struct ovsdb_idl_column *column,
+                                  const struct ovsdb_datum *arg)
 {
-    struct ovsdb_idl_clause *c, *next;
     struct ovsdb_idl_table *table = ovsdb_idl_table_from_class(idl, tc);
-
-    LIST_FOR_EACH_SAFE(c, next, node, &table->condition.clauses) {
-        if (c->function == function &&
-            (!column || (c->column == column &&
-                         ovsdb_datum_equals(&c->arg,
-                                             arg, &column->type)))) {
-            ovsdb_idl_clause_free(c);
-            idl->cond_changed = table->cond_changed = true;
-            poll_immediate_wake();
-            return;
-        }
+    struct ovsdb_idl_clause *c
+        = ovsdb_idl_condition_find_clause(table, function, column, arg);
+    if (c) {
+        ovsdb_idl_clause_free(c);
+        idl->cond_changed = table->cond_changed = true;
+        poll_immediate_wake();
     }
 }
 
@@ -826,13 +868,13 @@ ovsdb_idl_condition_to_json(const struct 
ovsdb_idl_condition *cnd)
 
     clauses = xmalloc(n_clauses * sizeof *clauses);
     LIST_FOR_EACH (c, node, &cnd->clauses) {
-           clauses[i++] = ovsdb_idl_clause_to_json(c);
+        clauses[i++] = ovsdb_idl_clause_to_json(c);
     }
 
     return json_array_create(clauses, n_clauses);
 }
 
-static struct json*
+static struct json *
 ovsdb_idl_create_cond_change_req(struct ovsdb_idl_table *table)
 {
     const struct ovsdb_idl_condition *cond = &table->condition;
diff --git a/lib/ovsdb-idl.h b/lib/ovsdb-idl.h
index 45befb0..a0b60e2 100644
--- a/lib/ovsdb-idl.h
+++ b/lib/ovsdb-idl.h
@@ -48,7 +48,6 @@ struct ovsdb_idl_class;
 struct ovsdb_idl_row;
 struct ovsdb_idl_column;
 struct ovsdb_idl_table_class;
-struct ovsdb_idl_condition;
 struct uuid;
 
 struct ovsdb_idl *ovsdb_idl_create(const char *remote,
@@ -311,18 +310,15 @@ struct ovsdb_idl_loop {
 void ovsdb_idl_loop_destroy(struct ovsdb_idl_loop *);
 struct ovsdb_idl_txn *ovsdb_idl_loop_run(struct ovsdb_idl_loop *);
 void ovsdb_idl_loop_commit_and_wait(struct ovsdb_idl_loop *);
-
-struct ovsdb_idl_condition {
-    const struct ovsdb_idl_table_class *tc;
-    struct ovs_list clauses;
-};
-
-struct ovsdb_idl_clause {
-    struct ovs_list node;
-    enum ovsdb_function function;
-    const struct ovsdb_idl_column *column;
-    struct ovsdb_datum arg;
-};
+
+/* Conditional Replication
+ * =======================
+ *
+ * By default, when the IDL replicates a particular table in the database, it
+ * replicates every row in the table.  These functions allow the client to
+ * specify that only selected rows should be replicated, by constructing a
+ * per-table condition that specifies the rows to replicate.
+ */
 
 void ovsdb_idl_condition_reset(struct ovsdb_idl *idl,
                                const struct ovsdb_idl_table_class *tc);
@@ -330,11 +326,11 @@ void ovsdb_idl_condition_add_clause(struct ovsdb_idl *idl,
                                     const struct ovsdb_idl_table_class *tc,
                                     enum ovsdb_function function,
                                     const struct ovsdb_idl_column *column,
-                                    struct ovsdb_datum *arg);
+                                    const struct ovsdb_datum *arg);
 void ovsdb_idl_condition_remove_clause(struct ovsdb_idl *idl,
                                        const struct ovsdb_idl_table_class *tc,
                                        enum ovsdb_function function,
                                        const struct ovsdb_idl_column *column,
-                                       struct ovsdb_datum *arg);
+                                       const struct ovsdb_datum *arg);
 
 #endif /* ovsdb-idl.h */
-- 
2.1.3

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to