[ovs-dev] [Simple DB Stats 10/11] ovsdb-idl: Make it possible to avoid replicating selected columns.

Ben Pfaff blp at nicira.com
Fri Jun 11 00:14:40 UTC 2010


ovs-vswitchd has no need to replicate some parts of the database.  In
particular, it doesn't need to replicate the bits that it only writes and
never reads, such as the ofport column in the Interface table.  In upcoming
commits it will start writing additional columns that also do not need to
be replicated.  This saves some memory, CPU time, and bandwidth to the
database.
---
 lib/ovsdb-idl-provider.h |    1 +
 lib/ovsdb-idl.c          |   37 ++++++++++++++++++++++++++++++++++++-
 lib/ovsdb-idl.h          |    2 ++
 3 files changed, 39 insertions(+), 1 deletions(-)

diff --git a/lib/ovsdb-idl-provider.h b/lib/ovsdb-idl-provider.h
index c86396c..cd956c0 100644
--- a/lib/ovsdb-idl-provider.h
+++ b/lib/ovsdb-idl-provider.h
@@ -54,6 +54,7 @@ struct ovsdb_idl_table_class {
 
 struct ovsdb_idl_table {
     const struct ovsdb_idl_table_class *class;
+    unsigned long *monitor_columns; /* Indexes of columns to monitor. */
     struct shash columns;    /* Contains "const struct ovsdb_idl_column *"s. */
     struct hmap rows;        /* Contains "struct ovsdb_idl_row"s. */
     struct ovsdb_idl *idl;   /* Containing idl. */
diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c
index 1bd953c..14652ae 100644
--- a/lib/ovsdb-idl.c
+++ b/lib/ovsdb-idl.c
@@ -160,6 +160,8 @@ ovsdb_idl_create(const char *remote, const struct ovsdb_idl_class *class)
         assert(!shash_find(&idl->table_by_name, tc->name));
         shash_add(&idl->table_by_name, tc->name, table);
         table->class = tc;
+        table->monitor_columns = bitmap_allocate(tc->n_columns);
+        bitmap_set_multiple(table->monitor_columns, 0, tc->n_columns, true);
         shash_init(&table->columns);
         for (j = 0; j < tc->n_columns; j++) {
             const struct ovsdb_idl_column *column = &tc->columns[j];
@@ -191,6 +193,7 @@ ovsdb_idl_destroy(struct ovsdb_idl *idl)
             struct ovsdb_idl_table *table = &idl->tables[i];
             shash_destroy(&table->columns);
             hmap_destroy(&table->rows);
+            free(table->monitor_columns);
         }
         shash_destroy(&idl->table_by_name);
         free(idl->tables);
@@ -359,6 +362,36 @@ ovsdb_idl_force_reconnect(struct ovsdb_idl *idl)
 {
     jsonrpc_session_force_reconnect(idl->session);
 }
+
+/* By default, 'idl' replicates all of the columns in the remote database.
+ * Call this function to omit replicating 'column'.  This saves CPU time and
+ * bandwidth to the database.
+ *
+ * This function should be called after ovsdb_idl_create(), but before the
+ * first call to ovsdb_idl_run().
+ *
+ * An omitted column may still be written through 'idl', but 'idl' will not
+ * reflect changes made by other clients.  Also, 'idl' assumes that 'column'
+ * initially has the default value for its type (see
+ * ovsdb_datum_init_default()) and it will therefore ignore any attempt to
+ * write that default value without first writing a different value. */
+void
+ovsdb_idl_omit(struct ovsdb_idl *idl, const struct ovsdb_idl_column *column)
+{
+    size_t i;
+
+    for (i = 0; i < idl->class->n_tables; i++) {
+        const struct ovsdb_idl_table *table = &idl->tables[i];
+        const struct ovsdb_idl_table_class *tc = table->class;
+
+        if (column >= tc->columns && column < &tc->columns[tc->n_columns]) {
+            bitmap_set0(table->monitor_columns, column - tc->columns);
+            return;
+        }
+    }
+
+    NOT_REACHED();
+}
 
 static void
 ovsdb_idl_send_monitor_request(struct ovsdb_idl *idl)
@@ -378,7 +411,9 @@ ovsdb_idl_send_monitor_request(struct ovsdb_idl *idl)
         columns = json_array_create_empty();
         for (i = 0; i < tc->n_columns; i++) {
             const struct ovsdb_idl_column *column = &tc->columns[i];
-            json_array_add(columns, json_string_create(column->name));
+            if (bitmap_is_set(table->monitor_columns, i)) {
+                json_array_add(columns, json_string_create(column->name));
+            }
         }
         json_object_put(monitor_request, "columns", columns);
         json_object_put(monitor_requests, tc->name, monitor_request);
diff --git a/lib/ovsdb-idl.h b/lib/ovsdb-idl.h
index e320406..31ca550 100644
--- a/lib/ovsdb-idl.h
+++ b/lib/ovsdb-idl.h
@@ -52,6 +52,8 @@ unsigned int ovsdb_idl_get_seqno(const struct ovsdb_idl *);
 bool ovsdb_idl_has_ever_connected(const struct ovsdb_idl *);
 void ovsdb_idl_force_reconnect(struct ovsdb_idl *);
 
+void ovsdb_idl_omit(struct ovsdb_idl *, const struct ovsdb_idl_column *);
+
 const struct ovsdb_idl_row *ovsdb_idl_get_row_for_uuid(
     const struct ovsdb_idl *, const struct ovsdb_idl_table_class *,
     const struct uuid *);
-- 
1.7.1





More information about the dev mailing list