jsonrpc-server: refactoring ovsdb_jsonrpc_monitor_needs_flush
[cascardo/ovs.git] / ovsdb / jsonrpc-server.c
index 7675585..23aa3fd 100644 (file)
@@ -1121,13 +1121,17 @@ ovsdb_jsonrpc_monitor_find(struct ovsdb_jsonrpc_session *s,
 }
 
 static void
-ovsdb_add_monitor_column(struct ovsdb_monitor_table *mt,
+ovsdb_monitor_add_column(struct ovsdb_monitor *dbmon,
+                         const struct ovsdb_table *table,
                          const struct ovsdb_column *column,
                          enum ovsdb_monitor_selection select,
                          size_t *allocated_columns)
 {
+    struct ovsdb_monitor_table *mt;
     struct ovsdb_monitor_column *c;
 
+    mt = shash_find_data(&dbmon->tables, table->schema->name);
+
     if (mt->n_columns >= *allocated_columns) {
         mt->columns = x2nrealloc(mt->columns, allocated_columns,
                                  sizeof *mt->columns);
@@ -1147,12 +1151,23 @@ compare_ovsdb_monitor_column(const void *a_, const void *b_)
     return a->column < b->column ? -1 : a->column > b->column;
 }
 
+static void
+ovsdb_monitor_table_add_select(struct ovsdb_monitor *dbmon,
+                               const struct ovsdb_table *table,
+                               enum ovsdb_monitor_selection select)
+{
+    struct ovsdb_monitor_table * mt;
+    mt = shash_find_data(&dbmon->tables, table->schema->name);
+    mt->select |= select;
+}
+
 static struct ovsdb_error * OVS_WARN_UNUSED_RESULT
-ovsdb_jsonrpc_parse_monitor_request(struct ovsdb_monitor_table *mt,
+ovsdb_jsonrpc_parse_monitor_request(struct ovsdb_monitor *dbmon,
+                                    const struct ovsdb_table *table,
                                     const struct json *monitor_request,
                                     size_t *allocated_columns)
 {
-    const struct ovsdb_table_schema *ts = mt->table->schema;
+    const struct ovsdb_table_schema *ts = table->schema;
     enum ovsdb_monitor_selection select;
     const struct json *columns, *select_json;
     struct ovsdb_parser parser;
@@ -1189,8 +1204,8 @@ ovsdb_jsonrpc_parse_monitor_request(struct ovsdb_monitor_table *mt,
     } else {
         select = OJMS_INITIAL | OJMS_INSERT | OJMS_DELETE | OJMS_MODIFY;
     }
-    mt->select |= select;
 
+    ovsdb_monitor_table_add_select(dbmon, table, select);
     if (columns) {
         size_t i;
 
@@ -1209,12 +1224,13 @@ ovsdb_jsonrpc_parse_monitor_request(struct ovsdb_monitor_table *mt,
             }
 
             s = columns->u.array.elems[i]->u.string;
-            column = shash_find_data(&mt->table->schema->columns, s);
+            column = shash_find_data(&table->schema->columns, s);
             if (!column) {
                 return ovsdb_syntax_error(columns, NULL, "%s is not a valid "
                                           "column name", s);
             }
-            ovsdb_add_monitor_column(mt, column, select, allocated_columns);
+            ovsdb_monitor_add_column(dbmon, table, column, select,
+                                     allocated_columns);
         }
     } else {
         struct shash_node *node;
@@ -1222,7 +1238,7 @@ ovsdb_jsonrpc_parse_monitor_request(struct ovsdb_monitor_table *mt,
         SHASH_FOR_EACH (node, &ts->columns) {
             const struct ovsdb_column *column = node->data;
             if (column->index != OVSDB_COL_UUID) {
-                ovsdb_add_monitor_column(mt, column, select,
+                ovsdb_monitor_add_column(dbmon, table, column, select,
                                          allocated_columns);
             }
         }
@@ -1248,6 +1264,44 @@ ovsdb_monitor_create(struct ovsdb *db,
     return m;
 }
 
+static void
+ovsdb_monitor_add_table(struct ovsdb_monitor *m,
+                        const struct ovsdb_table *table)
+{
+    struct ovsdb_monitor_table *mt;
+
+    mt = xzalloc(sizeof *mt);
+    mt->table = table;
+    hmap_init(&mt->changes);
+    shash_add(&m->tables, table->schema->name, mt);
+}
+
+/* Check for duplicated column names. Return the first
+ * duplicated column's name if found. Otherwise return
+ * NULL.  */
+static const char * OVS_WARN_UNUSED_RESULT
+ovsdb_monitor_table_check_duplicates(struct ovsdb_monitor *m,
+                          const struct ovsdb_table *table)
+{
+    struct ovsdb_monitor_table *mt;
+    int i;
+
+    mt = shash_find_data(&m->tables, table->schema->name);
+
+    if (mt) {
+        /* Check for duplicate columns. */
+        qsort(mt->columns, mt->n_columns, sizeof *mt->columns,
+              compare_ovsdb_monitor_column);
+        for (i = 1; i < mt->n_columns; i++) {
+            if (mt->columns[i].column == mt->columns[i - 1].column) {
+                return mt->columns[i].column->name;
+            }
+        }
+    }
+
+    return NULL;
+}
+
 static struct jsonrpc_msg *
 ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db,
                              struct json *params,
@@ -1285,7 +1339,7 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db,
 
     SHASH_FOR_EACH (node, json_object(monitor_requests)) {
         const struct ovsdb_table *table;
-        struct ovsdb_monitor_table *mt;
+        const char *column_name;
         size_t allocated_columns;
         const struct json *mr_value;
         size_t i;
@@ -1297,10 +1351,7 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db,
             goto error;
         }
 
-        mt = xzalloc(sizeof *mt);
-        mt->table = table;
-        hmap_init(&mt->changes);
-        shash_add(&m->dbmon->tables, table->schema->name, mt);
+        ovsdb_monitor_add_table(m->dbmon, table);
 
         /* Parse columns. */
         mr_value = node->data;
@@ -1310,29 +1361,26 @@ ovsdb_jsonrpc_monitor_create(struct ovsdb_jsonrpc_session *s, struct ovsdb *db,
 
             for (i = 0; i < array->n; i++) {
                 error = ovsdb_jsonrpc_parse_monitor_request(
-                    mt, array->elems[i], &allocated_columns);
+                    m->dbmon, table, array->elems[i], &allocated_columns);
                 if (error) {
                     goto error;
                 }
             }
         } else {
             error = ovsdb_jsonrpc_parse_monitor_request(
-                mt, mr_value, &allocated_columns);
+                m->dbmon, table, mr_value, &allocated_columns);
             if (error) {
                 goto error;
             }
         }
 
-        /* Check for duplicate columns. */
-        qsort(mt->columns, mt->n_columns, sizeof *mt->columns,
-              compare_ovsdb_monitor_column);
-        for (i = 1; i < mt->n_columns; i++) {
-            if (mt->columns[i].column == mt->columns[i - 1].column) {
-                error = ovsdb_syntax_error(mr_value, NULL, "column %s "
-                                           "mentioned more than once",
-                                           mt->columns[i].column->name);
-                goto error;
-            }
+        column_name = ovsdb_monitor_table_check_duplicates(m->dbmon, table);
+
+        if (column_name) {
+            error = ovsdb_syntax_error(mr_value, NULL, "column %s "
+                                       "mentioned more than once",
+                                        column_name);
+            goto error;
         }
     }
 
@@ -1628,8 +1676,8 @@ ovsdb_monitor_compose_row_update(
  * be used as part of the initial reply to a "monitor" request, false if it is
  * going to be used as part of an "update" notification. */
 static struct json *
-ovsdb_jsonrpc_monitor_compose_table_update(
-    const struct ovsdb_jsonrpc_monitor *monitor, bool initial)
+ovsdb_monitor_compose_table_update(
+    const struct ovsdb_monitor *dbmon, bool initial)
 {
     struct shash_node *node;
     unsigned long int *changed;
@@ -1637,7 +1685,7 @@ ovsdb_jsonrpc_monitor_compose_table_update(
     size_t max_columns;
 
     max_columns = 0;
-    SHASH_FOR_EACH (node, &monitor->dbmon->tables) {
+    SHASH_FOR_EACH (node, &dbmon->tables) {
         struct ovsdb_monitor_table *mt = node->data;
 
         max_columns = MAX(max_columns, mt->n_columns);
@@ -1645,7 +1693,7 @@ ovsdb_jsonrpc_monitor_compose_table_update(
     changed = xmalloc(bitmap_n_bytes(max_columns));
 
     json = NULL;
-    SHASH_FOR_EACH (node, &monitor->dbmon->tables) {
+    SHASH_FOR_EACH (node, &dbmon->tables) {
         struct ovsdb_monitor_table *mt = node->data;
         struct ovsdb_monitor_row *row, *next;
         struct json *table_json = NULL;
@@ -1684,20 +1732,36 @@ ovsdb_jsonrpc_monitor_compose_table_update(
     return json;
 }
 
+static struct json *
+ovsdb_jsonrpc_monitor_compose_table_update(
+    const struct ovsdb_jsonrpc_monitor *monitor, bool initial)
+{
+    return ovsdb_monitor_compose_table_update(monitor->dbmon, initial);
+}
+
+static bool
+ovsdb_monitor_needs_flush(struct ovsdb_monitor *dbmon)
+{
+    struct shash_node *node;
+
+    SHASH_FOR_EACH (node, &dbmon->tables) {
+        struct ovsdb_monitor_table *mt = node->data;
+
+        if (!hmap_is_empty(&mt->changes)) {
+            return true;
+        }
+    }
+    return false;
+}
+
 static bool
 ovsdb_jsonrpc_monitor_needs_flush(struct ovsdb_jsonrpc_session *s)
 {
     struct ovsdb_jsonrpc_monitor *m;
 
     HMAP_FOR_EACH (m, node, &s->monitors) {
-        struct shash_node *node;
-
-        SHASH_FOR_EACH (node, &m->dbmon->tables) {
-            struct ovsdb_monitor_table *mt = node->data;
-
-            if (!hmap_is_empty(&mt->changes)) {
-                return true;
-            }
+        if (ovsdb_monitor_needs_flush(m->dbmon)) {
+            return true;
         }
     }