Some DB modification transactions won't affect the columns of a monitor. Skip those updates.
Signed-off-by: Andy Zhou <az...@nicira.com> --- ovsdb/monitor.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c index 107bdef..d9ac6d8 100644 --- a/ovsdb/monitor.c +++ b/ovsdb/monitor.c @@ -673,6 +673,28 @@ ovsdb_monitor_table_add_select(struct ovsdb_monitor *dbmon, mt->select |= select; } + /* + * If a row's change type (insert, delete or modify) matches that of + * the monitor, they should be sent to the monitor's clients as updates. + * Of cause, the monitor should also internally update with this change. + * + * Even if when the change type does not require client updates, the monitor + * may still keep track of certain changes in order to generate correct + * updates in the future. For example, when DB inserts a new row. Even if the + * 'insert' change type is not being monitored, the monitor internal + * state still needs to be updated, so that it can produce the correct + * initial state for a new client. + * + * On the other hand, if a transaction only contains changes to columns + * that are not monitored, this transaction can be safely ignored by the + * monitor. */ +enum ovsdb_monitor_changes_efficacy { + OVSDB_CHANGES_NO_EFFECT, /* Monitor does not care about this + change. */ + OVSDB_CHANGES_REQUIRE_INTERNAL_UPDATE, /* Monitor internal updates. */ + OVSDB_CHANGES_REQUIRE_EXTERNAL_UPDATE, /* Client needs to be updated. */ +}; + struct ovsdb_monitor_aux { const struct ovsdb_monitor *monitor; struct ovsdb_monitor_table *mt; @@ -719,6 +741,42 @@ ovsdb_monitor_changes_update(const struct ovsdb_row *old, } static bool +ovsdb_monitor_columns_changed(const struct ovsdb_monitor_table *mt, + const unsigned long int *changed) +{ + size_t i; + + for (i = 0; i < mt->n_columns; i++) { + size_t column_index = mt->columns[i].column->index; + + if (bitmap_is_set(changed, column_index)) { + return true; + } + } + + return false; +} + +/* Return the efficacy of a row's change to a monitor table. + * + * Please see the block comment above 'ovsdb_monitor_changes_efficacy' + * definition form more information. */ +static enum ovsdb_monitor_changes_efficacy +ovsdb_monitor_changes_classify(enum ovsdb_monitor_selection type, + const struct ovsdb_monitor_table *mt, + const unsigned long int *changed) +{ + if (type == OJMS_MODIFY && + !ovsdb_monitor_columns_changed(mt, changed)) { + return OVSDB_CHANGES_NO_EFFECT; + } + + return (mt->select & type) + ? OVSDB_CHANGES_REQUIRE_EXTERNAL_UPDATE + : OVSDB_CHANGES_REQUIRE_INTERNAL_UPDATE; +} + +static bool ovsdb_monitor_change_cb(const struct ovsdb_row *old, const struct ovsdb_row *new, const unsigned long int *changed OVS_UNUSED, @@ -741,8 +799,16 @@ ovsdb_monitor_change_cb(const struct ovsdb_row *old, mt = aux->mt; HMAP_FOR_EACH(changes, hmap_node, &mt->changes) { - ovsdb_monitor_changes_update(old, new, mt, changes); + enum ovsdb_monitor_changes_efficacy efficacy; + enum ovsdb_monitor_selection type; + + type = ovsdb_monitor_row_update_type(false, old, new); + efficacy = ovsdb_monitor_changes_classify(type, mt, changed); + if (efficacy > OVSDB_CHANGES_NO_EFFECT) { + ovsdb_monitor_changes_update(old, new, mt, changes); + } } + return true; } -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev