diff options
author | Ben Pfaff <blp@ovn.org> | 2016-10-07 09:47:43 -0700 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2018-02-16 15:08:08 -0800 |
commit | 01928c964f572fb0551c999437557458f326be3e (patch) | |
tree | c9eec1da58096529e05cc3a08d3624d108e5e75a /ovsdb/ovsdb-idlc.in | |
parent | 00386a6921329d3449a93d536f86a756dedb14b3 (diff) | |
download | openvswitch-01928c964f572fb0551c999437557458f326be3e.tar.gz |
ovsdb-idlc: Implement synthetic columns.
A synthetic column is one that is not present in the actual database but
instead calculated by code in the client based on columns in the row. This
can be useful to avoid repeatedly calculating the same function of a row.
Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ovsdb/ovsdb-idlc.in')
-rwxr-xr-x | ovsdb/ovsdb-idlc.in | 89 |
1 files changed, 85 insertions, 4 deletions
diff --git a/ovsdb/ovsdb-idlc.in b/ovsdb/ovsdb-idlc.in index 95bb9f4ca..1ea2115c0 100755 --- a/ovsdb/ovsdb-idlc.in +++ b/ovsdb/ovsdb-idlc.in @@ -119,8 +119,42 @@ def cMembers(prefix, tableName, columnName, column, const, refTable=True): return (comment, members) +# This is equivalent to sorted(table.columns.items()), except that the +# sorting includes a topological component: if column B has a +# dependency on column A, then A will be sorted before B. def sorted_columns(table): - return sorted(table.columns.items()) + input = [] + for name, column in table.columns.items(): + dependencies = column.extensions.get('dependencies', []) + for d in dependencies: + if d not in table.columns: + sys.stderr.write("Table %s column %s depends on column %s " + "but there is no such column\n" + % (table.name, name, d)) + sys.exit(1) + input += [(name, column, set(dependencies))] + + output = [] + satisfied_dependencies = set() + while input: + done = [] + next = [] + for name, column, dependencies in input: + if dependencies <= satisfied_dependencies: + done += [(name, column)] + else: + next += [(name, column, dependencies)] + + if not done: + sys.stderr.write("Table %s columns have circular dependencies\n" + % table.name) + sys.exit(1) + + for name, column in done: + satisfied_dependencies.add(name) + output += sorted(done) + input = next + return output # If a column name in the schema is a C or C++ keyword, append an underscore # to the column name. @@ -179,6 +213,9 @@ extern "C" { print("\tstruct ovsdb_idl_row header_;") for columnName, column in sorted_columns(table): print("\n\t/* %s column. */" % columnName) + if column.extensions.get("members"): + print("\t%s" % column.extensions["members"]) + continue comment, members = cMembers(prefix, tableName, columnName, column, False) for member in members: @@ -261,10 +298,14 @@ bool %(s)s_is_updated(const struct %(s)s *, enum %(s)s_column_id); ''' % {'s': structName, 'S': structName.upper()}) for columnName, column in sorted_columns(table): + if column.extensions.get('synthetic'): + continue print('void %(s)s_verify_%(c)s(const struct %(s)s *);' % {'s': structName, 'c': columnName}) print("") for columnName, column in sorted_columns(table): + if column.extensions.get('synthetic'): + continue if column.type.value: valueParam = ', enum ovsdb_atomic_type value_type' else: @@ -274,6 +315,8 @@ bool %(s)s_is_updated(const struct %(s)s *, enum %(s)s_column_id); print("") for columnName, column in sorted_columns(table): + if column.extensions.get('synthetic'): + continue print('void %(s)s_set_%(c)s(const struct %(s)s *,' % {'s': structName, 'c': columnName}, end=' ') if column.type.is_smap(): args = ['const struct smap *'] @@ -285,6 +328,8 @@ bool %(s)s_is_updated(const struct %(s)s *, enum %(s)s_column_id); print("") for columnName, column in sorted_columns(table): + if column.extensions.get('synthetic'): + continue if column.type.is_map(): print('void %(s)s_update_%(c)s_setkey(const struct %(s)s *, ' % {'s': structName, 'c': columnName}, end=' ') print('%(coltype)s, %(valtype)s);' % {'coltype':column.type.key.to_const_c_type(prefix), 'valtype':column.type.value.to_const_c_type(prefix)}) @@ -391,6 +436,21 @@ static struct %(s)s * # Parse functions. for columnName, column in sorted_columns(table): + if 'parse' in column.extensions: + print(''' +static void +%(s)s_parse_%(c)s(struct ovsdb_idl_row *row_, const struct ovsdb_datum *datum OVS_UNUSED) +{ + struct %(s)s *row = %(s)s_cast(row_);\ +''' % {'s': structName, 'c': columnName}) + print(column.extensions["parse"]) + print("}") + continue + if column.extensions.get('synthetic'): + # Synthetic columns aren't parsed from a datum. + unused = " OVS_UNUSED" + else: + unused = "" print(''' static void %(s)s_parse_%(c)s(struct ovsdb_idl_row *row_, const struct ovsdb_datum *datum) @@ -398,6 +458,10 @@ static void struct %(s)s *row = %(s)s_cast(row_);''' % {'s': structName, 'c': columnName}) type = column.type + if 'parse' in column.extensions: + print(column.extensions["parse"]) + print("}") + continue if type.value: keyVar = "row->key_%s" % columnName valueVar = "row->value_%s" % columnName @@ -479,15 +543,16 @@ static void # Unparse functions. for columnName, column in sorted_columns(table): type = column.type - if type.is_smap() or (type.n_min != 1 or type.n_max != 1) and not type.is_optional_pointer(): + if (type.is_smap() or (type.n_min != 1 or type.n_max != 1) and not type.is_optional_pointer()) or 'unparse' in column.extensions: print(''' static void %(s)s_unparse_%(c)s(struct ovsdb_idl_row *row_) { struct %(s)s *row = %(s)s_cast(row_);''' % {'s': structName, 'c': columnName}) - - if type.is_smap(): + if 'unparse' in column.extensions: + print(column.extensions["unparse"]) + elif type.is_smap(): print(" smap_destroy(&row->%s);" % columnName) else: if type.value: @@ -628,6 +693,8 @@ bool # Verify functions. for columnName, column in sorted_columns(table): + if column.extensions.get('synthetic'): + continue print(''' /* Causes the original contents of column "%(c)s" in 'row' to be * verified as a prerequisite to completing the transaction. That is, if @@ -663,6 +730,8 @@ void # Get functions. for columnName, column in sorted_columns(table): + if column.extensions.get('synthetic'): + continue if column.type.value: valueParam = ',\n\tenum ovsdb_atomic_type value_type OVS_UNUSED' valueType = '\n ovs_assert(value_type == %s);' % column.type.value.toAtomicType() @@ -703,6 +772,8 @@ const struct ovsdb_datum * # Set functions. for columnName, column in sorted_columns(table): + if column.extensions.get('synthetic'): + continue type = column.type comment, members = cMembers(prefix, tableName, columnName, @@ -817,6 +888,8 @@ void print("}") # Update/Delete of partial map column functions for columnName, column in sorted_columns(table): + if column.extensions.get('synthetic'): + continue type = column.type if type.is_map(): print(''' @@ -926,6 +999,8 @@ void # Add clause functions. for columnName, column in sorted_columns(table): + if column.extensions.get('synthetic'): + continue type = column.type comment, members = cMembers(prefix, tableName, columnName, @@ -1299,6 +1374,10 @@ void mutable = "true" else: mutable = "false" + if column.extensions.get("synthetic"): + synthetic = "true" + else: + synthetic = "false" type_init = '\n'.join(" " + x for x in column.type.cInitType("%s_col_%s" % (tableName, columnName), prereqs)) print("""\ @@ -1308,6 +1387,7 @@ void %(type)s }, .is_mutable = %(mutable)s, + .is_synthetic = %(synthetic)s, .parse = %(s)s_parse_%(c)s, .unparse = %(s)s_unparse_%(c)s, },\n""" % {'P': prefix.upper(), @@ -1316,6 +1396,7 @@ void 'C': columnName.upper(), 's': structName, 'mutable': mutable, + 'synthetic': synthetic, 'type': type_init, 'column_name_in_schema': column.name}) print("};") |