diff options
author | Liran Schour <lirans@il.ibm.com> | 2016-07-18 11:45:50 +0300 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2016-07-18 22:58:04 -0700 |
commit | ae9cab378b4c6f2863a98089d6769da41ec94b47 (patch) | |
tree | fd2ee281368ba595c42b9a6b6615cb8cbbddef71 /ovsdb/condition.c | |
parent | ec1eadce89e0e4a900e538c7cd8756324ab6ad60 (diff) | |
download | openvswitch-ae9cab378b4c6f2863a98089d6769da41ec94b47.tar.gz |
ovsdb: add conditions utilities to support monitor_cond
Change ovsdb_condition to be a 3-element json array or a boolean value (see ovsdb-server
man page).
Conditions utilities will be used later for conditional monitoring.
Signed-off-by: Liran Schour <lirans@il.ibm.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ovsdb/condition.c')
-rw-r--r-- | ovsdb/condition.c | 186 |
1 files changed, 173 insertions, 13 deletions
diff --git a/ovsdb/condition.c b/ovsdb/condition.c index 4baf1bbe9..7bd8ee269 100644 --- a/ovsdb/condition.c +++ b/ovsdb/condition.c @@ -52,7 +52,7 @@ ovsdb_function_to_string(enum ovsdb_function function) return NULL; } -static OVS_WARN_UNUSED_RESULT struct ovsdb_error * +static struct ovsdb_error * ovsdb_clause_from_json(const struct ovsdb_table_schema *ts, const struct json *json, struct ovsdb_symbol_table *symtab, @@ -64,6 +64,18 @@ ovsdb_clause_from_json(const struct ovsdb_table_schema *ts, const char *column_name; struct ovsdb_type type; + if (json->type == JSON_TRUE || json->type == JSON_FALSE) { + clause->function = + json->type == JSON_TRUE ? OVSDB_F_TRUE : OVSDB_F_FALSE; + + /* Column and arg fields are not being used with boolean functions. + * Use dummy values */ + clause->column = ovsdb_table_schema_get_column(ts, "_uuid"); + clause->index = clause->column->index; + ovsdb_datum_init_default(&clause->arg, &clause->column->type); + return NULL; + } + if (json->type != JSON_ARRAY || json->u.array.n != 3 || json->u.array.elems[0]->type != JSON_STRING @@ -79,6 +91,7 @@ ovsdb_clause_from_json(const struct ovsdb_table_schema *ts, "No column %s in table %s.", column_name, ts->name); } + clause->index = clause->column->index; type = clause->column->type; function_name = json_string(array->elems[1]); @@ -109,7 +122,6 @@ ovsdb_clause_from_json(const struct ovsdb_table_schema *ts, return error; } break; - case OVSDB_F_EQ: case OVSDB_F_NE: break; @@ -126,6 +138,9 @@ ovsdb_clause_from_json(const struct ovsdb_table_schema *ts, type.n_min = 0; } break; + case OVSDB_F_TRUE: + case OVSDB_F_FALSE: + OVS_NOT_REACHED(); } return ovsdb_datum_from_json(&clause->arg, &type, array->elems[2], symtab); } @@ -164,6 +179,19 @@ compare_clauses_3way(const void *a_, const void *b_) } } +static int +compare_clauses_3way_with_data(const void *a_, const void *b_) +{ + const struct ovsdb_clause *a = a_; + const struct ovsdb_clause *b = b_; + int res; + + res = compare_clauses_3way(a, b); + return res ? res : ovsdb_datum_compare_3way(&a->arg, + &b->arg, + &a->column->type); + } + struct ovsdb_error * ovsdb_condition_from_json(const struct ovsdb_table_schema *ts, const struct json *json, @@ -190,7 +218,7 @@ ovsdb_condition_from_json(const struct ovsdb_table_schema *ts, /* A real database would have a query optimizer here. */ qsort(cnd->clauses, cnd->n_clauses, sizeof *cnd->clauses, - compare_clauses_3way); + compare_clauses_3way_with_data); return NULL; } @@ -198,10 +226,15 @@ ovsdb_condition_from_json(const struct ovsdb_table_schema *ts, static struct json * ovsdb_clause_to_json(const struct ovsdb_clause *clause) { - return json_array_create_3( - json_string_create(clause->column->name), - json_string_create(ovsdb_function_to_string(clause->function)), - ovsdb_datum_to_json(&clause->arg, &clause->column->type)); + if (clause->function != OVSDB_F_TRUE && + clause->function != OVSDB_F_FALSE) { + return json_array_create_3( + json_string_create(clause->column->name), + json_string_create(ovsdb_function_to_string(clause->function)), + ovsdb_datum_to_json(&clause->arg, &clause->column->type)); + } + + return json_boolean_create(clause->function == OVSDB_F_TRUE); } struct json * @@ -218,13 +251,20 @@ ovsdb_condition_to_json(const struct ovsdb_condition *cnd) } static bool -ovsdb_clause_evaluate(const struct ovsdb_row *row, - const struct ovsdb_clause *c) +ovsdb_clause_evaluate(const struct ovsdb_datum *fields, + const struct ovsdb_clause *c, + unsigned int index_map[]) { - const struct ovsdb_datum *field = &row->fields[c->column->index]; + const struct ovsdb_datum *field = &fields[index_map ? + index_map[c->column->index] : + c->column->index]; const struct ovsdb_datum *arg = &c->arg; const struct ovsdb_type *type = &c->column->type; + if (c->function == OVSDB_F_TRUE || + c->function == OVSDB_F_FALSE) { + return c->function == OVSDB_F_TRUE; + } if (ovsdb_type_is_optional_scalar(type) && field->n == 0) { switch (c->function) { case OVSDB_F_LT: @@ -237,6 +277,9 @@ ovsdb_clause_evaluate(const struct ovsdb_row *row, case OVSDB_F_NE: case OVSDB_F_EXCLUDES: return true; + case OVSDB_F_TRUE: + case OVSDB_F_FALSE: + OVS_NOT_REACHED(); } } else if (ovsdb_type_is_scalar(type) || ovsdb_type_is_optional_scalar(type)) { @@ -257,6 +300,9 @@ ovsdb_clause_evaluate(const struct ovsdb_row *row, return cmp >= 0; case OVSDB_F_GT: return cmp > 0; + case OVSDB_F_TRUE: + case OVSDB_F_FALSE: + OVS_NOT_REACHED(); } } else { switch (c->function) { @@ -272,6 +318,8 @@ ovsdb_clause_evaluate(const struct ovsdb_row *row, case OVSDB_F_LE: case OVSDB_F_GE: case OVSDB_F_GT: + case OVSDB_F_TRUE: + case OVSDB_F_FALSE: OVS_NOT_REACHED(); } } @@ -279,14 +327,24 @@ ovsdb_clause_evaluate(const struct ovsdb_row *row, OVS_NOT_REACHED(); } +static void +ovsdb_clause_clone(struct ovsdb_clause *new, struct ovsdb_clause *old) +{ + new->function = old->function; + new->column = old->column; + ovsdb_datum_clone(&new->arg, + &old->arg, + &old->column->type); +} + bool -ovsdb_condition_evaluate(const struct ovsdb_row *row, - const struct ovsdb_condition *cnd) +ovsdb_condition_match_every_clause(const struct ovsdb_row *row, + const struct ovsdb_condition *cnd) { size_t i; for (i = 0; i < cnd->n_clauses; i++) { - if (!ovsdb_clause_evaluate(row, &cnd->clauses[i])) { + if (!ovsdb_clause_evaluate(row->fields, &cnd->clauses[i], NULL)) { return false; } } @@ -294,6 +352,25 @@ ovsdb_condition_evaluate(const struct ovsdb_row *row, return true; } +/* Returns true if condition evaluation of one of the clauses is + * true. index_map[] is an optional array that if exists indicates a mapping + * between indexing row_datum to the indexes in ovsdb_column */ +bool +ovsdb_condition_match_any_clause(const struct ovsdb_datum *row_datum, + const struct ovsdb_condition *cnd, + unsigned int index_map[]) +{ + size_t i; + + for (i = 0; i < cnd->n_clauses; i++) { + if (ovsdb_clause_evaluate(row_datum, &cnd->clauses[i], index_map)) { + return true; + } + } + + return false; +} + void ovsdb_condition_destroy(struct ovsdb_condition *cnd) { @@ -303,4 +380,87 @@ ovsdb_condition_destroy(struct ovsdb_condition *cnd) ovsdb_clause_free(&cnd->clauses[i]); } free(cnd->clauses); + cnd->n_clauses = 0; +} + +void +ovsdb_condition_init(struct ovsdb_condition *cnd) +{ + cnd->clauses = NULL; + cnd->n_clauses = 0; +} + +bool +ovsdb_condition_empty(const struct ovsdb_condition *cnd) +{ + return cnd->n_clauses == 0; +} + +int +ovsdb_condition_cmp_3way(const struct ovsdb_condition *a, + const struct ovsdb_condition *b) +{ + size_t i; + int res; + + if (a->n_clauses != b->n_clauses) { + return a->n_clauses < b->n_clauses ? -1 : 1; + } + + /* We assume clauses are sorted */ + for (i = 0; i < a->n_clauses; i++) { + res = (compare_clauses_3way_with_data(&a->clauses[i], &b->clauses[i])); + if (res != 0) { + return res; + } + } + + return 0; +} + +void +ovsdb_condition_clone(struct ovsdb_condition *to, + const struct ovsdb_condition *from) +{ + size_t i; + + to->clauses = xzalloc(from->n_clauses * sizeof *to->clauses); + + for (i = 0; i < from->n_clauses; i++) { + ovsdb_clause_clone(&to->clauses[i], &from->clauses[i]); + } + to->n_clauses = from->n_clauses; +} + +/* Return true if ovsdb_condition_match_any_clause() will return true on + * any row */ +bool +ovsdb_condition_is_true(const struct ovsdb_condition *cond) +{ + return (!cond->n_clauses || + (cond->n_clauses >= 1 && (cond->clauses[0].function == OVSDB_F_TRUE)) || + (cond->n_clauses >= 2 && (cond->clauses[1].function == OVSDB_F_TRUE))); +} + +bool +ovsdb_condition_is_false(const struct ovsdb_condition *cond) +{ + return ((cond->n_clauses == 1) && + (cond->clauses[0].function == OVSDB_F_FALSE)); + } + +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; + + 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; } |