}
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);
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;
} 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;
}
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;
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);
}
}
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,
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;
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;
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;
}
}
* 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;
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);
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;
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;
}
}