From: Arnoldo Lutz Guevara <arnoldo.lutz.guev...@hpe.com> Generates and fill the default comparators for columns with type int, real, string. Also creates the macros that allow to iterate over the contents of the index, and perform queries.
Signed-off-by: Arnoldo Lutz Guevara <arnoldo.lutz.guev...@hpe.com> Signed-off-by: Esteban Rodriguez Betancourt <esteb...@hpe.com> --- ovsdb/ovsdb-idlc.in | 116 +++++++++++++++++++++ tests/idltest.ovsschema | 6 +- tests/ovsdb-idl.at | 267 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/test-ovsdb.c | 213 +++++++++++++++++++++++++++++++++++++- 4 files changed, 599 insertions(+), 3 deletions(-) diff --git a/ovsdb/ovsdb-idlc.in b/ovsdb/ovsdb-idlc.in index 26b0de4..38c0d51 100755 --- a/ovsdb/ovsdb-idlc.in +++ b/ovsdb/ovsdb-idlc.in @@ -8,9 +8,15 @@ import sys import ovs.json import ovs.db.error import ovs.db.schema +from ovs.db.types import StringType, IntegerType, RealType argv0 = sys.argv[0] +def isColumnIndexable(column): + return not column.type.is_map() and column.type.key.is_valid() \ + and (column.type.is_scalar()) and \ + column.type.key.toAtomicType() in ['OVSDB_TYPE_STRING', 'OVSDB_TYPE_REAL', 'OVSDB_TYPE_INTEGER'] + def parseSchema(filename): return ovs.db.schema.IdlSchema.from_json(ovs.json.from_file(filename)) @@ -186,6 +192,25 @@ const struct %(s)s *%(s)s_track_get_next(const struct %(s)s *); (ROW); \\ (ROW) = %(s)s_track_get_next(ROW)) +int %(s)s_index_compare(struct ovsdb_idl_index_cursor *, const struct %(s)s *, const struct %(s)s *); +const struct %(s)s *%(s)s_index_first(struct ovsdb_idl_index_cursor *); +const struct %(s)s *%(s)s_index_next(struct ovsdb_idl_index_cursor *); +const struct %(s)s *%(s)s_index_find(struct ovsdb_idl_index_cursor *, const struct %(s)s *); +const struct %(s)s *%(s)s_index_forward_to(struct ovsdb_idl_index_cursor *, const struct %(s)s *); +const struct %(s)s *%(s)s_index_get_data(const struct ovsdb_idl_index_cursor *); +#define %(S)s_FOR_EACH_RANGE(ROW, CURSOR, FROM, TO) \\ + for ((ROW) = %(s)s_index_forward_to(CURSOR, FROM); \\ + ((ROW) && %(s)s_index_compare(CURSOR, ROW, TO) <= 0); \\ + (ROW) = %(s)s_index_next(CURSOR)) +#define %(S)s_FOR_EACH_EQUAL(ROW, CURSOR, KEY) \\ + for ((ROW) = %(s)s_index_find(CURSOR, KEY); \\ + ((ROW) && %(s)s_index_compare(CURSOR, ROW, KEY) == 0); \\ + (ROW) = %(s)s_index_next(CURSOR)) +#define %(S)s_FOR_EACH_BYINDEX(ROW, CURSOR) \\ + for ((ROW) = %(s)s_index_first(CURSOR); \\ + (ROW); \\ + (ROW) = %(s)s_index_next(CURSOR)) + void %(s)s_init(struct %(s)s *); void %(s)s_delete(const struct %(s)s *); struct %(s)s *%(s)s_insert(struct ovsdb_idl_txn *); @@ -216,6 +241,10 @@ bool %(s)s_is_updated(const struct %(s)s *, enum %(s)s_column_id); print '%s);' % ', '.join(args) print + for columnName, column in sorted(table.columns.iteritems()): + if isColumnIndexable(column): + print 'int %(s)s_index_%(c)s_cmp(const void *, const void *);' % {'s': structName, 'c': columnName} + print # Table indexes. printEnum("%stable_id" % prefix.lower(), ["%sTABLE_%s" % (prefix.upper(), tableName.upper()) for tableName in sorted(schema.tables)] + ["%sN_TABLES" % prefix.upper()]) @@ -746,7 +775,90 @@ const struct ovsdb_datum * 'S': structName.upper(), 'C': columnName.upper()} print "}" + # Column Index compare functions + for columnName, column in sorted(table.columns.iteritems()): + type = column.type + funcDict = {'OVSDB_TYPE_STRING': 'str', 'OVSDB_TYPE_REAL': 'double', 'OVSDB_TYPE_INTEGER': 'int'} + if isColumnIndexable(column): + print ''' +/* Call an internal function defined to compare "%(f)s" type columns for "%(c)s" columns + in "%(s)s" tables. + Parameters: void *row1, void * row2. Data to be compared. Must be of type corresponding the record of + the table. + Return value: 0 if both data values are equal, -1 if first parameter is less than second and 1 otherwise. + For internal use only. Not recomended to be called directly. */ ''' % {'s' : structName, 'c' : columnName, 'f': type.key.toAtomicType()} + print 'int' + print '%(s)s_index_%(c)s_cmp(const void *row1, const void *row2)' % \ + {'s': structName, 'c': columnName} + print '{' + print ' struct %(s)s *data1 = (struct %(s)s *)row1;' % { 's' : structName } + print ' struct %(s)s *data2 = (struct %(s)s *)row2;' % { 's' : structName } + print ' return ovsdb_idl_index_%(f)scmp(data1->%(c)s, data2->%(c)s);' % \ + {'c': columnName, 'f': funcDict[type.key.toAtomicType()] } + print "}" +# Index table related functions + print ''' +/* This function is used to compare "%(s)s" records on table in iterartion loops for compound-index operations. + After been called, cursor point to current position in the index + Parameters: struct ovsdb_idl_index_cursor *cursor. Cursor used to iterate over the indexed data on this table. + const struct "%(s)s" *const_data1, const struct "%(s)s" *const_data2. Data to be compared. + Return value: 0 if both data values are equal, -1 if first parameter is less than second and 1 otherwise. */''' % {'s' : structName} + print 'int' + print '''%(s)s_index_compare(struct ovsdb_idl_index_cursor *cursor, const struct %(s)s *const_data1, const struct %(s)s *const_data2) +{ + struct %(s)s *data1 = CONST_CAST(struct %(s)s *, const_data1); + struct %(s)s *data2 = CONST_CAST(struct %(s)s *, const_data2); + return ovsdb_idl_index_compare(cursor, &data1->header_, &data2->header_); +}''' % { 's' : structName } + print ''' +/* This function is called to position the cursor at the first row in "%(s)s" table on the associated compound-index. + Parameters: struct ovsdb_idl_index_cursor *cursor. Cursor used to iterate over the indexed data on this table. + Return value: The first row in the corresponding index. */''' % {'s' : structName } + print '''const struct %(s)s *\n%(s)s_index_first(struct ovsdb_idl_index_cursor *cursor) +{ + return %(s)s_cast(ovsdb_idl_index_first(cursor)); +}''' % { 's' : structName } + print ''' +/* This function is called to position the cursor at the next row in "%(s)s" table on the associated compound-index. + Parameters: struct ovsdb_idl_index_cursor *cursor. Cursor used to iterate over the indexed data on this table. + Return value: The next row in the corresponding index. */''' % {'s' : structName, 'c' : columnName } + print '''const struct %(s)s *\n%(s)s_index_next(struct ovsdb_idl_index_cursor *cursor) +{ + return %(s)s_cast(ovsdb_idl_index_next(cursor)); +}''' % { 's' : structName } + print ''' +/* This function is used to find the data of the row in "%(s)s" table that meet criteria with the requested data + associated in the compound-index. + Parameters: struct ovsdb_idl_index_cursor *cursor. Cursor used to iterate over the indexed data on this table. + const struct %(s)s *const_data. Data to be searched. + Return value: The row in the corresponding index if found or NULL otherwise. */''' % {'s' : structName } + print '''const struct %(s)s *\n%(s)s_index_find(struct ovsdb_idl_index_cursor *cursor, const struct %(s)s *const_data) +{ + struct %(s)s *data = CONST_CAST(struct %(s)s *, const_data); + return %(s)s_cast(ovsdb_idl_index_find(cursor, &data->header_)); +}''' % { 's' : structName } + print ''' +/* This function is used to set the cursor pointing to the row in "%(s)s" table that meet criteria of the requested data + associated in the compound-index. + Parameters: struct ovsdb_idl_index_cursor *cursor. Cursor used to iterate over the indexed data on this table. + const struct %(s)s *const_data. Data to be searched. + Return value: The row in the corresponding index closest to the criteria. */''' % {'s' : structName } + print '''const struct %(s)s *\n%(s)s_index_forward_to(struct ovsdb_idl_index_cursor *cursor, const struct %(s)s *const_data) +{ + struct %(s)s *data = CONST_CAST(struct %(s)s *, const_data); + return %(s)s_cast(ovsdb_idl_index_forward_to(cursor, &data->header_)); +}''' % { 's' : structName } + print ''' +/* This function is used to get the data of the row in the current position pointed by the cursor in + "%(s)s" table. + Parameters: struct ovsdb_idl_index_cursor *cursor. Cursor used to iterate over the indexed data on this table. + Return value: The row in the corresponding index if found or NULL otherwise. */''' % {'s' : structName, 'c' : columnName } + print '''const struct %(s)s *\n%(s)s_index_get_data(const struct ovsdb_idl_index_cursor *cursor) +{ + return %(s)s_cast(ovsdb_idl_index_data(CONST_CAST(struct ovsdb_idl_index_cursor*, cursor))); +}''' % { 's' : structName } +# End Index table related functions # Table columns. print "\nstruct ovsdb_idl_column %s_columns[%s_N_COLUMNS];" % ( structName, structName.upper()) @@ -770,6 +882,10 @@ static void\n%s_columns_init(void) print " c->mutable = %s;" % mutable print " c->parse = %(s)s_parse_%(c)s;" % d print " c->unparse = %(s)s_unparse_%(c)s;" % d + if isColumnIndexable(column): + print ' c->compare = %(s)s_index_%(c)s_cmp;' % d + else: + print ' c->compare = NULL;' print "}" # Table classes. diff --git a/tests/idltest.ovsschema b/tests/idltest.ovsschema index 1d073aa..6c7f8a9 100644 --- a/tests/idltest.ovsschema +++ b/tests/idltest.ovsschema @@ -34,7 +34,8 @@ "min": 0 } } - } + }, + "isRoot":true }, "link2": { "columns": { @@ -104,7 +105,8 @@ "min": 0 } } - } + }, + "isRoot":true } } } diff --git a/tests/ovsdb-idl.at b/tests/ovsdb-idl.at index 33d508c..3773c43 100644 --- a/tests/ovsdb-idl.at +++ b/tests/ovsdb-idl.at @@ -800,3 +800,270 @@ OVSDB_CHECK_IDL_TRACK([track, simple idl, initially empty, various ops], 014: updated columns: ba i ia r ra s 015: done ]]) + +# Tests to verify the functionality of the one column compound index. +# It tests index for one column string and integer indexes. +# The run of test-ovsdb generates the output of the display of data using the different indexes defined in +# the program. +# Then, some at_checks are used to verify the correctness of the corresponding index as well as the existence +# of all the rows involved in the test. +m4_define([OVSDB_CHECK_IDL_COMPOUND_INDEX_SINGLE_COLUMN_C], + [AT_SETUP([$1 - C]) + AT_KEYWORDS([ovsdb server idl compound_index_single_column compound_index positive $5]) + AT_CHECK([ovsdb-tool create db $abs_srcdir/idltest.ovsschema], + [0], [stdout], [ignore]) + AT_CHECK([ovsdb-server '-vPATTERN:console:ovsdb-server|%c|%m' --detach --no-chdir --pidfile="`pwd`"/pid --remote=punix:socket --unixctl="`pwd`"/unixctl db], [0], [ignore], [ignore]) + m4_if([$2], [], [], + [AT_CHECK([ovsdb-client transact unix:socket $2], [0], [ignore], [ignore], [kill `cat pid`])]) +# Generate the data to be tested. + AT_CHECK([test-ovsdb '-vPATTERN:console:test-ovsdb|%c|%m' -vjsonrpc -t10 -c idl-compound-index unix:socket $3], + [0], [stdout], [ignore], [kill `cat pid`]) +# Filter the rows of data that corresponds to the string index eliminating the extra columns of data. +# This is done to verifiy that the output data is in the correct and expected order. + AT_CHECK([[cat stdout | grep -oh '[0-9]\{3\}: s=.*' | sed -e 's/ i=.*//g']], + [0], [$4], [], [kill `cat pid`]) +# Here, the data is filtered and sorted in order to have all the rows in the index and be +# able to determined that all the involved rows are present. + AT_CHECK([[cat stdout | grep -oh '[0-9]\{3\}: s=.*' | sort -k 1,1n -k 2,2 -k 3,3]], + [0], [$5], [], [kill `cat pid`]) +# Filter the rows of data that corresponds to the integer index eliminating the extra columns of data. +# This is done to verifiy that the output data is in the correct and expected order. + AT_CHECK([[cat stdout | grep -oh '[0-9]\{3\}: i=.*' | sed -e 's/ s=.*//g']], + [0], [$6], [], [kill `cat pid`]) +# Here again, the data is filtered and sorted in order to have all the rows in the index and be +# able to determined that all the involved rows are present. + AT_CHECK([[cat stdout | grep -oh '[0-9]\{3\}: i=.*' | sort -k 1,1n -k 2,2 -k 3,3]], + [0], [$7], [], [kill `cat pid`]) + OVSDB_SERVER_SHUTDOWN + AT_CLEANUP]) + +OVSDB_CHECK_IDL_COMPOUND_INDEX_SINGLE_COLUMN_C([Compound_index, single column test ], + [['["idltest", + {"op": "insert", "table": "simple", "row": {"s":"List000", "i": 1, "b":true, "r":101.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List000", "i": 2, "b":false, "r":102.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List000", "i": 10, "b":true, "r":110.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List001", "i": 1, "b":false, "r":110.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List001", "i": 2, "b":true, "r":120.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List001", "i": 2, "b":true, "r":122.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List001", "i": 4, "b":true, "r":130.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List005", "i": 5, "b":true, "r":130.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List020", "i": 20, "b":true, "r":220.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List020", "i": 19, "b":true, "r":219.0}} + ]']], + [idl_compound_index_single_column], + [001: s=List000 +001: s=List000 +001: s=List000 +001: s=List001 +001: s=List001 +001: s=List001 +001: s=List001 +001: s=List005 +001: s=List020 +001: s=List020 +003: s=List001 +003: s=List001 +003: s=List001 +003: s=List001 +], +[001: s=List000 i=1 b=True r=101.000000 +001: s=List000 i=10 b=True r=110.000000 +001: s=List000 i=2 b=False r=102.000000 +001: s=List001 i=1 b=False r=110.000000 +001: s=List001 i=2 b=True r=120.000000 +001: s=List001 i=2 b=True r=122.000000 +001: s=List001 i=4 b=True r=130.000000 +001: s=List005 i=5 b=True r=130.000000 +001: s=List020 i=19 b=True r=219.000000 +001: s=List020 i=20 b=True r=220.000000 +003: s=List001 i=1 b=False r=110.000000 +003: s=List001 i=2 b=True r=120.000000 +003: s=List001 i=2 b=True r=122.000000 +003: s=List001 i=4 b=True r=130.000000 +], +[002: i=1 +002: i=1 +002: i=2 +002: i=2 +002: i=2 +002: i=4 +002: i=5 +002: i=10 +002: i=19 +002: i=20 +004: i=5 +005: i=4 +005: i=5 +006: i=5 +006: i=10 +006: i=19 +006: i=20 +006: i=54 +], +[002: i=1 s=List000 b=True r=101.000000 +002: i=1 s=List001 b=False r=110.000000 +002: i=10 s=List000 b=True r=110.000000 +002: i=19 s=List020 b=True r=219.000000 +002: i=2 s=List000 b=False r=102.000000 +002: i=2 s=List001 b=True r=120.000000 +002: i=2 s=List001 b=True r=122.000000 +002: i=20 s=List020 b=True r=220.000000 +002: i=4 s=List001 b=True r=130.000000 +002: i=5 s=List005 b=True r=130.000000 +004: i=5 s=List005 b=True r=130.000000 +005: i=4 s=List001 b=True r=130.000000 +005: i=5 s=List005 b=True r=130.000000 +006: i=10 s=List000 b=True r=110.000000 +006: i=19 s=List020 b=True r=219.000000 +006: i=20 s=List020 b=True r=220.000000 +006: i=5 s=List005 b=True r=130.000000 +006: i=54 s=Lista054 b=False r=0.000000 +]) + +# Tests to verify the functionality of two column compound index. +# It tests index for two columns using string and integer fields. +# The run of test-ovsdb generates the output of the display of data using the different indexes defined in +# the program. +# Then, some at_checks are used to verify the correctness of the corresponding index as well as the existence +# of all the rows involved in the test. +m4_define([OVSDB_CHECK_IDL_COMPOUND_INDEX_DOUBLE_COLUMN_C], + [AT_SETUP([$1 - C]) + AT_KEYWORDS([ovsdb server idl compound_index_double_column compound_index positive $5]) + AT_CHECK([ovsdb-tool create db $abs_srcdir/idltest.ovsschema], + [0], [stdout], [ignore]) + AT_CHECK([ovsdb-server '-vPATTERN:console:ovsdb-server|%c|%m' --detach --no-chdir --pidfile="`pwd`"/pid --remote=punix:socket --unixctl="`pwd`"/unixctl db], [0], [ignore], [ignore]) + m4_if([$2], [], [], + [AT_CHECK([ovsdb-client transact unix:socket $2], [0], [ignore], [ignore], [kill `cat pid`])]) +# Generate the data to be tested. + AT_CHECK([test-ovsdb '-vPATTERN:console:test-ovsdb|%c|%m' -vjsonrpc -t10 -c idl-compound-index unix:socket $3], + [0], [stdout], [ignore], [kill `cat pid`]) +# Filter the rows of data that corresponds to the string-integer index eliminating the extra columns of data. +# This is done to verifiy that the output data is in the correct and expected order. + AT_CHECK([[cat stdout | grep -oh '[0-9]\{3\}: s=.*' | sed -e 's/ b=.*//g']], + [0], [$4], [], [kill `cat pid`]) +# Here, the data is filtered and sorted in order to have all the rows in the index and be +# able to determined that all the involved rows are present. + AT_CHECK([[cat stdout | grep -oh '[0-9]\{3\}: s=.*' | sort -k 1,1n -k 2,2 -k 3,3]], + [0], [$5], [], [kill `cat pid`]) +# Filter the rows of data that corresponds to the integer index eliminating the extra columns of data. +# This is done to verifiy that the output data is in the correct and expected order. + AT_CHECK([[cat stdout | grep -oh '[0-9]\{3\}: i=.*' | sed -e 's/ b=.*//g']], + [0], [$6], [], [kill `cat pid`]) +# Here again, the data is filtered and sorted in order to have all the rows in the index and be +# able to determined that all the involved rows are present. + AT_CHECK([[cat stdout | grep -oh '[0-9]\{3\}: i=.*' | sort -k 1,1n -k 2,2 -k 3,3]], + [0], [$7], [], [kill `cat pid`]) + OVSDB_SERVER_SHUTDOWN + AT_CLEANUP]) + +OVSDB_CHECK_IDL_COMPOUND_INDEX_DOUBLE_COLUMN_C([Compound_index, double column test ], + [['["idltest", + {"op": "insert", "table": "simple", "row": {"s":"List000", "i": 1, "b":true, "r":101.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List000", "i": 2, "b":false, "r":102.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List000", "i": 10, "b":true, "r":110.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List001", "i": 1, "b":false, "r":110.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List001", "i": 2, "b":true, "r":120.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List001", "i": 2, "b":true, "r":122.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List001", "i": 4, "b":true, "r":130.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List005", "i": 5, "b":true, "r":130.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List020", "i": 20, "b":true, "r":220.0}}, + {"op": "insert", "table": "simple", "row": {"s":"List020", "i": 19, "b":true, "r":219.0}} + ]']], + [idl_compound_index_double_column], + [001: s=List000 i=1 +001: s=List000 i=2 +001: s=List000 i=10 +001: s=List001 i=1 +001: s=List001 i=2 +001: s=List001 i=2 +001: s=List001 i=4 +001: s=List005 i=5 +001: s=List020 i=19 +001: s=List020 i=20 +002: s=List000 i=10 +002: s=List000 i=2 +002: s=List000 i=1 +002: s=List001 i=4 +002: s=List001 i=2 +002: s=List001 i=2 +002: s=List001 i=1 +002: s=List005 i=5 +002: s=List020 i=20 +002: s=List020 i=19 +003: s=List000 i=10 +004: s=List001 i=1 +004: s=List001 i=2 +004: s=List001 i=2 +004: s=List001 i=4 +004: s=List005 i=5 +], + [001: s=List000 i=1 b=True r=101.000000 +001: s=List000 i=10 b=True r=110.000000 +001: s=List000 i=2 b=False r=102.000000 +001: s=List001 i=1 b=False r=110.000000 +001: s=List001 i=2 b=True r=120.000000 +001: s=List001 i=2 b=True r=122.000000 +001: s=List001 i=4 b=True r=130.000000 +001: s=List005 i=5 b=True r=130.000000 +001: s=List020 i=19 b=True r=219.000000 +001: s=List020 i=20 b=True r=220.000000 +002: s=List000 i=1 b=True r=101.000000 +002: s=List000 i=10 b=True r=110.000000 +002: s=List000 i=2 b=False r=102.000000 +002: s=List001 i=1 b=False r=110.000000 +002: s=List001 i=2 b=True r=120.000000 +002: s=List001 i=2 b=True r=122.000000 +002: s=List001 i=4 b=True r=130.000000 +002: s=List005 i=5 b=True r=130.000000 +002: s=List020 i=19 b=True r=219.000000 +002: s=List020 i=20 b=True r=220.000000 +003: s=List000 i=10 b=True r=110.000000 +004: s=List001 i=1 b=False r=110.000000 +004: s=List001 i=2 b=True r=120.000000 +004: s=List001 i=2 b=True r=122.000000 +004: s=List001 i=4 b=True r=130.000000 +004: s=List005 i=5 b=True r=130.000000 +], + [005: i=1 s=List000 +005: i=1 s=List001 +005: i=2 s=List000 +005: i=2 s=List001 +005: i=2 s=List001 +005: i=4 s=List001 +005: i=5 s=List005 +005: i=10 s=List000 +005: i=19 s=List020 +005: i=20 s=List020 +006: i=20 s=List020 +006: i=19 s=List020 +006: i=10 s=List000 +006: i=5 s=List005 +006: i=4 s=List001 +006: i=2 s=List000 +006: i=2 s=List001 +006: i=2 s=List001 +006: i=1 s=List000 +006: i=1 s=List001 +], + [005: i=1 s=List000 b=True r=101.000000 +005: i=1 s=List001 b=False r=110.000000 +005: i=10 s=List000 b=True r=110.000000 +005: i=19 s=List020 b=True r=219.000000 +005: i=2 s=List000 b=False r=102.000000 +005: i=2 s=List001 b=True r=120.000000 +005: i=2 s=List001 b=True r=122.000000 +005: i=20 s=List020 b=True r=220.000000 +005: i=4 s=List001 b=True r=130.000000 +005: i=5 s=List005 b=True r=130.000000 +006: i=1 s=List000 b=True r=101.000000 +006: i=1 s=List001 b=False r=110.000000 +006: i=10 s=List000 b=True r=110.000000 +006: i=19 s=List020 b=True r=219.000000 +006: i=2 s=List000 b=False r=102.000000 +006: i=2 s=List001 b=True r=120.000000 +006: i=2 s=List001 b=True r=122.000000 +006: i=20 s=List020 b=True r=220.000000 +006: i=4 s=List001 b=True r=130.000000 +006: i=5 s=List005 b=True r=130.000000 +]) + diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c index e6af729..45d51b0 100644 --- a/tests/test-ovsdb.c +++ b/tests/test-ovsdb.c @@ -197,7 +197,14 @@ usage(void) " connect to SERVER and dump the contents of the database\n" " as seen initially by the IDL implementation and after\n" " executing each TRANSACTION. (Each TRANSACTION must modify\n" - " the database or this command will hang.)\n", + " the database or this command will hang.)\n" + " idl-compound-index TEST_TO_EXECUTE\n" + " Execute the tests to verify compound-index feature.\n" + " The TEST_TO_EXECUTE are:\n" + " idl_compound_index_single_column:\n" + " test for indexes using one column as part of the index.\n" + " idl_compound_index_double_column:\n" + " test for indexes using two columns as part of index.\n", program_name, program_name); vlog_usage(); printf("\nOther options:\n" @@ -2178,6 +2185,209 @@ do_idl(struct ovs_cmdl_context *ctx) printf("%03d: done\n", step); } +static int +test_idl_compound_index_single_column(struct ovsdb_idl *idl, + struct ovsdb_idl_index_cursor* sCursor, + struct ovsdb_idl_index_cursor* iCursor) +{ + const struct idltest_simple* myRow; + struct ovsdb_idl_txn *txn; + int step=0; + + /* Display records by string index -> sCursor */ + ++step; + IDLTEST_SIMPLE_FOR_EACH_BYINDEX(myRow, sCursor) + { + printf("%03d: s=%s i=%"PRId64" b=%s r=%f\n", step, myRow->s, myRow->i, myRow->b?"True":"False", myRow->r); + } + /* Display records by integer index -> iCursor */ + ++step; + IDLTEST_SIMPLE_FOR_EACH_BYINDEX(myRow, iCursor) + { + printf("%03d: i=%"PRId64" s=%s b=%s r=%f\n", step, myRow->i,myRow->s, myRow->b?"True":"False", myRow->r); + } + /* Display records by string index -> sCursor with filtering where s=\"List001\ */ + ++step; + struct idltest_simple equal; + equal.s = "List001"; + IDLTEST_SIMPLE_FOR_EACH_EQUAL(myRow, sCursor, &equal) + { + printf("%03d: s=%s i=%"PRId64" b=%s r=%f\n", step, myRow->s, myRow->i, myRow->b?"True":"False", myRow->r); + } + /* Display records by integer index -> iCursor with filtering where i=5 */ + ++step; + equal.i=5; + IDLTEST_SIMPLE_FOR_EACH_EQUAL(myRow, iCursor, &equal) { + printf("%03d: i=%"PRId64" s=%s b=%s r=%f\n", step, myRow->i,myRow->s, myRow->b?"True":"False", myRow->r); + } + /* Display records by integer index -> iCursor in range i=[3,7] */ + ++step; + struct idltest_simple from, to; + from.i = 3; + to.i = 7; + IDLTEST_SIMPLE_FOR_EACH_RANGE(myRow, iCursor, &from, &to) + { + printf("%03d: i=%"PRId64" s=%s b=%s r=%f\n", step, myRow->i,myRow->s, myRow->b?"True":"False", myRow->r); + } + /* Delete record i=4 and insert i=54 by integer index -> iCursor */ + ++step; + struct idltest_simple toDelete, *toInsert; + toDelete.i = 4; + myRow = &toDelete; + myRow = idltest_simple_index_find(iCursor, myRow); + txn = ovsdb_idl_txn_create(idl); + idltest_simple_delete(myRow); + toInsert = idltest_simple_insert(txn); + idltest_simple_set_i(toInsert, 54); + idltest_simple_set_s(toInsert, "Lista054"); + ovsdb_idl_txn_commit_block(txn); + ovsdb_idl_txn_destroy(txn); + to.i = 60; + IDLTEST_SIMPLE_FOR_EACH_RANGE(myRow, iCursor, &from, &to) + { + printf("%03d: i=%"PRId64" s=%s b=%s r=%f\n", step, myRow->i, myRow->s, myRow->b?"True":"False", myRow->r); + } + return step; +} + +static int +test_idl_compound_index_double_column(struct ovsdb_idl_index_cursor* siCursor, + struct ovsdb_idl_index_cursor* sidCursor, + struct ovsdb_idl_index_cursor* isCursor, + struct ovsdb_idl_index_cursor* idsCursor) +{ + const struct idltest_simple* myRow; + int step = 0; + + /* Display records by string-integer index -> siCursor */ + step++; + IDLTEST_SIMPLE_FOR_EACH_BYINDEX(myRow, siCursor) + { + printf("%03d: s=%s i=%"PRId64" b=%s r=%f\n", step, myRow->s, myRow->i, myRow->b?"True":"False", myRow->r); + } + /* Display records by string-integer(down order) index -> sidCursor */ + step++; + IDLTEST_SIMPLE_FOR_EACH_BYINDEX(myRow, sidCursor) + { + printf("%03d: s=%s i=%"PRId64" b=%s r=%f\n", step, myRow->s, myRow->i, myRow->b?"True":"False", myRow->r); + } + /* Display records by string-integer index -> siCursor with filtering where s="List000" and i=10 */ + step++; + struct idltest_simple equal; + equal.s = "List000"; + equal.i = 10; + IDLTEST_SIMPLE_FOR_EACH_EQUAL(myRow, siCursor, &equal) + { + printf("%03d: s=%s i=%"PRId64" b=%s r=%f\n", step, myRow->s, myRow->i, myRow->b?"True":"False", myRow->r); + } + /* Display records by string-integer index -> siCursor in range i=[0,100] and s=[\"List002\",\"List003\"] */ + step++; + struct idltest_simple from, to; + from.i = 0; + from.s = "List001"; + to.i = 100; + to.s = "List005"; + IDLTEST_SIMPLE_FOR_EACH_RANGE(myRow, siCursor, &from, &to) + { + printf("%03d: s=%s i=%"PRId64" b=%s r=%f\n", step, myRow->s, myRow->i, myRow->b?"True":"False", myRow->r); + } + /* Display records using integer-string index. */ + step++; + IDLTEST_SIMPLE_FOR_EACH_BYINDEX(myRow, isCursor) { + printf("%03d: i=%"PRId64" s=%s b=%s r=%f\n", step, myRow->i, myRow->s, myRow->b?"True":"False", myRow->r); + } + /* Display records using integer(descend)-string index. */ + step++; + IDLTEST_SIMPLE_FOR_EACH_BYINDEX(myRow, idsCursor) { + printf("%03d: i=%"PRId64" s=%s b=%s r=%f\n", step, myRow->i, myRow->s, myRow->b?"True":"False", myRow->r); + } + return step; +} + +static void +do_idl_compound_index(struct ovs_cmdl_context *ctx) +{ + struct ovsdb_idl *idl; + struct ovsdb_idl_index_cursor sCursor, iCursor, siCursor, sidCursor, + isCursor, idsCursor; + enum TESTS { IDL_COMPOUND_INDEX_WITH_SINGLE_COLUMN, + IDL_COMPOUND_INDEX_WITH_DOUBLE_COLUMN + }; + int step = 0; + int i; + + idltest_init(); + + idl = ovsdb_idl_create(ctx->argv[1], &idltest_idl_class, false, true); + + /* Add tables/columns and initialize index data needed for tests */ + ovsdb_idl_add_table(idl, &idltest_table_simple); + ovsdb_idl_add_column(idl, &idltest_simple_col_s); + ovsdb_idl_add_column(idl, &idltest_simple_col_i); + ovsdb_idl_add_column(idl, &idltest_simple_col_r); + ovsdb_idl_add_column(idl, &idltest_simple_col_b); + + struct ovsdb_idl_index *index; + index = ovsdb_idl_create_index(idl, &idltest_table_simple, "string"); + ovsdb_idl_index_add_column(index, &idltest_simple_col_s, OVSDB_INDEX_ASC, NULL); + + index = ovsdb_idl_create_index(idl, &idltest_table_simple, "integer"); + ovsdb_idl_index_add_column(index, &idltest_simple_col_i, OVSDB_INDEX_ASC, NULL); + + index = ovsdb_idl_create_index(idl, &idltest_table_simple, "string-integer"); + ovsdb_idl_index_add_column(index, &idltest_simple_col_s, OVSDB_INDEX_ASC, NULL); + ovsdb_idl_index_add_column(index, &idltest_simple_col_i, OVSDB_INDEX_ASC, NULL); + + index = ovsdb_idl_create_index(idl, &idltest_table_simple, "string-integerd"); + ovsdb_idl_index_add_column(index, &idltest_simple_col_s, OVSDB_INDEX_ASC, NULL); + ovsdb_idl_index_add_column(index, &idltest_simple_col_i, OVSDB_INDEX_DESC, NULL); + + index = ovsdb_idl_create_index(idl, &idltest_table_simple, "integer-string"); + ovsdb_idl_index_add_column(index, &idltest_simple_col_i, OVSDB_INDEX_ASC, NULL); + ovsdb_idl_index_add_column(index, &idltest_simple_col_s, OVSDB_INDEX_ASC, NULL); + + index = ovsdb_idl_create_index(idl, &idltest_table_simple, "integerd-string"); + ovsdb_idl_index_add_column(index, &idltest_simple_col_i, OVSDB_INDEX_DESC, NULL); + ovsdb_idl_index_add_column(index, &idltest_simple_col_s, OVSDB_INDEX_ASC, NULL); + + /* wait for replica to be updated */ + ovsdb_idl_get_initial_snapshot(idl); + + /* Initialize cursors to be used by indexes */ + ovsdb_idl_initialize_cursor(idl, &idltest_table_simple, "string", &sCursor); + ovsdb_idl_initialize_cursor(idl, &idltest_table_simple, "integer", &iCursor); + ovsdb_idl_initialize_cursor(idl, &idltest_table_simple, "string-integer", &siCursor); + ovsdb_idl_initialize_cursor(idl, &idltest_table_simple, "string-integerd", &sidCursor); + ovsdb_idl_initialize_cursor(idl, &idltest_table_simple, "integer-string", &isCursor); + ovsdb_idl_initialize_cursor(idl, &idltest_table_simple, "integerd-string", &idsCursor); + + setvbuf(stdout, NULL, _IONBF, 0); + int test_to_run = -1; + for (i = 2; i < ctx->argc; i++) { + char *arg = ctx->argv[i]; + + if(strcmp(arg,"idl_compound_index_single_column")== 0) { + test_to_run = IDL_COMPOUND_INDEX_WITH_SINGLE_COLUMN; + } else if(strcmp(arg, "idl_compound_index_double_column")==0) { + test_to_run = IDL_COMPOUND_INDEX_WITH_DOUBLE_COLUMN; + } + + switch(test_to_run) { + case IDL_COMPOUND_INDEX_WITH_SINGLE_COLUMN: + test_idl_compound_index_single_column(idl, &sCursor, &iCursor); + break; + case IDL_COMPOUND_INDEX_WITH_DOUBLE_COLUMN: + test_idl_compound_index_double_column(&siCursor, + &sidCursor, &isCursor, &idsCursor); + break; + default: + printf("%03d: Test %s not implemented.\n", step++, arg); + } + } + ovsdb_idl_destroy(idl); + printf("%03d: done\n", step); +} + static struct ovs_cmdl_command all_commands[] = { { "log-io", NULL, 2, INT_MAX, do_log_io }, { "default-atoms", NULL, 0, 0, do_default_atoms }, @@ -2206,6 +2416,7 @@ static struct ovs_cmdl_command all_commands[] = { { "execute", NULL, 2, INT_MAX, do_execute }, { "trigger", NULL, 2, INT_MAX, do_trigger }, { "idl", NULL, 1, INT_MAX, do_idl }, + { "idl-compound-index", NULL, 2, 2, do_idl_compound_index }, { "help", NULL, 0, INT_MAX, do_help }, { NULL, NULL, 0, 0, NULL }, }; -- 1.9.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev