diff mbox

[ovs-dev,monitor_cond,V4,13/17] ovsdb: adjust ovsdb_monitor_changes to hold rows by transaction id XOR datum

Message ID 1455796015-14898-14-git-send-email-lirans@il.ibm.com
State Superseded
Headers show

Commit Message

Liran Schour Feb. 18, 2016, 11:46 a.m. UTC
The next few patchs implements a data structure to track rows according to matched
condition's clauses. The goal is to reduce the computation of conditional monitoring
when all clauses have "==" function (which is the most common case).
This patch adjust ovsdb_monitor_changes to hold rows at transaction point in time XOR
hold rows with common column value. In the later case we need to maintain a list of
all old values that we have and set the right old value before using ovsdb_monitor_row.

Signed-off-by: Liran Schour <lirans@il.ibm.com>
---
 ovsdb/monitor.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 74 insertions(+), 6 deletions(-)
diff mbox

Patch

diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c
index e6f8a88..9c907ef 100644
--- a/ovsdb/monitor.c
+++ b/ovsdb/monitor.c
@@ -102,11 +102,19 @@  struct ovsdb_monitor_column {
     enum ovsdb_monitor_selection select;
     bool monitored;
 };
+struct ovsdb_monitor_data {
+    struct ovs_list node;
+    uint64_t transaction;
+    struct ovsdb_datum *data;
+};
 
-/* A row that has changed in a monitored table. */
+/* A row that has changed in a monitored table.
+ * Tracked by table's changes OR by ovsdb_tracked_clauses */
 struct ovsdb_monitor_row {
     struct hmap_node hmap_node; /* In ovsdb_jsonrpc_monitor_table.changes. */
     struct uuid uuid;           /* UUID of row that changed. */
+    uint64_t transaction;       /* Transaction ID at time of insertion */
+    struct ovs_list old_list;   /* List of Old data sorted by transaction */
     struct ovsdb_datum *old;    /* Old data, NULL for an inserted row. */
     struct ovsdb_datum *new;    /* New data, NULL for a deleted row. */
 };
@@ -126,6 +134,8 @@  struct ovsdb_monitor_changes {
     struct hmap rows;
     int n_refs;
     uint64_t transaction;
+    const struct ovsdb_type *type;
+    struct ovsdb_datum arg;
     struct hmap_node hmap_node;  /* Element in ovsdb_monitor_tables' changes
                                     hmap.  */
 };
@@ -178,6 +188,14 @@  static void ovsdb_monitor_changes_destroy(
                                   struct ovsdb_monitor_changes *changes);
 static void ovsdb_monitor_table_track_changes(struct ovsdb_monitor_table *mt,
                                   uint64_t unflushed);
+static void
+ovsdb_monitor_changes_update(const struct ovsdb_row *old,
+                             const struct ovsdb_row *new,
+                             const struct ovsdb_monitor_table *mt,
+                             struct ovsdb_monitor_changes *changes,
+                             uint64_t transaction);
+static void
+ovsdb_monitor_row_set_old(struct ovsdb_monitor_row *row, uint64_t transaction);
 
 static uint32_t
 json_cache_hash(enum ovsdb_monitor_version version, uint64_t from_txn)
@@ -348,7 +366,16 @@  ovsdb_monitor_row_destroy(const struct ovsdb_monitor_table *mt,
                           struct ovsdb_monitor_row *row)
 {
     if (row) {
-        free_monitor_row_data(mt, row->old);
+        if (!row->transaction) {
+            free_monitor_row_data(mt, row->old);
+        } else {
+            struct ovsdb_monitor_data *old;
+
+            LIST_FOR_EACH_POP(old, node, &row->old_list) {
+                free_monitor_row_data(mt, old->data);
+                free(old);
+            }
+        }
         free_monitor_row_data(mt, row->new);
         free(row);
     }
@@ -548,6 +575,8 @@  ovsdb_monitor_table_add_changes(struct ovsdb_monitor_table *mt,
     changes->transaction = next_txn;
     changes->mt = mt;
     changes->n_refs = 1;
+    ovsdb_datum_init_empty(&changes->arg);
+    changes->type = &ovsdb_type_boolean;
     hmap_init(&changes->rows);
     hmap_insert(&mt->changes, &changes->hmap_node, hash_uint64(next_txn));
 
@@ -611,6 +640,7 @@  ovsdb_monitor_changes_destroy(struct ovsdb_monitor_changes *changes)
         ovsdb_monitor_row_destroy(changes->mt, row);
     }
     hmap_destroy(&changes->rows);
+    ovsdb_datum_destroy(&changes->arg, changes->type);
     free(changes);
 }
 
