diff mbox

[ovs-dev,monitor_cond,V4,16/17] ovsdb: Track changed rows by clauses match

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

Commit Message

Liran Schour Feb. 18, 2016, 11:46 a.m. UTC
Track rows change by condition clauses and compose update notification
according to those tracked changes.

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

Patch

diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c
index 9e9cd5c..46d2d13 100644
--- a/ovsdb/monitor.c
+++ b/ovsdb/monitor.c
@@ -1306,6 +1306,46 @@  ovsdb_monitor_add_json_row(struct json **json, const char *table_name,
     json_object_put(*table_json, uuid, row_json);
 }
 
+/* Save processed rows to avoid duplications if row matchs more the one clause */
+struct row_uuid {
+    struct hmap_node hmap_node;
+    struct uuid uuid;
+};
+
+static bool
+uuid_exists(struct hmap *row_uuids, struct uuid *uuid)
+{
+    struct row_uuid *row_uuid;
+
+    HMAP_FOR_EACH_WITH_HASH (row_uuid, hmap_node, uuid_hash(uuid),
+                             row_uuids) {
+        if (uuid_equals(&row_uuid->uuid, uuid)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static void
+uuid_insert(struct hmap *row_uuids, struct uuid *uuid)
+{
+    struct row_uuid *row_uuid = xzalloc(sizeof *row_uuid);
+
+    row_uuid->uuid = *uuid;
+    hmap_insert(row_uuids, &row_uuid->hmap_node, uuid_hash(uuid));
+
+}
+
+static void row_uuids_destroy(struct hmap *row_uuids)
+{
+    struct row_uuid *row_uuid, *next;
+
+    HMAP_FOR_EACH_SAFE(row_uuid, next, hmap_node, row_uuids) {
+        hmap_remove(row_uuids, &row_uuid->hmap_node);
+        free(row_uuid);
+    }
+}
+
 /* Constructs and returns JSON for a <table-updates> object (as described in
  * RFC 7047) for all the outstanding changes within 'monitor', starting from
  * 'transaction'.  */
@@ -1336,7 +1376,7 @@  ovsdb_monitor_compose_update(
         if (mtc && mtc->cond_mode == MTC_MODE_FALSE) {
             continue;
         }
-        if (!mtc || !mtc->cond_mode) {
+        if (!mtc || mtc->cond_mode == MTC_MODE_TRUE) {
             cache_node = ovsdb_monitor_json_cache_search(&mt->json_cache, version, transaction);
         }
         if (cache_node) {
@@ -1348,22 +1388,59 @@  ovsdb_monitor_compose_update(
                 json_object_put(json, mt->table->schema->name, table_json);
             }
         } else {
-            changes = ovsdb_monitor_table_find_changes(mt, transaction);
-            if (!changes) {
-                continue;
-            }
+            if (!initial && mtc && mtc->cond_mode == MTC_MODE_EQ_COND) {
+                int i;
+                struct hmap row_uuids = HMAP_INITIALIZER(&row_uuids);
+
+                /* iterate over session clauses */
+                for (i = 0; i < mtc->old_condition.n_clauses; i++) {
+                    struct ovsdb_clause *clause = &mtc->old_condition.clauses[i];
+
+                    changes = ovsdb_monitor_table_find_clause_changes(mtc, clause);
+                    if (!changes) {
+                        continue;
+                    }
+
+                    HMAP_FOR_EACH_SAFE (row, next, hmap_node, &changes->rows) {
+                        struct json *row_json;
+
+                        ovsdb_monitor_row_set_old(row, transaction);
+                        if (row->transaction < transaction) {
+                            continue;
+                        }
+                        if (uuid_exists(&row_uuids, &row->uuid)) {
+                            continue;
+                        }
+                        uuid_insert(&row_uuids, &row->uuid);
+
+                        row_json = (*row_update)(mt, condition, OVSDB_MONITOR_ROW, row,
+                                                 initial, changed);
+                        if (row_json) {
+                            ovsdb_monitor_add_json_row(&json, mt->table->schema->name,
+                                                       &table_json, row_json, &row->uuid);
+                        }
+                    }
+                }
+                row_uuids_destroy(&row_uuids);
+            } else {
+                changes = ovsdb_monitor_table_find_changes(mt, transaction);
 
-            HMAP_FOR_EACH_SAFE (row, next, hmap_node, &changes->rows) {
-                struct json *row_json;
-                row_json = (*row_update)(mt, condition, OVSDB_MONITOR_ROW, row,
-                                         initial, changed);
-                if (row_json) {
-                    ovsdb_monitor_add_json_row(&json, mt->table->schema->name,
-                                               &table_json, row_json, &row->uuid);
+                if (!changes) {
+                    continue;
+                }
+
+                HMAP_FOR_EACH_SAFE (row, next, hmap_node, &changes->rows) {
+                    struct json *row_json;
+                    row_json = (*row_update)(mt, condition, OVSDB_MONITOR_ROW, row,
+                                             initial, changed);
+                    if (row_json) {
+                        ovsdb_monitor_add_json_row(&json, mt->table->schema->name,
+                                                   &table_json, row_json, &row->uuid);
+                    }
+                }
+                if (!mtc || !mtc->cond_mode) {
+                    ovsdb_monitor_json_cache_insert(&mt->json_cache, version, transaction, table_json);
                 }
-            }
-            if (!mtc || !mtc->cond_mode) {
-                ovsdb_monitor_json_cache_insert(&mt->json_cache, version, transaction, table_json);
             }
         }
     }
@@ -1665,10 +1742,13 @@  ovsdb_monitor_change_cb(const struct ovsdb_row *old,
     if (efficacy == OVSDB_CHANGES_REQUIRE_EXTERNAL_UPDATE) {
         ovsdb_monitor_json_cache_flush(&mt->json_cache);
     }
-    HMAP_FOR_EACH(changes, hmap_node, &mt->changes) {
-        if (efficacy > OVSDB_CHANGES_NO_EFFECT) {
+    if (efficacy > OVSDB_CHANGES_NO_EFFECT) {
+        HMAP_FOR_EACH(changes, hmap_node, &mt->changes) {
             ovsdb_monitor_changes_update(old, new, mt, changes, 0);
         }
+        if (mt->track_clauses) {
+            ovsdb_monitor_clauses_track_update(old, new, mt);
+        }
     }
 
     if (aux->efficacy < efficacy) {