[ovs-dev] [PATCH monitor_cond V3 04/10] ovsdb: generate update notifications for monitor_cond session

Liran Schour LIRANS at il.ibm.com
Sun Feb 7 09:10:54 UTC 2016


Andy Zhou <azhou at ovn.org> wrote on 05/02/2016 10:47:48 AM:

> 
> Only a few small comments in line. 
> 
> On Wed, Feb 3, 2016 at 5:53 AM, Liran Schour <lirans at il.ibm.com> wrote:
> Hold session's conditions in ovsdb_monitor_session_condition. Pass it
> to ovsdb_monitor for generating "update2" notifications.
> Add functions that can generate "update2" notification for a
> "monitor_cond" session.
> json_cache is enabled only for session's with nulled or empty condition.
> "monitor_cond" and "monitor_cond_change" are RFC 7047 extensions
> described by ovsdb-server(1) manpage.
> 
> Signed-off-by: Liran Schour <lirans at il.ibm.com>
> 
> ---
> v2->v3:
> * Document monitor_cond_update receives a single json condition
> * Pass session's condition down to row_update function
> * Do not classify modify as delete or insert since we send update
>   due to cond_update with empty changes list
> * Allow conditions with non-monitored columns
> * Bug fix: allow json cache when session's condition is NULL
> * Bug fix: allow json cahce when all table's conditions are empty
> ---
>  ovsdb/condition.c       |  21 ++++
>  ovsdb/condition.h       |   4 +
>  ovsdb/jsonrpc-server.c  |  37 ++++++-
>  ovsdb/monitor.c         | 261 +++++++++++++++++++++++++++++++++++++
> +++++++----
>  ovsdb/monitor.h         |  40 +++++++-
>  ovsdb/ovsdb-server.1.in | 230 
+++++++++++++++++++++++++++++++++++++++---
>  6 files changed, 551 insertions(+), 42 deletions(-)
> 
> diff --git a/ovsdb/condition.c b/ovsdb/condition.c
> index 7321640..5edee5b 100644
> --- a/ovsdb/condition.c
> +++ b/ovsdb/condition.c
> @@ -444,3 +444,24 @@ ovsdb_condition_clone(struct ovsdb_condition *to,
>      }
>      to->n_clauses = from->n_clauses;
>  }
> +
> +const struct ovsdb_column **
> +ovsdb_condition_get_columns(const struct ovsdb_condition *cond,
> +                            size_t *n_columns)
> +{
> +    const struct ovsdb_column **columns;
> +    size_t i;
> +
> +    if (!cond->n_clauses) {
> +        *n_columns = 0;
> +        return NULL;
> +    }
> +
> +    columns = xmalloc(cond->n_clauses * sizeof *columns);
> +    for (i = 0; i < cond->n_clauses; i++) {
> +        columns[i] = cond->clauses[i].column;
> +    }
> +    *n_columns = i;
> +
> +    return columns;
> +}
> diff --git a/ovsdb/condition.h b/ovsdb/condition.h
> index 318efba..e65b8c3 100644
> --- a/ovsdb/condition.h
> +++ b/ovsdb/condition.h
> @@ -82,4 +82,8 @@ int ovsdb_condition_cmp(const struct ovsdb_condition 
*a,
>  void ovsdb_condition_clone(struct ovsdb_condition *to,
>                             const struct ovsdb_condition *from);
> 
> +const struct ovsdb_column **
> +ovsdb_condition_get_columns(const struct ovsdb_condition *cond,
> +                            size_t *n_columns);
> +
>  #endif /* ovsdb/condition.h */
> diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c
> index fcda8dc..fa5d5c4 100644
> --- a/ovsdb/jsonrpc-server.c
> +++ b/ovsdb/jsonrpc-server.c
> @@ -28,6 +28,7 @@
>  #include "ovsdb-error.h"
>  #include "ovsdb-parser.h"
>  #include "ovsdb.h"
> +#include "condition.h"
>  #include "poll-loop.h"
>  #include "reconnect.h"
>  #include "row.h"
> @@ -849,14 +850,16 @@ ovsdb_jsonrpc_session_got_request(struct 
> ovsdb_jsonrpc_session *s,
>              reply = execute_transaction(s, db, request);
>          }
>      } else if (!strcmp(request->method, "monitor") ||
> -               (monitor2_enable__ && !strcmp(request->method, 
"monitor2"))) {
> +               (monitor2_enable__ && !strcmp(request->method, 
"monitor2")) ||
> +               !strcmp(request->method, "monitor_cond")) {
>          struct ovsdb *db = ovsdb_jsonrpc_lookup_db(s, request, &reply);
>          if (!reply) {
>              int l = strlen(request->method) - strlen("monitor");
>              enum ovsdb_monitor_version version = l ? OVSDB_MONITOR_V2
>                                                     : OVSDB_MONITOR_V1;
>              reply = ovsdb_jsonrpc_monitor_create(s, db, 
request->params,
> -                                                 version, request->id);
> +                                                 version,
> +                                                 request->id);
> Is this change intentional?  
>   

No. Will remove it.
       }