@@ -1287,21 +1317,50 @@  ovsdb_monitor_init_aux(struct ovsdb_monitor_aux *aux,
 }
 
 static void
+ovsdb_monitor_row_set_old(struct ovsdb_monitor_row *row, uint64_t transaction)
+{
+    struct ovsdb_monitor_data *data;
+    ovs_assert(row->transaction);
+
+    LIST_FOR_EACH(data, node, &row->old_list) {
+        if (data->transaction >= transaction) {
+            break;
+        }
+    }
+    ovs_assert(data);
+
+    row->old = data->data;
+}
+
+static void
 ovsdb_monitor_changes_update(const struct ovsdb_row *old,
                              const struct ovsdb_row *new,
                              const struct ovsdb_monitor_table *mt,
-                             struct ovsdb_monitor_changes *changes)
+                             struct ovsdb_monitor_changes *changes,
+                             uint64_t transaction)
 {
     const struct uuid *uuid = ovsdb_row_get_uuid(new ? new : old);
     struct ovsdb_monitor_row *change;
 
     change = ovsdb_monitor_changes_row_find(changes, uuid);
     if (!change) {
+        struct ovsdb_datum *old_data = clone_monitor_row_data(mt, old);
+
         change = xzalloc(sizeof *change);
         hmap_insert(&changes->rows, &change->hmap_node, uuid_hash(uuid));
         change->uuid = *uuid;
-        change->old = clone_monitor_row_data(mt, old);
+        change->transaction = transaction;
         change->new = clone_monitor_row_data(mt, new);
+        list_init(&change->old_list);
+        if (!transaction) {
+            change->old = old_data;
+        } else {
+            struct ovsdb_monitor_data *data = xzalloc(sizeof *data);
+
+            data->data = old_data;
+            data->transaction = transaction;
+            list_push_back(&change->old_list, &data->node);
+        }
     } else {
         if (new) {
             update_monitor_row_data(mt, new, change->new);
@@ -1315,6 +1374,14 @@  ovsdb_monitor_changes_update(const struct ovsdb_row *old,
                 free(change);
             }
         }
+        if (transaction) {
+            /* Clauses tracked row - maintain old_list */
+            struct ovsdb_monitor_data *data = xzalloc(sizeof *data);
+
+            data->data = clone_monitor_row_data(mt, old);;
+            change->transaction = data->transaction = transaction;
+            list_push_back(&change->old_list, &data->node);
+        }
     }
 }
 
@@ -1391,9 +1458,10 @@  ovsdb_monitor_change_cb(const struct ovsdb_row *old,
     }
     HMAP_FOR_EACH(changes, hmap_node, &mt->changes) {
         if (efficacy > OVSDB_CHANGES_NO_EFFECT) {
-            ovsdb_monitor_changes_update(old, new, mt, changes);
+            ovsdb_monitor_changes_update(old, new, mt, changes, 0);
         }
     }
+
     if (aux->efficacy < efficacy) {
         aux->efficacy = efficacy;
     }
@@ -1417,7 +1485,7 @@  ovsdb_monitor_get_initial(const struct ovsdb_monitor *dbmon)
             if (!changes) {
                 changes = ovsdb_monitor_table_add_changes(mt, 0);
                 HMAP_FOR_EACH (row, hmap_node, &mt->table->rows) {
-                    ovsdb_monitor_changes_update(NULL, row, mt, changes);
+                    ovsdb_monitor_changes_update(NULL, row, mt, changes, 0);
                 }
             } else {
                 changes->n_refs++;