>      } else if (!strcmp(request->method, "monitor_cancel")) {
>          reply = ovsdb_jsonrpc_monitor_cancel(s, 
json_array(request->params),
> @@ -1048,6 +1051,7 @@ struct ovsdb_jsonrpc_monitor {
>      uint64_t unflushed;         /* The first transaction that has not 
been
>                                         flushed to the jsonrpc 
> remote client. */
>      enum ovsdb_monitor_version version;
> +    struct ovsdb_monitor_session_condition *condition;/* Session's 
> condition */
>  };
> 
>  static struct ovsdb_jsonrpc_monitor *
> @@ -1077,18 +1081,24 @@ parse_bool(struct ovsdb_parser *parser, 
> const char *name, bool default_value)
>  static struct ovsdb_error * OVS_WARN_UNUSED_RESULT
>  ovsdb_jsonrpc_parse_monitor_request(struct ovsdb_monitor *dbmon,
>                                      const struct ovsdb_table *table,
> +                                    struct 
> ovsdb_monitor_session_condition *cond,
>                                      const struct json *monitor_request)
>  {
>      const struct ovsdb_table_schema *ts = table->schema;
>      enum ovsdb_monitor_selection select;
> -    const struct json *columns, *select_json;
> +    const struct json *columns, *select_json, *where = NULL;
>      struct ovsdb_parser parser;
>      struct ovsdb_error *error;
> 
>      ovsdb_parser_init(&parser, monitor_request, "table %s", ts->name);
> +    if (cond) {
> +        where = ovsdb_parser_member(&parser, "where", OP_ARRAY | 
> OP_OPTIONAL);
> +    }
>      columns = ovsdb_parser_member(&parser, "columns", OP_ARRAY | 
> OP_OPTIONAL);
> +
>      select_json = ovsdb_parser_member(&parser, "select",
>                                        OP_OBJECT | OP_OPTIONAL);
> +
>      error = ovsdb_parser_finish(&parser);
>      if (error) {
>          return error;
> @@ -1155,6 +1165,12 @@ ovsdb_jsonrpc_parse_monitor_request(struct 
> ovsdb_monitor *dbmon,
>              }
>          }
>      }
> +    if (cond) {
> +        error = ovsdb_monitor_table_condition_add(cond, table, where);
> +        if (error) {
> +            return error;
> +        }
> +    }
> 
>      return NULL;
>  }
> @@ -1193,6 +1209,9 @@ ovsdb_jsonrpc_monitor_create(struct 
> ovsdb_jsonrpc_session *s, struct ovsdb *db,
>      m->session = s;
>      m->db = db;
>      m->dbmon = ovsdb_monitor_create(db, m);
> +    if (version == OVSDB_MONITOR_V2) {
> +        m->condition = ovsdb_monitor_session_condition_create();
> +    }
>      m->unflushed = 0;
>      m->version = version;
>      hmap_insert(&s->monitors, &m->node, json_hash(monitor_id, 0));
> @@ -1221,6 +1240,7 @@ 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(m->dbmon,
>                                                              table,
> +                                                            
m->condition,
>                                                             
 array->elems[i]);
>                  if (error) {
>                      goto error;
> @@ -1229,6 +1249,7 @@ ovsdb_jsonrpc_monitor_create(struct 
> ovsdb_jsonrpc_session *s, struct ovsdb *db,
>          } else {
>              error = ovsdb_jsonrpc_parse_monitor_request(m->dbmon,
>                                                          table,
> +                                                        m->condition,
>                                                          mr_value);
>              if (error) {
>                  goto error;
> @@ -1253,6 +1274,11 @@ ovsdb_jsonrpc_monitor_create(struct 
> ovsdb_jsonrpc_session *s, struct ovsdb *db,
>          m->dbmon = dbmon;
>      }
> 
> +    /* We only add conditions columns here to simplify 
ovsdb_monitor_add */
> +    if (m->condition) {
> +        ovsdb_monitor_add_all_condition_columns(m->dbmon, 
m->condition);
> +    }
> +
>      ovsdb_monitor_get_initial(m->dbmon);
>      json = ovsdb_jsonrpc_monitor_compose_update(m, true);
>      json = json ? json : json_object_create();
> @@ -1305,7 +1331,7 @@ ovsdb_jsonrpc_monitor_compose_update(struct 
> ovsdb_jsonrpc_monitor *m,
>                                       bool initial)
>  {
>      return ovsdb_monitor_get_update(m->dbmon, initial, &m->unflushed,
> -                                    m->version);
> +                                    m->condition, m->version);
>  }
> 
>  static bool
> @@ -1328,6 +1354,9 @@ ovsdb_jsonrpc_monitor_destroy(struct 
> ovsdb_jsonrpc_monitor *m)
>      json_destroy(m->monitor_id);
>      hmap_remove(&m->session->monitors, &m->node);
>      ovsdb_monitor_remove_jsonrpc_monitor(m->dbmon, m);
> +    if (m->condition) {
> +        ovsdb_monitor_session_condition_destroy(m->condition);
> +    }
>      free(m);
>  }
> 
> diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c
> index 7802560..1614d67 100644
> --- a/ovsdb/monitor.c
> +++ b/ovsdb/monitor.c
> @@ -27,6 +27,7 @@
>  #include "ovsdb-parser.h"
>  #include "ovsdb.h"
>  #include "row.h"
> +#include "condition.h"
>  #include "simap.h"
>  #include "hash.h"
>  #include "table.h"
> @@ -41,6 +42,20 @@
>  static const struct ovsdb_replica_class ovsdb_jsonrpc_replica_class;
>  static struct hmap ovsdb_monitors = HMAP_INITIALIZER(&ovsdb_monitors);
> 
> +/* Keep state of session's conditions */
> +struct ovsdb_monitor_session_condition {
> +    size_t n_empty_cnd;
> +    struct shash tables;     /* Contains
> +                              *   "struct 
> ovsdb_monitor_table_condition *"s. */
> +};
> +
> +/* Monitored table session's conditions */
> +struct ovsdb_monitor_table_condition {
> +    const struct ovsdb_table *table;
> +    struct ovsdb_condition old_condition;
> +    struct ovsdb_condition new_condition;
> +};
> +
>  /*  Backend monitor.
>   *
>   *  ovsdb_monitor keep track of the ovsdb changes.
> @@ -108,6 +123,7 @@ struct ovsdb_monitor_changes {
>  /* A particular table being monitored. */
>  struct ovsdb_monitor_table {
>      const struct ovsdb_table *table;
> +    const struct ovsdb_monitor *dbmon;
> 
>      /* This is the union (bitwise-OR) of the 'select' values in all of 
the
>       * members of 'columns' below. */
> @@ -129,9 +145,11 @@ struct ovsdb_monitor_table {
>  };
> 
>  typedef struct json *
> -(*compose_row_update_cb_func)(const struct ovsdb_monitor_table *mt,
> -                              const struct ovsdb_monitor_row *row,
> -                              bool initial, unsigned long int 
*changed);
> +(*compose_row_update_cb_func)
> +    (const struct ovsdb_monitor_table *mt,
> +     const struct ovsdb_monitor_session_condition * condition,
> +     const struct ovsdb_monitor_row *row,
> +     bool initial, unsigned long int *changed);
> 
>  static void ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon);
>  static struct ovsdb_monitor_changes * ovsdb_monitor_table_add_changes(
> @@ -372,6 +390,7 @@ ovsdb_monitor_add_table(struct ovsdb_monitor *m,
> 
>      mt = xzalloc(sizeof *mt);
>      mt->table = table;
> +    mt->dbmon = m;
>      shash_add(&m->tables, table->schema->name, mt);
>      hmap_init(&mt->changes);
>      mt->columns_index_map =
> @@ -390,9 +409,20 @@ ovsdb_monitor_add_column(struct ovsdb_monitor 
*dbmon,
>  {
>      struct ovsdb_monitor_table *mt;
>      struct ovsdb_monitor_column *c;
> +    int i;
> 
>      mt = shash_find_data(&dbmon->tables, table->schema->name);
> 
> +    /* Check duplication only for non-monitored columns */
> +    if (!monitored) {
> +        for (i = 0; i < mt->n_columns; i++) {
> +            if (mt->columns[i].column == column) {
> +                /* column exists */
> +                return;
> +            }
> +        }
> +    }
> +
>      if (mt->n_columns >= mt->allocated_columns) {
>          mt->columns = x2nrealloc(mt->columns, &mt->allocated_columns,
>                                   sizeof *mt->columns);
> @@ -409,6 +439,39 @@ ovsdb_monitor_add_column(struct ovsdb_monitor 
*dbmon,
>      }
>  }
> 
> +static void
> +ovsdb_monitor_condition_add_columns(struct ovsdb_monitor *dbmon,
> +                                    const struct ovsdb_table *table,
> +                                    struct ovsdb_condition *condition)
> +{
> +    size_t n_columns;
> +    int i;
> +    const struct ovsdb_column **columns =
> +        ovsdb_condition_get_columns(condition, &n_columns);
> +
> +    for (i = 0; i < n_columns; i++) {
> +        ovsdb_monitor_add_column(dbmon, table, columns[i],
> +                                 OJMS_NONE, false);
> +    }
> +    if (n_columns) {
> +        free(columns);
> +    }
> +}
> +
> +void
> +ovsdb_monitor_add_all_condition_columns(
> +                          struct ovsdb_monitor *dbmon,
> +                          struct ovsdb_monitor_session_condition *cond)
> +{
> +    struct shash_node *node;
> +
> +    SHASH_FOR_EACH(node, &cond->tables) {
> +        struct ovsdb_monitor_table_condition *mtc = node->data;
> +
> +        ovsdb_monitor_condition_add_columns(dbmon, mtc->table, 
> &mtc->new_condition);
> +    }
> +}
> +
>  /* Check for duplicated column names. Return the first
>   * duplicated column's name if found. Otherwise return
>   * NULL.  */
> @@ -519,6 +582,153 @@ ovsdb_monitor_row_update_type(bool initial, 
> const bool old, const bool new)
>              : !new ? OJMS_DELETE
>              : OJMS_MODIFY;
>  }
> +
> +/* Returnes an empty allocated session's condition state holder */
> +struct ovsdb_monitor_session_condition *
> +ovsdb_monitor_session_condition_create(void)
> +{
> +    struct ovsdb_monitor_session_condition *condition;
> +
> +    condition = xzalloc(sizeof *condition);
> +    shash_init(&condition->tables);
> +
> +    return condition;
> +}
> +
> +void
> +ovsdb_monitor_session_condition_destroy(
> +                           struct ovsdb_monitor_session_condition 
*condition)
> +{
> +    struct shash_node *node, *next;
> +
> +    SHASH_FOR_EACH_SAFE (node, next, &condition->tables) {
> +        struct ovsdb_monitor_table_condition *mtc = node->data;
> +
> +        ovsdb_condition_destroy(&mtc->new_condition);
> +        ovsdb_condition_destroy(&mtc->old_condition);
> +        shash_delete(&condition->tables, node);
> +        free(mtc);
> +    }
> +    free(condition);
> +}
> +
> +struct ovsdb_error *
> +ovsdb_monitor_table_condition_add(
> +                         struct ovsdb_monitor_session_condition 
*condition,
> +                         const struct ovsdb_table *table,
> +                         const struct json *json_cnd)
> +{
> +    struct ovsdb_monitor_table_condition *mtc;
> +    struct ovsdb_error *error;
> +
> +    mtc = xzalloc(sizeof *mtc);
> +    shash_add(&condition->tables, table->schema->name, mtc);
> +    mtc->table = table;
> +    ovsdb_condition_init(&mtc->old_condition);
> +    ovsdb_condition_init(&mtc->new_condition);
> +
> +    if (json_cnd) {
> +        error = ovsdb_condition_from_json(table->schema,
> +                                          json_cnd,
> +                                          NULL,
> +                                          &mtc->old_condition);
> +        if (error) {
> +            return ovsdb_syntax_error(json_cnd,
> +                                      NULL, "array of conditions 
expected");
> +        }
> +    }
> +    ovsdb_condition_clone(&mtc->new_condition, &mtc->old_condition);
> +    if (ovsdb_condition_empty(&mtc->old_condition)) {
> +        condition->n_empty_cnd++;
> +    }
> +
> +    return NULL;
> +}
> +
> +static inline bool
> +ovsdb_can_cache(const struct ovsdb_monitor_session_condition 
*condition)
> +{
> +    return shash_count(&condition->tables) == condition->n_empty_cnd;
> +}
> +
> +static bool
> +ovsdb_monitor_get_table_conditions(
> +                      const struct ovsdb_monitor_table *mt,
> +                      const struct ovsdb_monitor_session_condition 
> *condition,
> +                      struct ovsdb_condition **old_condition,
> +                      struct ovsdb_condition **new_condition)
> +{
> +    if (!condition) {
> +        return false;
> +    }
> +
> +    struct ovsdb_monitor_table_condition *mtc =
> +        shash_find_data(&condition->tables, mt->table->schema->name);
> +
> +    if (!mtc) {
> +        return false;
> +    }
> +    *old_condition = &mtc->old_condition;
> +    *new_condition = &mtc->new_condition;
> +
> +    return true;
> +}
> +
> +static enum ovsdb_monitor_selection
> +ovsdb_monitor_row_update_type_condition(
> +                      const struct ovsdb_monitor_table *mt,
> +                      const struct ovsdb_monitor_session_condition 
> *condition,
> +                      bool initial,
> +                      const struct ovsdb_datum *old,
> +                      const struct ovsdb_datum *new,
> +                      const bool index_map)
> +{
> +    struct ovsdb_condition *old_condition, *new_condition;
> +    unsigned int *columns_index_map = index_map ? mt->columns_index_map
> +                                      : NULL;
> +    enum ovsdb_monitor_selection type =
> +        ovsdb_monitor_row_update_type(initial, old, new);
> +
> +    if (ovsdb_monitor_get_table_conditions(mt,
> +                                           condition,
> +                                           &old_condition,
> +                                           &new_condition)) {
> +        bool old_cond = !old ? false
> +            : ovsdb_condition_evaluate_or_datum(old,
> +                                                old_condition,
> +                                                columns_index_map);
> +        bool new_cond = !new ? false
> +            : ovsdb_condition_evaluate_or_datum(new,
> +                                                new_condition,
> +                                                columns_index_map);
> +
> +        if (!old_cond && !new_cond) {
> +            type = OJMS_NONE;
> +        }
> +
> +        switch (type) {
> +        case OJMS_INITIAL:
> +        case OJMS_INSERT:
> +            if (!new_cond) {
> +                type = OJMS_NONE;
> +            }
> +            break;
> +        case OJMS_MODIFY:
> +            type = !old_cond ? OJMS_INSERT : !new_cond
> +                ? OJMS_DELETE : OJMS_MODIFY;
> +            break;
> +        case OJMS_DELETE:
> +            if (!old_cond) {
> +                type = OJMS_NONE;
> +            }
> +            break;
> +        case OJMS_NONE:
> +            break;
> +        }
> +    }
> +    return type;
> +}
> +
>  static bool
>  ovsdb_monitor_row_skip_update(const struct ovsdb_monitor_table *mt,
>                                const struct ovsdb_monitor_row *row,
> @@ -563,6 +773,7 @@ ovsdb_monitor_row_skip_update(const struct 
> ovsdb_monitor_table *mt,
>  static struct json *
>  ovsdb_monitor_compose_row_update(
>      const struct ovsdb_monitor_table *mt,
> +    const struct ovsdb_monitor_session_condition *condition OVS_UNUSED,
>      const struct ovsdb_monitor_row *row,
>      bool initial, unsigned long int *changed)
>  {
> @@ -624,6 +835,7 @@ ovsdb_monitor_compose_row_update(
>  static struct json *
>  ovsdb_monitor_compose_row_update2(
>      const struct ovsdb_monitor_table *mt,
> +    const struct ovsdb_monitor_session_condition *condition,
>      const struct ovsdb_monitor_row *row,
>      bool initial, unsigned long int *changed)
>  {
> @@ -631,7 +843,8 @@ ovsdb_monitor_compose_row_update2(
>      struct json *row_update2, *diff_json;
>      size_t i;
> 
> -    type = ovsdb_monitor_row_update_type(initial, row->old, row->new);
> +    type = ovsdb_monitor_row_update_type_condition(mt, condition, 
initial,
> +                                                   row->old, row->new, 
true);
>      if (ovsdb_monitor_row_skip_update(mt, row, type, changed)) {
>          return NULL;
>      }
> @@ -701,9 +914,11 @@ ovsdb_monitor_max_columns(struct ovsdb_monitor 
*dbmon)
>   * RFC 7047) for all the outstanding changes within 'monitor', starting 
from
>   * 'transaction'.  */
>  static struct json*
> -ovsdb_monitor_compose_update(struct ovsdb_monitor *dbmon,
> -                             bool initial, uint64_t transaction,
> -                             compose_row_update_cb_func row_update)
> +ovsdb_monitor_compose_update(
> +                      struct ovsdb_monitor *dbmon,
> +                      bool initial, uint64_t transaction,
> +                      const struct ovsdb_monitor_session_condition 
> *condition,
> +                      compose_row_update_cb_func row_update)
>  {
>      struct shash_node *node;
>      struct json *json;
> @@ -725,7 +940,7 @@ ovsdb_monitor_compose_update(struct ovsdb_monitor 
*dbmon,
>          HMAP_FOR_EACH_SAFE (row, next, hmap_node, &changes->rows) {
>              struct json *row_json;
> 
> -            row_json = (*row_update)(mt, row, initial, changed);
> +            row_json = (*row_update)(mt, condition, row, initial, 
changed);
>              if (row_json) {
>                  char uuid[UUID_LEN + 1];
> 
> @@ -759,11 +974,13 @@ ovsdb_monitor_compose_update(struct 
> ovsdb_monitor *dbmon,
>   * 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. */
>  struct json *
> -ovsdb_monitor_get_update(struct ovsdb_monitor *dbmon,
> -                         bool initial, uint64_t *unflushed,
> -                         enum ovsdb_monitor_version version)
> +ovsdb_monitor_get_update(
> +             struct ovsdb_monitor *dbmon,
> +             bool initial, uint64_t *unflushed,
> +             const struct ovsdb_monitor_session_condition *condition,
> +             enum ovsdb_monitor_version version)
>  {
> -    struct ovsdb_monitor_json_cache_node *cache_node;
> +    struct ovsdb_monitor_json_cache_node *cache_node = NULL;
>      struct shash_node *node;
>      struct json *json;
>      uint64_t prev_txn = *unflushed;
> @@ -771,19 +988,27 @@ ovsdb_monitor_get_update(struct ovsdb_monitor 
*dbmon,
> 
>      /* Return a clone of cached json if one exists. Otherwise,
>       * generate a new one and add it to the cache.  */
> -    cache_node = ovsdb_monitor_json_cache_search(dbmon, version, 
prev_txn);
> +    if (!condition || (condition && ovsdb_can_cache(condition))) {
> +        cache_node = ovsdb_monitor_json_cache_search(dbmon, 
> version, prev_txn);
> +    }
>      if (cache_node) {
>          json = cache_node->json ? json_clone(cache_node->json) : NULL;
>      } else {
>          if (version == OVSDB_MONITOR_V1) {
> -            json = ovsdb_monitor_compose_update(dbmon, initial, 
prev_txn,
> -                                        
ovsdb_monitor_compose_row_update);
> +            json =
> +               ovsdb_monitor_compose_update(dbmon, initial, prev_txn,
> +                                            condition,
> +                                            
> ovsdb_monitor_compose_row_update);
>          } else {
>              ovs_assert(version == OVSDB_MONITOR_V2);
> -            json = ovsdb_monitor_compose_update(dbmon, initial, 
prev_txn,
> -                                        
ovsdb_monitor_compose_row_update2);
> +            json =
> +               ovsdb_monitor_compose_update(dbmon, initial, prev_txn,
> +                                            condition,
> +                                            
> ovsdb_monitor_compose_row_update2);
> +        }
> +        if (!condition || (condition && ovsdb_can_cache(condition))) {
> +            ovsdb_monitor_json_cache_insert(dbmon, version, prev_txn, 
json);
>          }
> -        ovsdb_monitor_json_cache_insert(dbmon, version, prev_txn, 
json);
>      }
> 
>      /* Maintain transaction id of 'changes'. */
> diff --git a/ovsdb/monitor.h b/ovsdb/monitor.h
> index 1f3dc6e..0529e5a 100644
> --- a/ovsdb/monitor.h
> +++ b/ovsdb/monitor.h
> @@ -19,8 +19,11 @@
> 
>  struct ovsdb_monitor;
>  struct ovsdb_jsonrpc_monitor;
> +struct ovsdb_monitor_session_condition;
> +struct ovsdb_condition;
> 
>  enum ovsdb_monitor_selection {
> +    OJMS_NONE = 0,              /* None for this iteration */
>      OJMS_INITIAL = 1 << 0,      /* All rows when monitor is created. */
>      OJMS_INSERT = 1 << 1,       /* New rows. */
>      OJMS_DELETE = 1 << 2,       /* Deleted rows. */
> @@ -60,21 +63,50 @@ void ovsdb_monitor_add_column(struct ovsdb_monitor 
*dbmon,
>                                enum ovsdb_monitor_selection select,
>                                bool monitored);
> 
> +void ovsdb_monitor_add_all_condition_columns(struct ovsdb_monitor 
*dbmon,
> +                             struct ovsdb_monitor_session_condition 
*cond);
> +
>  const char * OVS_WARN_UNUSED_RESULT
>  ovsdb_monitor_table_check_duplicates(struct ovsdb_monitor *,
>                            const struct ovsdb_table *);
> 
> -struct json *ovsdb_monitor_get_update(struct ovsdb_monitor *dbmon,
> -                                      bool initial,
> -                                      uint64_t *unflushed_transaction,
> -                                      enum ovsdb_monitor_version 
version);
> +struct json *ovsdb_monitor_get_update(
> +               struct ovsdb_monitor *dbmon,
> +               bool initial,
> +               uint64_t *unflushed_transaction,
> +               const struct ovsdb_monitor_session_condition *condition,
> +               enum ovsdb_monitor_version version);
> 
>  void ovsdb_monitor_table_add_select(struct ovsdb_monitor *dbmon,
>                                      const struct ovsdb_table *table,
>                                      enum ovsdb_monitor_selection 
select);
> 
> +struct ovsdb_condition *
> +ovsdb_monitor_table_get_condition(struct ovsdb_monitor *dbmon,
> +                                  const struct ovsdb_table *table);
> +
> +void ovsdb_monitor_table_set_conditional(struct ovsdb_monitor *dbmon,
> +                                         const struct ovsdb_table 
*table);
> +
>  bool ovsdb_monitor_needs_flush(struct ovsdb_monitor *dbmon,
>                                 uint64_t next_transaction);
> 
>  void ovsdb_monitor_get_initial(const struct ovsdb_monitor *dbmon);
> +
> +struct ovsdb_monitor_session_condition *
> +ovsdb_monitor_session_condition_create(void);
> +
> +void
> +ovsdb_monitor_session_condition_destroy(
> +                          struct ovsdb_monitor_session_condition 
*condition);
> +struct ovsdb_error *
> +ovsdb_monitor_table_condition_add(
> +                          struct ovsdb_monitor_session_condition 
*condition,
> +                          const struct ovsdb_table *table,
> +                          const struct json *json_cnd);
> +
> +void ovsdb_monitor_session_condition_bind(
> +                           const struct ovsdb_monitor_session_condition 
*,
> +                           const struct ovsdb_monitor *);
> Is this function defined?  

No. Will remove this. Thanks.




More information about the dev mailing list