-To create the cursor for the example, we use the following code:
-
-::
-
- ovsdb_idl_index_cursor my_cursor;
- ovsdb_idl_initialize_cursor(idl, &ovsrec_table_test, "by_stringField",
- &my_cursor);
-
-Now the cursor can be used to perform queries. The library implements three
-different iterators: a range iterator, an equality iterator and a full index
-iterator. The range iterator receives two values and iterates over all
-rows with values that are within that range (inclusive of the two values
-defining the range). The equality iterator iterates over all rows that exactly
-match the value passed. The full index iterator iterates over all rows in the
-index, in an order determined by the comparison function and configured
-direction (ascending or descending).
+The library implements three different iterators: a range iterator, an
+equality iterator and a full index iterator. The range iterator
+receives two values and iterates over all rows with values that are
+within that range (inclusive of the two values defining the range). The
+equality iterator iterates over all rows that exactly match the value
+passed. The full index iterator iterates over all rows in the index, in
+an order determined by the comparison function and configured direction
+(ascending or descending).
Note that indexes are *sorted by the "concatenation" of the values in
all indexed columns*, so the ranged iterator returns all the values
@@ -248,41 +230,40 @@ these iterators follows:
/*
* Equality iterator; iterates over all the records equal to "value".
*/
- ovsrec_test *value, *record;
- value = ovsrec_test_index_init_row(idl, &ovsrec_table_test);
- ovsrec_test_index_set_stringField(value, "hello world");
- OVSREC_TEST_FOR_EACH_EQUAL (record, &my_cursor, value) {
+ struct ovsrec_test *target = ovsrec_test_index_init_row(index);
+ ovsrec_test_index_set_stringField(target, "hello world");
+ struct ovsrec_test *record;
+ OVSREC_TEST_FOR_EACH_EQUAL (record, target, index) {
/* Can return zero, one or more records */
assert(strcmp(record->stringField, "hello world") == 0);
printf("Found one record with %s", record->stringField);
}
- ovsrec_test_index_destroy_row(value);
+ ovsrec_test_index_destroy_row(target);
/*
* Range iterator; iterates over all records between two values
* (inclusive).
*/
- ovsrec_test *value_from, *value_to;
- value_from = ovsrec_test_index_init_row(idl, &ovsrec_table_test);
- value_to = ovsrec_test_index_init_row(idl, &ovsrec_table_test);
+ struct ovsrec_test *from = ovsrec_test_index_init_row(index);
+ struct ovsrec_test *to = ovsrec_test_index_init_row(index);
- ovsrec_test_index_set_stringField(value_from, "aaa");
- ovsrec_test_index_set_stringField(value_to, "mmm");
- OVSREC_TEST_FOR_EACH_RANGE (record, &my_cursor, value_from, value_to) {
+ ovsrec_test_index_set_stringField(from, "aaa");
+ ovsrec_test_index_set_stringField(to, "mmm");
+ OVSREC_TEST_FOR_EACH_RANGE (record, from, to, index) {
/* Can return zero, one or more records */
assert(strcmp("aaa", record->stringField) <= 0);
assert(strcmp(record->stringField, "mmm") <= 0);
printf("Found one record with %s", record->stringField);
}
- ovsrec_test_index_destroy_row(value_from);
- ovsrec_test_index_destroy_row(value_to);
+ ovsrec_test_index_destroy_row(from);
+ ovsrec_test_index_destroy_row(to);
/*
* Index iterator; iterates over all nodes in the index, in order
* determined by comparison function and configured order (ascending
* or descending).
*/
- OVSREC_TEST_FOR_EACH_BYINDEX (record, &my_cursor) {
+ OVSREC_TEST_FOR_EACH_BYINDEX (record, index) {
/* Can return zero, one or more records */
printf("Found one record with %s", record->stringField);
}
@@ -292,11 +273,4 @@ General Index Access
While the currently defined iterators are suitable for many use cases, it is
also possible to create custom iterators using the more general API on which
-the existing iterators have been built. This API includes the following
-functions, declared in "lib/ovsdb-idl.h":
-
-1. ``ovsrec_<table>_index_compare()``
-2. ``ovsrec_<table>_index_next()``
-3. ``ovsrec_<table>_index_find()``
-4. ``ovsrec_<table>_index_forward_to()``
-5. ``ovsrec_<table>_index_get_data()``
+the existing iterators have been built. See ``ovsdb-idl.h`` for the details.
diff --git a/lib/ovsdb-idl-provider.h b/lib/ovsdb-idl-provider.h
index 70bfde11e6a1..2eee4fd01271 100644
--- a/lib/ovsdb-idl-provider.h
+++ b/lib/ovsdb-idl-provider.h
@@ -118,7 +118,7 @@ struct ovsdb_idl_table {
struct hmap rows; /* Contains "struct ovsdb_idl_row"s. */
struct ovsdb_idl_db *db; /* Containing db. */
unsigned int change_seqno[OVSDB_IDL_CHANGE_MAX];
- struct shash indexes; /* Contains "struct ovsdb_idl_index"s */
+ struct ovs_list indexes; /* Contains "struct ovsdb_idl_index"s */
struct ovs_list track_list; /* Tracked rows (ovsdb_idl_row.track_node). */
struct ovsdb_idl_condition condition;
bool cond_changed;
@@ -130,33 +130,6 @@ struct ovsdb_idl_class {
size_t n_tables;
};
-/*
- * Structure containing the per-column configuration of the index.
- */
-struct ovsdb_idl_index_column {
- const struct ovsdb_idl_column *column; /* Column used for index key. */
- column_comparator *comparer; /* Column comparison function. */
- int sorting_order; /* Sorting order (ascending or descending). */
-};
-
-/*
- * Defines a IDL compound index
- */
-struct ovsdb_idl_index {
- struct skiplist *skiplist; /* Skiplist with pointers to rows. */
- struct ovsdb_idl_index_column *columns; /* Columns configuration */
- size_t n_columns; /* Number of columns in index. */
- size_t alloc_columns; /* Size allocated memory for columns,
- comparers and sorting order. */
- bool ins_del; /* True if a row in the index is being
- inserted or deleted; if true, the
- search key is augmented with the
- UUID and address in order to discriminate
- between entries with identical keys. */
- const struct ovsdb_idl_table *table; /* Table that owns this index */
- const char *index_name; /* The name of this index. */
-};
-
struct ovsdb_idl_row *ovsdb_idl_get_row_arc(
struct ovsdb_idl_row *src,
const struct ovsdb_idl_table_class *dst_table,
@@ -166,6 +139,34 @@ void ovsdb_idl_txn_verify(const struct ovsdb_idl_row *,
const struct ovsdb_idl_column *);
struct ovsdb_idl_txn *ovsdb_idl_txn_get(const struct ovsdb_idl_row *);
+
+/* Index internals. */
+
+struct ovsdb_idl_index {
+ struct ovs_list node; /* In ->table->indexes. */
+ struct ovsdb_idl_table *table; /* The indexed table. */
+ struct ovsdb_idl_index_column *columns; /* The indexed columns. */
+ size_t n_columns;
+
+ /* Skiplist with pointers to rows. */
+ struct skiplist *skiplist;
+
+ /* True if a row in the index is being inserted or deleted. If true, the
+ search key is augmented with the UUID and address to discriminate
+ between entries with identical keys. */
+ bool ins_del;
+};
+
+int ovsdb_idl_index_compare(struct ovsdb_idl_index *,
+ const struct ovsdb_idl_row *a,
+ const struct ovsdb_idl_row *b);
+
+void ovsdb_idl_index_write(struct ovsdb_idl_row *,
+ const struct ovsdb_idl_column *,
+ struct ovsdb_datum *,
+ const struct ovsdb_idl_table_class *);
+struct ovsdb_idl_row *ovsdb_idl_index_init_row(struct ovsdb_idl_index *);
+void ovsdb_idl_index_destroy_row(const struct ovsdb_idl_row *);
#ifdef __cplusplus
}
diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c
index c6ff78e25a04..cd1a12704f29 100644
--- a/lib/ovsdb-idl.c
+++ b/lib/ovsdb-idl.c
@@ -361,11 +361,7 @@ ovsdb_idl_table_from_class(const struct ovsdb_idl *,
static bool ovsdb_idl_track_is_set(struct ovsdb_idl_table *table);
static void ovsdb_idl_send_cond_change(struct ovsdb_idl *idl);
-static struct ovsdb_idl_index *ovsdb_idl_create_index_(const struct
- ovsdb_idl_table *table,
- size_t allocated_cols);
-static void
- ovsdb_idl_destroy_indexes(struct ovsdb_idl_table *table);
+static void ovsdb_idl_destroy_indexes(struct ovsdb_idl_table *);
static void ovsdb_idl_add_to_indexes(const struct ovsdb_idl_row *);
static void ovsdb_idl_remove_from_indexes(const struct ovsdb_idl_row *);
@@ -405,7 +401,7 @@ ovsdb_idl_db_init(struct ovsdb_idl_db *db, const struct ovsdb_idl_class *class,
memset(table->modes, default_mode, tc->n_columns);
table->need_table = false;
shash_init(&table->columns);
- shash_init(&table->indexes);
+ ovs_list_init(&table->indexes);
for (size_t j = 0; j < tc->n_columns; j++) {
const struct ovsdb_idl_column *column = &tc->columns[j];
@@ -2461,44 +2457,6 @@ ovsdb_idl_row_unparse(struct ovsdb_idl_row *row)
* iterate over a subset of rows in a defined order.
*/
-static struct ovsdb_idl_index *
-ovsdb_idl_db_create_index(struct ovsdb_idl_db *db,
- const struct ovsdb_idl_table_class *tc,
- const char *index_name)
-{
- struct ovsdb_idl_index *index;
- size_t i;
-
- for (i = 0; i < db->class_->n_tables; i++) {
- struct ovsdb_idl_table *table = &db->tables[i];
-
- if (table->class_ == tc) {
- index = ovsdb_idl_create_index_(table, 1);
- if (!shash_add_once(&table->indexes, index_name, index)) {
- VLOG_ERR("Duplicate index name '%s' in table %s",
- index_name, table->class_->name);
- return NULL;
- }
- index->index_name = index_name;
- return index;
- }
- }
- OVS_NOT_REACHED();
- return NULL;
-}
-
-/* Creates a new index with the provided name, attached to the given idl and
- * table. Note that all indexes must be created and indexing columns added
- * before the first call to ovsdb_idl_run() is made.
- */
-struct ovsdb_idl_index *
-ovsdb_idl_create_index(struct ovsdb_idl *idl,
- const struct ovsdb_idl_table_class *tc,
- const char *index_name)
-{
- return ovsdb_idl_db_create_index(&idl->data, tc, index_name);
-}
-
/* Generic comparator that can compare each index, using the custom
* configuration (an struct ovsdb_idl_index) passed to it.
* Not intended for direct usage.
@@ -2533,7 +2491,7 @@ ovsdb_idl_index_generic_comparer(const void *a,
}
if (val) {
- return val * index->columns[i].sorting_order;
+ return index->columns[i].order == OVSDB_INDEX_ASC ? val : -val;
}
}
@@ -2558,34 +2516,73 @@ ovsdb_idl_index_generic_comparer(const void *a,
}
static struct ovsdb_idl_index *
-ovsdb_idl_create_index_(const struct ovsdb_idl_table *table,
- size_t allocated_cols)
+ovsdb_idl_db_index_create(struct ovsdb_idl_db *db,
+ const struct ovsdb_idl_index_column *columns,
+ size_t n)
{
- struct ovsdb_idl_index *index;
+ ovs_assert(n > 0);
- index = xmalloc(sizeof (struct ovsdb_idl_index));
- index->n_columns = 0;
- index->alloc_columns = allocated_cols;
+ struct ovsdb_idl_index *index = xzalloc(sizeof *index);
+
+ index->table = ovsdb_idl_table_from_column(db, columns[0].column);
+ for (size_t i = 0; i < n; i++) {
+ const struct ovsdb_idl_index_column *c = &columns[i];
+ ovs_assert(ovsdb_idl_table_from_column(db, c->column) == index->table);
+ ovs_assert(*ovsdb_idl_db_get_mode(db, c->column) & OVSDB_IDL_MONITOR);
+ }
+
+ index->columns = xmemdup(columns, n * sizeof *columns);
+ index->n_columns = n;
index->skiplist = skiplist_create(ovsdb_idl_index_generic_comparer,
index);
- index->columns = xmalloc(allocated_cols *
- sizeof (struct ovsdb_idl_index_column));
- index->ins_del = false;
- index->table = table;
+
+ ovs_list_push_back(&index->table->indexes, &index->node);
+
return index;
}
+/* Creates a new index for the given 'idl' and with the 'n' specified
+ * 'columns'.
+ *
+ * All indexes must be created before the first call to ovsdb_idl_run(). */
+struct ovsdb_idl_index *
+ovsdb_idl_index_create(struct ovsdb_idl *idl,
+ const struct ovsdb_idl_index_column *columns,
+ size_t n)
+{
+ return ovsdb_idl_db_index_create(&idl->data, columns, n);
+}
+
+struct ovsdb_idl_index *
+ovsdb_idl_index_create1(struct ovsdb_idl *idl,
+ const struct ovsdb_idl_column *column1)
+{
+ const struct ovsdb_idl_index_column columns[] = {
+ { .column = column1 },
+ };
+ return ovsdb_idl_index_create(idl, columns, ARRAY_SIZE(columns));
+}
+
+struct ovsdb_idl_index *
+ovsdb_idl_index_create2(struct ovsdb_idl *idl,
+ const struct ovsdb_idl_column *column1,
+ const struct ovsdb_idl_column *column2)
+{
+ const struct ovsdb_idl_index_column columns[] = {
+ { .column = column1 },
+ { .column = column2 },
+ };
+ return ovsdb_idl_index_create(idl, columns, ARRAY_SIZE(columns));
+}
+
static void
ovsdb_idl_destroy_indexes(struct ovsdb_idl_table *table)
{
- struct ovsdb_idl_index *index;
- struct shash_node *node;
-
- SHASH_FOR_EACH (node, &(table->indexes)) {
- index = node->data;
+ struct ovsdb_idl_index *index, *next;
+ LIST_FOR_EACH_SAFE (index, next, node, &table->indexes) {
skiplist_destroy(index->skiplist, NULL);
free(index->columns);
+ free(index);
}
- shash_destroy_free_data(&table->indexes);
}
static void
@@ -2593,10 +2590,7 @@ ovsdb_idl_add_to_indexes(const struct ovsdb_idl_row *row)
{
struct ovsdb_idl_table *table = row->table;
struct ovsdb_idl_index *index;
- struct shash_node *node;
-
- SHASH_FOR_EACH (node, &(table->indexes)) {
- index = node->data;
+ LIST_FOR_EACH (index, node, &table->indexes) {
index->ins_del = true;
skiplist_insert(index->skiplist, row);
index->ins_del = false;
@@ -2608,110 +2602,17 @@ ovsdb_idl_remove_from_indexes(const struct
ovsdb_idl_row *row)
{
struct ovsdb_idl_table *table = row->table;
struct ovsdb_idl_index *index;
- struct shash_node *node;
-
- SHASH_FOR_EACH (node, &(table->indexes)) {
- index = node->data;
+ LIST_FOR_EACH (index, node, &table->indexes) {
index->ins_del = true;
skiplist_delete(index->skiplist, row);
index->ins_del = false;
}
}
-/* Adds a column to an existing index (note that columns can only be added to
- * an index before the first call to ovsdb_idl_run()). The 'order' parameter
- * specifies whether the sort order should be ascending (OVSDB_INDEX_ASC) or
- * descending (OVSDB_INDEX_DESC). The 'custom_comparer' parameter, if non-NULL,
- * contains a pointer to a custom comparison function. A default comparison
- * function is used if a custom comparison function is not provided (the
- * default comparison function can only be used for columns of type string,
- * uuid, integer, real, or boolean).
- */
+/* Writes a datum in an ovsdb_idl_row, and updates the corresponding field in
+ * the table record. Not intended for direct usage. */
void
-ovsdb_idl_index_add_column(struct ovsdb_idl_index *index,
- const struct ovsdb_idl_column *column,
- int order, column_comparator *custom_comparer)
-{
- /* Check that the column or table is tracked */
- if (!index->table->need_table &&
- !((OVSDB_IDL_MONITOR | OVSDB_IDL_ALERT) &
- *ovsdb_idl_db_get_mode(index->table->db, column))) {
- VLOG_ERR("Can't add unmonitored column '%s' at index '%s' in "
- "table '%s'.",
- column->name, index->index_name, index->table->class_->name);
- }
- if (!ovsdb_type_is_scalar(&column->type) && !custom_comparer) {
- VLOG_WARN("Comparing non-scalar values.");
- }
-
- /* Allocate more memory for column configuration */
- if (index->n_columns == index->alloc_columns) {
- index->alloc_columns++;
- index->columns = xrealloc(index->columns,
- index->alloc_columns *
- sizeof(struct ovsdb_idl_index_column));
- }
-
- /* Append column to index */
- int i = index->n_columns;
-
- index->columns[i].column = column;
- index->columns[i].comparer = custom_comparer ? custom_comparer : NULL;
- if (order == OVSDB_INDEX_ASC) {
- index->columns[i].sorting_order = OVSDB_INDEX_ASC;
- } else {
- index->columns[i].sorting_order = OVSDB_INDEX_DESC;
- }
- index->n_columns++;
-}
-
-static bool
-ovsdb_idl_db_initialize_cursor(struct ovsdb_idl_db *db,
- const struct ovsdb_idl_table_class *tc,
- const char *index_name,
- struct ovsdb_idl_index_cursor *cursor)
-{
- size_t i;
-
- for (i = 0; i < db->class_->n_tables; i++) {
- struct ovsdb_idl_table *table = &db->tables[i];
-
- if (table->class_ == tc) {
- struct shash_node *node = shash_find(&table->indexes, index_name);
-
- if (!node || !node->data) {
- VLOG_ERR("Cursor initialization failed, "
- "index %s at table %s does not exist.",
- index_name, tc->name);
- cursor->index = NULL;
- cursor->position = NULL;
- return false;
- }
- cursor->index = node->data;
- cursor->position = skiplist_first(cursor->index->skiplist);
- return true;
- }
- }
- VLOG_ERR("Cursor initialization failed, "
- "index %s at table %s does not exist.", index_name, tc->name);
- return false;
-}
-
-bool
-ovsdb_idl_initialize_cursor(struct ovsdb_idl *idl,
- const struct ovsdb_idl_table_class *tc,
- const char *index_name,
- struct ovsdb_idl_index_cursor *cursor)
-{
- return ovsdb_idl_db_initialize_cursor(&idl->data, tc, index_name, cursor);
-}
-
-/* ovsdb_idl_index_write_ writes a datum in an ovsdb_idl_row,
- * and updates the corresponding field in the table record.
- * Not intended for direct usage.
- */
-void
-ovsdb_idl_index_write_(struct ovsdb_idl_row *const_row,
+ovsdb_idl_index_write(struct ovsdb_idl_row *const_row,
const struct ovsdb_idl_column *column,
struct ovsdb_datum *datum,
const struct ovsdb_idl_table_class *class)
@@ -2739,7 +2640,7 @@ static const struct uuid index_row_uuid = {
/* Check if a row is an index row */
static bool
-is_index_row(struct ovsdb_idl_row *row)
+is_index_row(const struct ovsdb_idl_row *row)
{
return uuid_equals(&row->uuid, &index_row_uuid);
}
@@ -2748,15 +2649,15 @@ is_index_row(struct ovsdb_idl_row *row)
* Not intended for direct usage.
*/
struct ovsdb_idl_row *
-ovsdb_idl_index_init_row(struct ovsdb_idl * idl,
- const struct ovsdb_idl_table_class *class)
+ovsdb_idl_index_init_row(struct ovsdb_idl_index *index)
{
+ const struct ovsdb_idl_table_class *class = index->table->class_;
struct ovsdb_idl_row *row = xzalloc(class->allocation_size);
class->row_init(row);
row->uuid = index_row_uuid;
row->new_datum = xmalloc(class->n_columns * sizeof *row->new_datum);
row->written = bitmap_allocate(class->n_columns);
- row->table = ovsdb_idl_table_from_class(idl, class);
+ row->table = index->table;
/* arcs are not used for index row, but it doesn't harm to initialize */
ovs_list_init(&row->src_arcs);
ovs_list_init(&row->dst_arcs);
@@ -2768,13 +2669,14 @@ ovsdb_idl_index_init_row(struct ovsdb_idl * idl,
* generated by ovsdb-idlc.
*/
void
-ovsdb_idl_index_destroy_row__(const struct ovsdb_idl_row *row_)
+ovsdb_idl_index_destroy_row(const struct ovsdb_idl_row *row_)
{
struct ovsdb_idl_row *row = CONST_CAST(struct ovsdb_idl_row *, row_);
const struct ovsdb_idl_table_class *class = row->table->class_;
const struct ovsdb_idl_column *c;
size_t i;
+ ovs_assert(is_index_row(row_));
ovs_assert(ovs_list_is_empty(&row_->src_arcs));
ovs_assert(ovs_list_is_empty(&row_->dst_arcs));
BITMAP_FOR_EACH_1 (i, class->n_columns, row->written) {
@@ -2788,68 +2690,59 @@ ovsdb_idl_index_destroy_row__(const struct
ovsdb_idl_row *row_)
free(row);
}
-/* Moves the cursor to the first entry in the index. Returns a pointer to the
- * corresponding ovsdb_idl_row, or NULL if the index list is empy.
- */
struct ovsdb_idl_row *
-ovsdb_idl_index_first(struct ovsdb_idl_index_cursor *cursor)
+ovsdb_idl_index_find(struct ovsdb_idl_index *index,
+ const struct ovsdb_idl_row *target)
{
- cursor->position = skiplist_first(cursor->index->skiplist);
- return ovsdb_idl_index_data(cursor);
+ return skiplist_get_data(skiplist_find(index->skiplist, target));
}
-/* Moves the cursor to the next record in the index list.
- */
-struct ovsdb_idl_row *
-ovsdb_idl_index_next(struct ovsdb_idl_index_cursor *cursor)
+struct ovsdb_idl_cursor
+ovsdb_idl_cursor_first(struct ovsdb_idl_index *index)
{
- if (!cursor->position) {
- return NULL;
- }
- cursor->position = skiplist_next(cursor->position);
- return ovsdb_idl_index_data(cursor);
- }
+ return (struct ovsdb_idl_cursor) { skiplist_first(index->skiplist) };
+}
-/* Returns the ovsdb_idl_row pointer corresponding to the record at the
- * current cursor location.
- */
-struct ovsdb_idl_row *
-ovsdb_idl_index_data(struct ovsdb_idl_index_cursor *cursor)
+struct ovsdb_idl_cursor
+ovsdb_idl_cursor_first_eq(struct ovsdb_idl_index *index,
+ const struct ovsdb_idl_row *target)
{
- return skiplist_get_data(cursor->position);
+ return (struct ovsdb_idl_cursor) { skiplist_find(index->skiplist,
+ target) };
}
-/* Moves the cursor to the first entry in the index matching the specified
- * value. If 'value' is NULL, the cursor is moved to the last entry in the
- * list. Returns a pointer to the corresponding ovsdb_idl_row or NULL.
- */
-struct ovsdb_idl_row *
-ovsdb_idl_index_find(struct ovsdb_idl_index_cursor *cursor,
- struct ovsdb_idl_row *value)
+struct ovsdb_idl_cursor
+ovsdb_idl_cursor_first_ge(struct ovsdb_idl_index *index,
+ const struct ovsdb_idl_row *target)
{
- if (value) {
- cursor->position = skiplist_find(cursor->index->skiplist, value);
- } else {
- cursor->position = skiplist_first(cursor->index->skiplist);
- }
- return ovsdb_idl_index_data(cursor);
+ struct skiplist_node *node = (target
+ ? skiplist_forward_to(index->skiplist,
+ target)
+ : skiplist_first(index->skiplist));
+ return (struct ovsdb_idl_cursor) { node };
+}
+
+void
+ovsdb_idl_cursor_next(struct ovsdb_idl_cursor *cursor)
+{
+ cursor->position = skiplist_next(cursor->position);
+}
+
+void
+ovsdb_idl_cursor_next_eq(struct ovsdb_idl_cursor *cursor,
+ struct ovsdb_idl_index *index)
+{
+ struct ovsdb_idl_row *data = skiplist_get_data(cursor->position);
+ struct skiplist_node *next_position = skiplist_next(cursor->position);
+ struct ovsdb_idl_row *next_data = skiplist_get_data(next_position);
+ cursor->position = (!ovsdb_idl_index_compare(index, data, next_data)
+ ? next_position : NULL);
}
-/* Moves the cursor to the first entry in the index with a value greater than
- * or equal to the given value. If 'value' is NULL, the cursor is moved to the
- * first entry in the index. Returns a pointer to the corresponding
- * ovsdb_idl_row or NULL if such a row does not exist.
- */
struct ovsdb_idl_row *
-ovsdb_idl_index_forward_to(struct ovsdb_idl_index_cursor *cursor,
- struct ovsdb_idl_row *value)
+ovsdb_idl_cursor_data(struct ovsdb_idl_cursor *cursor)
{
- if (value) {
- cursor->position = skiplist_forward_to(cursor->index->skiplist, value);
- } else {
- cursor->position = skiplist_first(cursor->index->skiplist);
- }
- return ovsdb_idl_index_data(cursor);
+ return skiplist_get_data(cursor->position);
}
/* Returns the result of comparing two rows using the comparison function
@@ -2862,11 +2755,12 @@ ovsdb_idl_index_forward_to(struct
ovsdb_idl_index_cursor *cursor,
* greater than any other value, and NULL == NULL.
*/
int
-ovsdb_idl_index_compare(struct ovsdb_idl_index_cursor *cursor,
- struct ovsdb_idl_row *a, struct ovsdb_idl_row *b)
+ovsdb_idl_index_compare(struct ovsdb_idl_index *index,
+ const struct ovsdb_idl_row *a,
+ const struct ovsdb_idl_row *b)
{
if (a && b) {
- return ovsdb_idl_index_generic_comparer(a, b, cursor->index);
+ return ovsdb_idl_index_generic_comparer(a, b, index);
} else if (!a && !b) {
return 0;
} else if (a) {
diff --git a/lib/ovsdb-idl.h b/lib/ovsdb-idl.h
index 2f5655227ac1..2c711f4f6d94 100644
--- a/lib/ovsdb-idl.h
+++ b/lib/ovsdb-idl.h
@@ -366,55 +366,57 @@ unsigned int ovsdb_idl_set_condition(struct ovsdb_idl *,
const struct ovsdb_idl_condition *);
unsigned int ovsdb_idl_get_condition_seqno(const struct ovsdb_idl *);
+
+/* Indexes over one or more columns in the IDL, to retrieve rows matching
+ * particular search criteria and to iterate over a subset of rows in a defined
+ * order. */
-/* The OVSDB-IDL Compound Indexes feature allows for the creation of custom
- * table indexes over one or more columns in the IDL. These indexes provide
- * the ability to retrieve rows matching a particular search criteria and to
- * iterate over a subset of rows in a defined order.
- */
+enum ovsdb_index_order {
+ OVSDB_INDEX_ASC, /* 0, 1, 2, ... */
+ OVSDB_INDEX_DESC /* 2, 1, 0, ... */
+};
-#define OVSDB_INDEX_DESC -1
-#define OVSDB_INDEX_ASC 1
+typedef int column_comparator_func(const void *a, const void *b);
-/*
- * Skiplist comparison function. Allows to store sorted data.
- */
-typedef int (column_comparator)(const void *a, const void *b);
+struct ovsdb_idl_index_column {
+ const struct ovsdb_idl_column *column;
+ column_comparator_func *comparer;
+ enum ovsdb_index_order order;
+};
-struct ovsdb_idl_index_cursor {
- struct ovsdb_idl_index *index; /* Index used by this cursor */
+/* Creating an index. */
+struct ovsdb_idl_index *ovsdb_idl_index_create(
+ struct ovsdb_idl *, const struct ovsdb_idl_index_column *, size_t n);
+struct ovsdb_idl_index *ovsdb_idl_index_create1(
+ struct ovsdb_idl *, const struct ovsdb_idl_column *);
+struct ovsdb_idl_index *ovsdb_idl_index_create2(
+ struct ovsdb_idl *, const struct ovsdb_idl_column *,
+ const struct ovsdb_idl_column *);
+
+/* Searching an index. */
+struct ovsdb_idl_row *ovsdb_idl_index_find(struct ovsdb_idl_index *,
+ const struct ovsdb_idl_row *);
+
+/* Iteration over an index.
+ *
+ * Usually these would be invoked through table-specific wrappers generated
+ * by the IDL. */
+
+struct ovsdb_idl_cursor {
struct skiplist_node *position; /* Current position in the index */
};
-struct ovsdb_idl_index *ovsdb_idl_create_index(struct ovsdb_idl *idl,
- const struct ovsdb_idl_table_class *tc,
- const char *index_name);
-void ovsdb_idl_index_add_column(struct ovsdb_idl_index *,
- const struct ovsdb_idl_column *,
- int order,
- column_comparator *custom_comparer);
-bool ovsdb_idl_initialize_cursor(struct ovsdb_idl *,
- const struct ovsdb_idl_table_class *tc,
- const char *index_name,
- struct ovsdb_idl_index_cursor *cursor);
-void ovsdb_idl_index_write_(struct ovsdb_idl_row *,
- const struct ovsdb_idl_column *,
- struct ovsdb_datum *,
- const struct ovsdb_idl_table_class *);
-struct ovsdb_idl_row *ovsdb_idl_index_init_row(struct ovsdb_idl *,
- const struct ovsdb_idl_table_class *);
-void ovsdb_idl_index_destroy_row__(const struct ovsdb_idl_row *);
-struct ovsdb_idl_row *ovsdb_idl_index_first(struct ovsdb_idl_index_cursor *);
-struct ovsdb_idl_row *ovsdb_idl_index_next(struct ovsdb_idl_index_cursor *);
-struct ovsdb_idl_row *ovsdb_idl_index_data(struct ovsdb_idl_index_cursor *);
-struct ovsdb_idl_row *ovsdb_idl_index_find(struct ovsdb_idl_index_cursor *,
- struct ovsdb_idl_row *);
-struct ovsdb_idl_row *ovsdb_idl_index_forward_to(
- struct ovsdb_idl_index_cursor *,
- struct ovsdb_idl_row *);
-int ovsdb_idl_index_compare(struct ovsdb_idl_index_cursor *,
- struct ovsdb_idl_row *a,
- struct ovsdb_idl_row *b);
+struct ovsdb_idl_cursor ovsdb_idl_cursor_first(struct ovsdb_idl_index *);
+struct ovsdb_idl_cursor ovsdb_idl_cursor_first_eq(
+ struct ovsdb_idl_index *, const struct ovsdb_idl_row *);
+struct ovsdb_idl_cursor ovsdb_idl_cursor_first_ge(
+ struct ovsdb_idl_index *, const struct ovsdb_idl_row *);
+
+void ovsdb_idl_cursor_next(struct ovsdb_idl_cursor *);
+void ovsdb_idl_cursor_next_eq(struct ovsdb_idl_cursor *,
+ struct ovsdb_idl_index *);
+
+struct ovsdb_idl_row *ovsdb_idl_cursor_data(struct ovsdb_idl_cursor *);
#ifdef __cplusplus
}
diff --git a/ovn/controller/bfd.c b/ovn/controller/bfd.c
index c6c6cbaaacb9..1b78b6114658 100644
--- a/ovn/controller/bfd.c
+++ b/ovn/controller/bfd.c
@@ -106,11 +106,11 @@ struct local_datapath_node {
};
static void
-bfd_travel_gw_related_chassis(const struct local_datapath *dp,
- const struct hmap *local_datapaths,
- struct ovsdb_idl_index_cursor *cursor,
- struct sbrec_port_binding *lpval,
- struct sset *bfd_chassis)
+bfd_travel_gw_related_chassis(
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ const struct local_datapath *dp,
+ const struct hmap *local_datapaths,
+ struct sset *bfd_chassis)
{
struct ovs_list dp_list;
const struct sbrec_port_binding *pb;
@@ -131,12 +131,12 @@ bfd_travel_gw_related_chassis(const struct local_datapath
*dp,
dp_binding->dp = dp;
ovs_list_push_back(&dp_list, &dp_binding->node);
- /*
- * Go through whole graph to figure out all chassis which may deliver
+ struct sbrec_port_binding *target = sbrec_port_binding_index_init_row(
+ sbrec_port_binding_by_datapath);
+
+ /* Go through whole graph to figure out all chassis which may deliver
* packets to gateway. */
- do {
- dp_binding = CONTAINER_OF(ovs_list_pop_front(&dp_list),
- struct local_datapath_node, node);
+ LIST_FOR_EACH_POP (dp_binding, node, &dp_list) {
dp = dp_binding->dp;
free(dp_binding);
for (size_t i = 0; i < dp->n_peer_dps; i++) {
@@ -167,8 +167,9 @@ bfd_travel_gw_related_chassis(const struct local_datapath
*dp,
hmap_node);
ovs_list_push_back(&dp_list, &dp_binding->node);
- sbrec_port_binding_index_set_datapath(lpval, pdp);
- SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, cursor, lpval) {
+ sbrec_port_binding_index_set_datapath(target, pdp);
+ SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, target,
+ sbrec_port_binding_by_datapath)
{
if (pb->chassis) {
const char *chassis_name = pb->chassis->name;
if (chassis_name) {
@@ -177,17 +178,52 @@ bfd_travel_gw_related_chassis(const struct local_datapath
*dp,
}
}
}
- } while (!ovs_list_is_empty(&dp_list));
+ }
+ sbrec_port_binding_index_destroy_row(target);
sset_destroy(&visited_dp);
}
+static struct ovs_list *
+bfd_find_ha_gateway_chassis(
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ const struct chassis_index *chassis_index,
+ const struct sbrec_datapath_binding *datapath)
+{
+ struct sbrec_port_binding *target = sbrec_port_binding_index_init_row(
+ sbrec_port_binding_by_datapath);
+ sbrec_port_binding_index_set_datapath(target, datapath);
+
+ struct ovs_list *ha_gateway_chassis = NULL;
+ const struct sbrec_port_binding *pb;
+ SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, target,
+ sbrec_port_binding_by_datapath) {
+ if (strcmp(pb->type, "chassisredirect")) {
+ continue;
+ }
+
+ struct ovs_list *gateway_chassis = gateway_chassis_get_ordered(
+ pb, chassis_index);
+ if (!gateway_chassis || ovs_list_is_short(gateway_chassis)) {
+ /* We don't need BFD for non-HA chassisredirect. */
+ gateway_chassis_destroy(gateway_chassis);
+ continue;
+ }
+
+ ha_gateway_chassis = gateway_chassis;
+ break;
+ }
+ sbrec_port_binding_index_destroy_row(target);
+ return ha_gateway_chassis;
+}
+
static void
-bfd_calculate_chassis(struct controller_ctx *ctx,
- const struct sbrec_chassis *our_chassis,
- const struct hmap *local_datapaths,
- const struct chassis_index *chassis_index,
- struct sset *bfd_chassis)
+bfd_calculate_chassis(
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ const struct sbrec_chassis *our_chassis,
+ const struct hmap *local_datapaths,
+ const struct chassis_index *chassis_index,
+ struct sset *bfd_chassis)
{
/* Identify all chassis nodes to which we need to enable bfd.
* 1) Any chassis hosting the chassisredirect ports for known
@@ -196,57 +232,36 @@ bfd_calculate_chassis(struct controller_ctx *ctx,
* to a router datapath when our chassis is hosting a router
* with a chassis redirect port. */
- const struct sbrec_port_binding *pb;
- struct ovsdb_idl_index_cursor cursor;
- struct sbrec_port_binding *lpval;
const struct local_datapath *dp;
-
- ovsdb_idl_initialize_cursor(ctx->ovnsb_idl,
- &sbrec_table_port_binding,
- "lport-by-datapath", &cursor);
- lpval = sbrec_port_binding_index_init_row(ctx->ovnsb_idl,
- &sbrec_table_port_binding);
-
HMAP_FOR_EACH (dp, hmap_node, local_datapaths) {
const char *is_router = smap_get(&dp->datapath->external_ids,
"logical-router");
bool our_chassis_is_gw_for_dp = false;
if (is_router) {
- sbrec_port_binding_index_set_datapath(lpval, dp->datapath);
- SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, &cursor, lpval) {
- if (!strcmp(pb->type, "chassisredirect")) {
- struct ovs_list *gateway_chassis = NULL;
- gateway_chassis =
- gateway_chassis_get_ordered(pb, chassis_index);
- /* we don't need BFD for non-HA chassisredirect */
- if (!gateway_chassis ||
- ovs_list_is_short(gateway_chassis)) {
- gateway_chassis_destroy(gateway_chassis);
- continue;
- }
- our_chassis_is_gw_for_dp = gateway_chassis_contains(
- gateway_chassis, our_chassis);
- struct gateway_chassis *gwc;
- LIST_FOR_EACH (gwc, node, gateway_chassis) {
- if (gwc->db->chassis) {
- sset_add(bfd_chassis, gwc->db->chassis->name);
- }
+ struct ovs_list *ha_gateway_chassis
+ = bfd_find_ha_gateway_chassis(sbrec_port_binding_by_datapath,
+ chassis_index, dp->datapath);
+ if (ha_gateway_chassis) {
+ our_chassis_is_gw_for_dp = gateway_chassis_contains(
+ ha_gateway_chassis, our_chassis);
+ struct gateway_chassis *gwc;
+ LIST_FOR_EACH (gwc, node, ha_gateway_chassis) {
+ if (gwc->db->chassis) {
+ sset_add(bfd_chassis, gwc->db->chassis->name);
}
- gateway_chassis_destroy(gateway_chassis);
- break;
}
+ gateway_chassis_destroy(ha_gateway_chassis);
}
}
if (our_chassis_is_gw_for_dp) {
- bfd_travel_gw_related_chassis(dp, local_datapaths, &cursor,
- lpval, bfd_chassis);
+ bfd_travel_gw_related_chassis(sbrec_port_binding_by_datapath,
+ dp, local_datapaths, bfd_chassis);
}
}
- sbrec_port_binding_index_destroy_row(lpval);
}
void
-bfd_run(struct controller_ctx *ctx,
+bfd_run(struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
const struct ovsrec_interface_table *interface_table,
const struct ovsrec_bridge *br_int,
const struct sbrec_chassis *chassis_rec,
@@ -258,7 +273,8 @@ bfd_run(struct controller_ctx *ctx,
return;
}
struct sset bfd_chassis = SSET_INITIALIZER(&bfd_chassis);
- bfd_calculate_chassis(ctx, chassis_rec, local_datapaths, chassis_index,
+ bfd_calculate_chassis(sbrec_port_binding_by_datapath,
+ chassis_rec, local_datapaths, chassis_index,
&bfd_chassis);
/* Identify tunnels ports(connected to remote chassis id) to enable bfd */
struct sset tunnels = SSET_INITIALIZER(&tunnels);
diff --git a/ovn/controller/bfd.h b/ovn/controller/bfd.h
index 240cf2d6bde5..a453976d50d4 100644
--- a/ovn/controller/bfd.h
+++ b/ovn/controller/bfd.h
@@ -20,13 +20,14 @@ struct chassis_index;
struct controller_ctx;
struct hmap;
struct ovsdb_idl;
+struct ovsdb_idl_index;
struct ovsrec_bridge;
struct ovsrec_interface_table;
struct sbrec_chassis;
struct sset;
void bfd_register_ovs_idl(struct ovsdb_idl *);
-void bfd_run(struct controller_ctx *ctx,
+void bfd_run(struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
const struct ovsrec_interface_table *interface_table,
const struct ovsrec_bridge *br_int,
const struct sbrec_chassis *chassis_rec,
diff --git a/ovn/controller/binding.c b/ovn/controller/binding.c
index a9a50dc68132..b5e8c8ed4db4 100644
--- a/ovn/controller/binding.c
+++ b/ovn/controller/binding.c
@@ -110,16 +110,14 @@ get_local_iface_ids(const struct ovsrec_bridge *br_int,
}
static void
-add_local_datapath__(struct controller_ctx *ctx,
+add_local_datapath__(struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_datapath_binding *datapath,
bool has_local_l3gateway, int depth,
struct hmap *local_datapaths)
{
uint32_t dp_key = datapath->tunnel_key;
- const struct sbrec_port_binding *pb;
- struct ovsdb_idl_index_cursor cursor;
- struct sbrec_port_binding *lpval;
-
struct local_datapath *ld = get_local_datapath(local_datapaths, dp_key);
if (ld) {
if (has_local_l3gateway) {
@@ -140,44 +138,52 @@ add_local_datapath__(struct controller_ctx *ctx,
return;
}
- /* Recursively add logical datapaths to which this one patches. */
- lpval = sbrec_port_binding_index_init_row(ctx->ovnsb_idl,
- &sbrec_table_port_binding);
- sbrec_port_binding_index_set_datapath(lpval, datapath);
- ovsdb_idl_initialize_cursor(ctx->ovnsb_idl, &sbrec_table_port_binding,
- "lport-by-datapath", &cursor);
+ struct sbrec_port_binding *target =
+ sbrec_port_binding_index_init_row(sbrec_port_binding_by_datapath);
+ sbrec_port_binding_index_set_datapath(target, datapath);
- SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, &cursor, lpval) {
+ const struct sbrec_port_binding *pb;
+ SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, target,
+ sbrec_port_binding_by_datapath) {
if (!strcmp(pb->type, "patch")) {
const char *peer_name = smap_get(&pb->options, "peer");
if (peer_name) {
const struct sbrec_port_binding *peer;
- peer = lport_lookup_by_name( ctx->ovnsb_idl, peer_name);
+ peer = lport_lookup_by_name(sbrec_port_binding_by_name,
+ peer_name);
if (peer && peer->datapath) {
- add_local_datapath__(ctx, peer->datapath,
- false, depth + 1, local_datapaths);
+ add_local_datapath__(sbrec_datapath_binding_by_key,
+ sbrec_port_binding_by_datapath,
+ sbrec_port_binding_by_name,
+ peer->datapath, false,
+ depth + 1, local_datapaths);
ld->n_peer_dps++;
ld->peer_dps = xrealloc(
ld->peer_dps,
ld->n_peer_dps * sizeof *ld->peer_dps);
ld->peer_dps[ld->n_peer_dps - 1] = datapath_lookup_by_key(
- ctx->ovnsb_idl, peer->datapath->tunnel_key);
+ sbrec_datapath_binding_by_key,
+ peer->datapath->tunnel_key);
}
}
}
}
- sbrec_port_binding_index_destroy_row(lpval);
+ sbrec_port_binding_index_destroy_row(target);
}
static void
-add_local_datapath(struct controller_ctx *ctx,
+add_local_datapath(struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_datapath_binding *datapath,
bool has_local_l3gateway, struct hmap *local_datapaths)
{
- add_local_datapath__(ctx, datapath, has_local_l3gateway, 0,
- local_datapaths);
+ add_local_datapath__(sbrec_datapath_binding_by_key,
+ sbrec_port_binding_by_datapath,
+ sbrec_port_binding_by_name,
+ datapath, has_local_l3gateway, 0, local_datapaths);
}
static void
@@ -387,6 +393,9 @@ update_local_lport_ids(struct sset *local_lport_ids,
static void
consider_local_datapath(struct controller_ctx *ctx,
+ struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct chassis_index *chassis_index,
const struct sset *active_tunnels,
const struct sbrec_chassis *chassis_rec,
@@ -409,8 +418,10 @@ consider_local_datapath(struct controller_ctx *ctx,
/* Add child logical port to the set of all local ports. */
sset_add(local_lports, binding_rec->logical_port);
}
- add_local_datapath(ctx, binding_rec->datapath,
- false, local_datapaths);
+ add_local_datapath(sbrec_datapath_binding_by_key,
+ sbrec_port_binding_by_datapath,
+ sbrec_port_binding_by_name,
+ binding_rec->datapath, false, local_datapaths);
if (iface_rec && qos_map && ctx->ovs_idl_txn) {
get_qos_params(binding_rec, qos_map);
}
@@ -424,8 +435,10 @@ consider_local_datapath(struct controller_ctx *ctx,
our_chassis = chassis_id && !strcmp(chassis_id, chassis_rec->name);
if (our_chassis) {
sset_add(local_lports, binding_rec->logical_port);
- add_local_datapath(ctx, binding_rec->datapath,
- false, local_datapaths);
+ add_local_datapath(sbrec_datapath_binding_by_key,
+ sbrec_port_binding_by_datapath,
+ sbrec_port_binding_by_name,
+ binding_rec->datapath, false, local_datapaths);
}
} else if (!strcmp(binding_rec->type, "chassisredirect")) {
gateway_chassis = gateway_chassis_get_ordered(binding_rec,
@@ -436,8 +449,10 @@ consider_local_datapath(struct controller_ctx *ctx,
our_chassis = gateway_chassis_is_active(
gateway_chassis, chassis_rec, active_tunnels);
- add_local_datapath(ctx, binding_rec->datapath,
- false, local_datapaths);
+ add_local_datapath(sbrec_datapath_binding_by_key,
+ sbrec_port_binding_by_datapath,
+ sbrec_port_binding_by_name,
+ binding_rec->datapath, false, local_datapaths);
}
gateway_chassis_destroy(gateway_chassis);
} else if (!strcmp(binding_rec->type, "l3gateway")) {
@@ -445,8 +460,10 @@ consider_local_datapath(struct controller_ctx *ctx,
"l3gateway-chassis");
our_chassis = chassis_id && !strcmp(chassis_id, chassis_rec->name);
if (our_chassis) {
- add_local_datapath(ctx, binding_rec->datapath,
- true, local_datapaths);
+ add_local_datapath(sbrec_datapath_binding_by_key,
+ sbrec_port_binding_by_datapath,
+ sbrec_port_binding_by_name,
+ binding_rec->datapath, true, local_datapaths);
}
} else if (!strcmp(binding_rec->type, "localnet")) {
/* Add all localnet ports to local_lports so that we allocate ct zones
@@ -529,6 +546,9 @@ consider_localnet_port(const struct sbrec_port_binding
*binding_rec,
void
binding_run(struct controller_ctx *ctx,
+ struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct ovsrec_port_table *port_table,
const struct ovsrec_qos_table *qos_table,
const struct sbrec_port_binding_table *port_binding_table,
@@ -558,7 +578,9 @@ binding_run(struct controller_ctx *ctx,
* chassis and update the binding accordingly. This includes both
* directly connected logical ports and children of those ports. */
SBREC_PORT_BINDING_TABLE_FOR_EACH (binding_rec, port_binding_table) {
- consider_local_datapath(ctx, chassis_index,
+ consider_local_datapath(ctx, sbrec_datapath_binding_by_key,
+ sbrec_port_binding_by_datapath,
+ sbrec_port_binding_by_name, chassis_index,
active_tunnels, chassis_rec, binding_rec,
sset_is_empty(&egress_ifaces) ? NULL :
&qos_map, local_datapaths, &lport_to_iface,
diff --git a/ovn/controller/binding.h b/ovn/controller/binding.h
index 0f8a3a19bcf9..1759b70de2e3 100644
--- a/ovn/controller/binding.h
+++ b/ovn/controller/binding.h
@@ -23,6 +23,7 @@ struct controller_ctx;
struct chassis_index;
struct hmap;
struct ovsdb_idl;
+struct ovsdb_idl_index;
struct ovsrec_bridge;
struct ovsrec_port_table;
struct ovsrec_qos_table;
@@ -32,6 +33,9 @@ struct sset;
void binding_register_ovs_idl(struct ovsdb_idl *);
void binding_run(struct controller_ctx *,
+ struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct ovsrec_port_table *,
const struct ovsrec_qos_table *,
const struct sbrec_port_binding_table *,
diff --git a/ovn/controller/lflow.c b/ovn/controller/lflow.c
index 86aac2a4731a..434adf3b8428 100644
--- a/ovn/controller/lflow.c
+++ b/ovn/controller/lflow.c
@@ -50,33 +50,36 @@ lflow_init(void)
}
struct lookup_port_aux {
- struct ovsdb_idl *ovnsb_idl;
+ struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath;
+ struct ovsdb_idl_index *sbrec_port_binding_by_name;
const struct sbrec_datapath_binding *dp;
};
struct condition_aux {
- struct ovsdb_idl *ovnsb_idl;
+ struct ovsdb_idl_index *sbrec_port_binding_by_name;
const struct sbrec_chassis *chassis;
const struct sset *active_tunnels;
const struct chassis_index *chassis_index;
};
-static void consider_logical_flow(struct controller_ctx *ctx,
- const struct chassis_index *chassis_index,
- const struct sbrec_logical_flow *lflow,
- const struct hmap *local_datapaths,
- const struct sbrec_chassis *chassis,
- struct hmap *dhcp_opts,
- struct hmap *dhcpv6_opts,
- struct hmap *nd_ra_opts,
- uint32_t *conj_id_ofs,
- const struct shash *addr_sets,
- const struct shash *port_groups,
- const struct sset *active_tunnels,
- const struct sset *local_lport_ids,
- struct hmap *flow_table,
- struct ovn_extend_table *group_table,
- struct ovn_extend_table *meter_table);
+static void consider_logical_flow(
+ struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
+ const struct chassis_index *,
+ const struct sbrec_logical_flow *,
+ const struct hmap *local_datapaths,
+ const struct sbrec_chassis *,
+ struct hmap *dhcp_opts,
+ struct hmap *dhcpv6_opts,
+ struct hmap *nd_ra_opts,
+ uint32_t *conj_id_ofs,
+ const struct shash *addr_sets,
+ const struct shash *port_groups,
+ const struct sset *active_tunnels,
+ const struct sset *local_lport_ids,
+ struct hmap *flow_table,
+ struct ovn_extend_table *group_table,
+ struct ovn_extend_table *meter_table);
static bool
lookup_port_cb(const void *aux_, const char *port_name, unsigned int *portp)
@@ -84,14 +87,14 @@ lookup_port_cb(const void *aux_, const char *port_name,
unsigned int *portp)
const struct lookup_port_aux *aux = aux_;
const struct sbrec_port_binding *pb
- = lport_lookup_by_name(aux->ovnsb_idl, port_name);
+ = lport_lookup_by_name(aux->sbrec_port_binding_by_name, port_name);
if (pb && pb->datapath == aux->dp) {
*portp = pb->tunnel_key;
return true;
}
- const struct sbrec_multicast_group *mg
- = mcgroup_lookup_by_dp_name(aux->ovnsb_idl, aux->dp, port_name);
+ const struct sbrec_multicast_group *mg = mcgroup_lookup_by_dp_name(
+ aux->sbrec_multicast_group_by_name_datapath, aux->dp, port_name);
if (mg) {
*portp = mg->tunnel_key;
return true;
@@ -106,7 +109,7 @@ is_chassis_resident_cb(const void *c_aux_, const char
*port_name)
const struct condition_aux *c_aux = c_aux_;
const struct sbrec_port_binding *pb
- = lport_lookup_by_name(c_aux->ovnsb_idl, port_name);
+ = lport_lookup_by_name(c_aux->sbrec_port_binding_by_name, port_name);
if (!pb) {
return false;
}
@@ -138,7 +141,8 @@ is_switch(const struct sbrec_datapath_binding *ldp)
/* Adds the logical flows from the Logical_Flow table to flow tables. */
static void
add_logical_flows(
- struct controller_ctx *ctx,
+ struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_dhcp_options_table *dhcp_options_table,
const struct sbrec_dhcpv6_options_table *dhcpv6_options_table,
const struct sbrec_logical_flow_table *logical_flow_table,
@@ -176,7 +180,9 @@ add_logical_flows(
nd_ra_opts_init(&nd_ra_opts);
SBREC_LOGICAL_FLOW_TABLE_FOR_EACH (lflow, logical_flow_table) {
- consider_logical_flow(ctx, chassis_index, lflow, local_datapaths,
+ consider_logical_flow(sbrec_multicast_group_by_name_datapath,
+ sbrec_port_binding_by_name,
+ chassis_index, lflow, local_datapaths,
chassis, &dhcp_opts, &dhcpv6_opts, &nd_ra_opts,
&conj_id_ofs, addr_sets, port_groups,
active_tunnels, local_lport_ids,
@@ -189,22 +195,24 @@ add_logical_flows(
}
static void
-consider_logical_flow(struct controller_ctx *ctx,
- const struct chassis_index *chassis_index,
- const struct sbrec_logical_flow *lflow,
- const struct hmap *local_datapaths,
- const struct sbrec_chassis *chassis,
- struct hmap *dhcp_opts,
- struct hmap *dhcpv6_opts,
- struct hmap *nd_ra_opts,
- uint32_t *conj_id_ofs,
- const struct shash *addr_sets,
- const struct shash *port_groups,
- const struct sset *active_tunnels,
- const struct sset *local_lport_ids,
- struct hmap *flow_table,
- struct ovn_extend_table *group_table,
- struct ovn_extend_table *meter_table)
+consider_logical_flow(
+ struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
+ const struct chassis_index *chassis_index,
+ const struct sbrec_logical_flow *lflow,
+ const struct hmap *local_datapaths,
+ const struct sbrec_chassis *chassis,
+ struct hmap *dhcp_opts,
+ struct hmap *dhcpv6_opts,
+ struct hmap *nd_ra_opts,
+ uint32_t *conj_id_ofs,
+ const struct shash *addr_sets,
+ const struct shash *port_groups,
+ const struct sset *active_tunnels,
+ const struct sset *local_lport_ids,
+ struct hmap *flow_table,
+ struct ovn_extend_table *group_table,
+ struct ovn_extend_table *meter_table)
{
/* Determine translation of logical table IDs to physical table IDs. */
bool ingress = !strcmp(lflow->pipeline, "ingress");
@@ -280,11 +288,17 @@ consider_logical_flow(struct controller_ctx *ctx,
}
struct lookup_port_aux aux = {
- .ovnsb_idl = ctx->ovnsb_idl,
+ .sbrec_multicast_group_by_name_datapath
+ = sbrec_multicast_group_by_name_datapath,
+ .sbrec_port_binding_by_name = sbrec_port_binding_by_name,
.dp = lflow->logical_datapath
};
- struct condition_aux cond_aux = { ctx->ovnsb_idl, chassis, active_tunnels,
- chassis_index};
+ struct condition_aux cond_aux = {
+ .sbrec_port_binding_by_name = sbrec_port_binding_by_name,
+ .chassis = chassis,
+ .active_tunnels = active_tunnels,
+ .chassis_index = chassis_index
+ };
expr = expr_simplify(expr, is_chassis_resident_cb, &cond_aux);
expr = expr_normalize(expr);
uint32_t n_conjs = expr_to_matches(expr, lookup_port_cb, &aux,
@@ -381,12 +395,12 @@ put_load(const uint8_t *data, size_t len,
}
static void
-consider_neighbor_flow(struct controller_ctx *ctx,
+consider_neighbor_flow(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_mac_binding *b,
struct hmap *flow_table)
{
const struct sbrec_port_binding *pb
- = lport_lookup_by_name(ctx->ovnsb_idl, b->logical_port);
+ = lport_lookup_by_name(sbrec_port_binding_by_name, b->logical_port);
if (!pb) {
return;
}
@@ -432,20 +446,21 @@ consider_neighbor_flow(struct controller_ctx *ctx,
/* Adds an OpenFlow flow to flow tables for each MAC binding in the OVN
* southbound database. */
static void
-add_neighbor_flows(struct controller_ctx *ctx,
+add_neighbor_flows(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_mac_binding_table *mac_binding_table,
struct hmap *flow_table)
{
const struct sbrec_mac_binding *b;
SBREC_MAC_BINDING_TABLE_FOR_EACH (b, mac_binding_table) {
- consider_neighbor_flow(ctx, b, flow_table);
+ consider_neighbor_flow(sbrec_port_binding_by_name, b, flow_table);
}
}
/* Translates logical flows in the Logical_Flow table in the OVN_SB database
* into OpenFlow flows. See ovn-architecture(7) for more information. */
void
-lflow_run(struct controller_ctx *ctx,
+lflow_run(struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_dhcp_options_table *dhcp_options_table,
const struct sbrec_dhcpv6_options_table *dhcpv6_options_table,
const struct sbrec_logical_flow_table *logical_flow_table,
@@ -463,11 +478,14 @@ lflow_run(struct controller_ctx *ctx,
{
COVERAGE_INC(lflow_run);
- add_logical_flows(ctx, dhcp_options_table, dhcpv6_options_table,
- logical_flow_table, chassis_index, local_datapaths,
- chassis, addr_sets, port_groups, active_tunnels,
- local_lport_ids, flow_table, group_table, meter_table);
- add_neighbor_flows(ctx, mac_binding_table, flow_table);
+ add_logical_flows(sbrec_multicast_group_by_name_datapath,
+ sbrec_port_binding_by_name, dhcp_options_table,
+ dhcpv6_options_table, logical_flow_table, chassis_index,
+ local_datapaths, chassis, addr_sets, port_groups,
+ active_tunnels, local_lport_ids, flow_table, group_table,
+ meter_table);
+ add_neighbor_flows(sbrec_port_binding_by_name, mac_binding_table,
+ flow_table);
}
void
diff --git a/ovn/controller/lflow.h b/ovn/controller/lflow.h
index 7e081d72126a..feb59ee09d08 100644
--- a/ovn/controller/lflow.h
+++ b/ovn/controller/lflow.h
@@ -36,8 +36,8 @@
#include <stdint.h>
struct chassis_index;
-struct controller_ctx;
struct ovn_extend_table;
+struct ovsdb_idl_index;
struct hmap;
struct sbrec_chassis;
struct sbrec_dhcp_options_table;
@@ -66,7 +66,8 @@ struct uuid;
#define LOG_PIPELINE_LEN 24
void lflow_init(void);
-void lflow_run(struct controller_ctx *,
+void lflow_run(struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_dhcp_options_table *,
const struct sbrec_dhcpv6_options_table *,
const struct sbrec_logical_flow_table *,
diff --git a/ovn/controller/lport.c b/ovn/controller/lport.c
index e5305d0b0922..cc5c5fbb20e6 100644
--- a/ovn/controller/lport.c
+++ b/ovn/controller/lport.c
@@ -22,146 +22,81 @@
#include "ovn/lib/ovn-sb-idl.h"
VLOG_DEFINE_THIS_MODULE(lport);
-static struct ovsdb_idl_index_cursor lport_by_name_cursor;
-static struct ovsdb_idl_index_cursor lport_by_key_cursor;
-static struct ovsdb_idl_index_cursor dpath_by_key_cursor;
-static struct ovsdb_idl_index_cursor mc_grp_by_dp_name_cursor;
-
-
-
-/* Finds and returns the port binding record with the given 'name',
- * or NULL if no such port binding exists. */
const struct sbrec_port_binding *
-lport_lookup_by_name(struct ovsdb_idl *idl, const char *name)
+lport_lookup_by_name(struct ovsdb_idl_index *sbrec_port_binding_by_name,
+ const char *name)
{
- struct sbrec_port_binding *value;
- const struct sbrec_port_binding *pb, *retval = NULL;
-
- /* Build key for an indexed lookup. */
- value = sbrec_port_binding_index_init_row(idl, &sbrec_table_port_binding);
- sbrec_port_binding_index_set_logical_port(value, name);
-
- /* Find an entry with matching logical port name. Since this column is
- * declared to be an index in the OVN_Southbound schema, the first match
- * (if any) will be the only match. */
- SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, &lport_by_name_cursor, value) {
- retval = pb;
- break;
- }
-
- sbrec_port_binding_index_destroy_row(value);
-
- return retval;
-}
+ struct sbrec_port_binding *pb = sbrec_port_binding_index_init_row(
+ sbrec_port_binding_by_name);
+ sbrec_port_binding_index_set_logical_port(pb, name);
-/* Finds and returns the datapath binding record with tunnel_key equal to the
- * given 'dp_key', or NULL if no such datapath binding exists. */
-const struct sbrec_datapath_binding *
-datapath_lookup_by_key(struct ovsdb_idl *idl, uint64_t dp_key)
-{
- struct sbrec_datapath_binding *dbval;
- const struct sbrec_datapath_binding *db, *retval = NULL;
+ const struct sbrec_port_binding *retval = sbrec_port_binding_index_find(
+ sbrec_port_binding_by_name, pb);
- /* Build key for an indexed lookup. */
- dbval = sbrec_datapath_binding_index_init_row(idl,
- &sbrec_table_datapath_binding);
- sbrec_datapath_binding_index_set_tunnel_key(dbval, dp_key);
-
- /* Find an entry with matching tunnel_key. Since this column is declared
- * to be an index in the OVN_Southbound schema, the first match (if any)
- * will be the only match. */
- SBREC_DATAPATH_BINDING_FOR_EACH_EQUAL (db, &dpath_by_key_cursor, dbval) {
- retval = db;
- break;
- }
- sbrec_datapath_binding_index_destroy_row(dbval);
+ sbrec_port_binding_index_destroy_row(pb);
return retval;
}
-/* Finds and returns the port binding record with tunnel_key equal to the
- * given 'port_key' and datapath binding matching 'dp_key', or NULL if no
- * such port binding exists. */
const struct sbrec_port_binding *
-lport_lookup_by_key(struct ovsdb_idl *idl, uint64_t dp_key, uint64_t port_key)
+lport_lookup_by_key(struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+ struct ovsdb_idl_index *sbrec_port_binding_by_key,
+ uint64_t dp_key, uint64_t port_key)
{
- struct sbrec_port_binding *pbval;
- const struct sbrec_port_binding *pb, *retval = NULL;
- const struct sbrec_datapath_binding *db;
-
/* Lookup datapath corresponding to dp_key. */
- db = datapath_lookup_by_key(idl, dp_key);
+ const struct sbrec_datapath_binding *db = datapath_lookup_by_key(
+ sbrec_datapath_binding_by_key, dp_key);
if (!db) {
return NULL;
}
/* Build key for an indexed lookup. */
- pbval = sbrec_port_binding_index_init_row(idl, &sbrec_table_port_binding);
- sbrec_port_binding_index_set_datapath(pbval, db);
- sbrec_port_binding_index_set_tunnel_key(pbval, port_key);
-
- /* Find an entry with matching tunnel_key and datapath UUID. Since this
- * column pair is declared to be an index in the OVN_Southbound schema,
- * the first match (if any) will be the only match. */
- SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, &lport_by_key_cursor, pbval) {
- retval = pb;
- break;
- }
- sbrec_port_binding_index_destroy_row(pbval);
+ struct sbrec_port_binding *pb = sbrec_port_binding_index_init_row(
+ sbrec_port_binding_by_key);
+ sbrec_port_binding_index_set_datapath(pb, db);
+ sbrec_port_binding_index_set_tunnel_key(pb, port_key);
+
+ const struct sbrec_port_binding *retval = sbrec_port_binding_index_find(
+ sbrec_port_binding_by_key, pb);
+
+ sbrec_port_binding_index_destroy_row(pb);
return retval;
}
-
-/* Finds and returns the logical multicast group with the given 'name' and
- * datapath binding, or NULL if no such logical multicast group exists. */
-const struct sbrec_multicast_group *
-mcgroup_lookup_by_dp_name(struct ovsdb_idl *idl,
- const struct sbrec_datapath_binding *dp,
- const char *name)
+
+const struct sbrec_datapath_binding *
+datapath_lookup_by_key(struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+ uint64_t dp_key)
{
- struct sbrec_multicast_group *mcval;
- const struct sbrec_multicast_group *mc, *retval = NULL;
+ struct sbrec_datapath_binding *db = sbrec_datapath_binding_index_init_row(
+ sbrec_datapath_binding_by_key);
+ sbrec_datapath_binding_index_set_tunnel_key(db, dp_key);
- /* Build key for an indexed lookup. */
- mcval = sbrec_multicast_group_index_init_row(idl,
- &sbrec_table_multicast_group);
- sbrec_multicast_group_index_set_name(mcval, name);
- sbrec_multicast_group_index_set_datapath(mcval, dp);
-
- /* Find an entry with matching logical multicast group name and datapath.
- * Since this column pair is declared to be an index in the OVN_Southbound
- * schema, the first match (if any) will be the only match. */
- SBREC_MULTICAST_GROUP_FOR_EACH_EQUAL (mc, &mc_grp_by_dp_name_cursor,
- mcval) {
- retval = mc;
- break;
- }
+ const struct sbrec_datapath_binding *retval
+ = sbrec_datapath_binding_index_find(sbrec_datapath_binding_by_key,
+ db);
- sbrec_multicast_group_index_destroy_row(mcval);
+ sbrec_datapath_binding_index_destroy_row(db);
return retval;
}
-void
-lport_init(struct ovsdb_idl *idl)
+const struct sbrec_multicast_group *
+mcgroup_lookup_by_dp_name(
+ struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
+ const struct sbrec_datapath_binding *db, const char *name)
{
- /* Create a cursor for searching multicast group table by datapath
- * and group name. */
- ovsdb_idl_initialize_cursor(idl, &sbrec_table_multicast_group,
- "multicast-group-by-dp-name",
- &mc_grp_by_dp_name_cursor);
-
- /* Create cursor to search port binding table by logical port name. */
- ovsdb_idl_initialize_cursor(idl, &sbrec_table_port_binding,
- "lport-by-name",
- &lport_by_name_cursor);
-
- /* Create cursor to search port binding table by logical port tunnel key
- * and datapath uuid. */
- ovsdb_idl_initialize_cursor(idl, &sbrec_table_port_binding, "lport-by-key",
- &lport_by_key_cursor);
-
- /* Create cursor to search datapath binding table by tunnel key. */
- ovsdb_idl_initialize_cursor(idl, &sbrec_table_datapath_binding,
- "dpath-by-key", &dpath_by_key_cursor);
+ /* Build key for an indexed lookup. */
+ struct sbrec_multicast_group *mc = sbrec_multicast_group_index_init_row(
+ sbrec_multicast_group_by_name_datapath);
+ sbrec_multicast_group_index_set_name(mc, name);
+ sbrec_multicast_group_index_set_datapath(mc, db);
+
+ const struct sbrec_multicast_group *retval
+ = sbrec_multicast_group_index_find(
+ sbrec_multicast_group_by_name_datapath, mc);
+
+ sbrec_multicast_group_index_destroy_row(mc);
+
+ return retval;
}
diff --git a/ovn/controller/lport.h b/ovn/controller/lport.h
index 38c7344dc221..7dcd5bee0aa6 100644
--- a/ovn/controller/lport.h
+++ b/ovn/controller/lport.h
@@ -17,13 +17,11 @@
#define OVN_LPORT_H 1
#include <stdint.h>
-#include "lib/uuid.h"
-#include "openvswitch/hmap.h"
-#include "openvswitch/list.h"
-struct ovsdb_idl;
+struct ovsdb_idl_index;
struct sbrec_chassis;
struct sbrec_datapath_binding;
+struct sbrec_multicast_group;
struct sbrec_port_binding;
@@ -34,22 +32,21 @@ struct sbrec_port_binding;
* look up data based on values of its fields. It's not that smart (yet), so
* instead we define our own indexes.
*/
-
-
-const struct sbrec_datapath_binding *datapath_lookup_by_key(struct ovsdb_idl *,
- uint64_t dp_key);
const struct sbrec_port_binding *lport_lookup_by_name(
- struct ovsdb_idl *, const char *name);
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
+ const char *name);
+
const struct sbrec_port_binding *lport_lookup_by_key(
- struct ovsdb_idl *, uint64_t dp_key, uint64_t port_key);
-
+ struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+ struct ovsdb_idl_index *sbrec_port_binding_by_key,
+ uint64_t dp_key, uint64_t port_key);
-const struct sbrec_multicast_group *mcgroup_lookup_by_dp_name(
- struct ovsdb_idl *idl,
- const struct sbrec_datapath_binding *,
- const char *name);
+const struct sbrec_datapath_binding *datapath_lookup_by_key(
+ struct ovsdb_idl_index *sbrec_datapath_binding_by_key, uint64_t dp_key);
-void lport_init(struct ovsdb_idl *idl);
+const struct sbrec_multicast_group *mcgroup_lookup_by_dp_name(
+ struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath,
+ const struct sbrec_datapath_binding *, const char *name);
#endif /* ovn/lport.h */
diff --git a/ovn/controller/ovn-controller.c b/ovn/controller/ovn-controller.c
index 30f6fbb892c2..4ec1de3976ee 100644
--- a/ovn/controller/ovn-controller.c
+++ b/ovn/controller/ovn-controller.c
@@ -556,46 +556,6 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl)
physical_register_ovs_idl(ovs_idl);
}
-static void
-create_ovnsb_indexes(struct ovsdb_idl *ovnsb_idl)
-{
- struct ovsdb_idl_index *index;
-
- /* Index multicast group table by name and datapath. */
- index = ovsdb_idl_create_index(ovnsb_idl, &sbrec_table_multicast_group,
- "multicast-group-by-dp-name");
- ovsdb_idl_index_add_column(index, &sbrec_multicast_group_col_name,
- OVSDB_INDEX_ASC, NULL);
- ovsdb_idl_index_add_column(index, &sbrec_multicast_group_col_datapath,
- OVSDB_INDEX_ASC, NULL);
-
- /* Index logical port table by name. */
- index = ovsdb_idl_create_index(ovnsb_idl, &sbrec_table_port_binding,
- "lport-by-name");
- ovsdb_idl_index_add_column(index, &sbrec_port_binding_col_logical_port,
- OVSDB_INDEX_ASC, NULL);
-
- /* Index logical port table by tunnel key and datapath. */
- index = ovsdb_idl_create_index(ovnsb_idl, &sbrec_table_port_binding,
- "lport-by-key");
- ovsdb_idl_index_add_column(index, &sbrec_port_binding_col_tunnel_key,
- OVSDB_INDEX_ASC, NULL);
- ovsdb_idl_index_add_column(index, &sbrec_port_binding_col_datapath,
- OVSDB_INDEX_ASC, NULL);
-
- /* Index logical port table by datapath. */
- index = ovsdb_idl_create_index(ovnsb_idl, &sbrec_table_port_binding,
- "lport-by-datapath");
- ovsdb_idl_index_add_column(index, &sbrec_port_binding_col_datapath,
- OVSDB_INDEX_ASC, NULL);
-
- /* Index datapath binding table by tunnel key. */
- index = ovsdb_idl_create_index(ovnsb_idl, &sbrec_table_datapath_binding,
- "dpath-by-key");
- ovsdb_idl_index_add_column(index, &sbrec_datapath_binding_col_tunnel_key,
- OVSDB_INDEX_ASC, NULL);
-}
-
int
main(int argc, char *argv[])
{
@@ -643,8 +603,23 @@ main(int argc, char *argv[])
ovsdb_idl_create(ovnsb_remote, &sbrec_idl_class, true, true));
ovsdb_idl_set_leader_only(ovnsb_idl_loop.idl, false);
- create_ovnsb_indexes(ovnsb_idl_loop.idl);
- lport_init(ovnsb_idl_loop.idl);
+ struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath
+ = ovsdb_idl_index_create2(ovnsb_idl_loop.idl,
+ &sbrec_multicast_group_col_name,
+ &sbrec_multicast_group_col_datapath);
+ struct ovsdb_idl_index *sbrec_port_binding_by_name
+ = ovsdb_idl_index_create1(ovnsb_idl_loop.idl,
+ &sbrec_port_binding_col_logical_port);
+ struct ovsdb_idl_index *sbrec_port_binding_by_key
+ = ovsdb_idl_index_create2(ovnsb_idl_loop.idl,
+ &sbrec_port_binding_col_tunnel_key,
+ &sbrec_port_binding_col_datapath);
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath
+ = ovsdb_idl_index_create1(ovnsb_idl_loop.idl,
+ &sbrec_port_binding_col_datapath);
+ struct ovsdb_idl_index *sbrec_datapath_binding_by_key
+ = ovsdb_idl_index_create1(ovnsb_idl_loop.idl,
+ &sbrec_datapath_binding_col_tunnel_key);
ovsdb_idl_omit_alert(ovnsb_idl_loop.idl, &sbrec_chassis_col_nb_cfg);
update_sb_monitors(ovnsb_idl_loop.idl, NULL, NULL, NULL);
@@ -727,6 +702,9 @@ main(int argc, char *argv[])
sbrec_chassis_table_get(ctx.ovnsb_idl), chassis_id);
bfd_calculate_active_tunnels(br_int, &active_tunnels);
binding_run(&ctx,
+ sbrec_datapath_binding_by_key,
+ sbrec_port_binding_by_datapath,
+ sbrec_port_binding_by_name,
ovsrec_port_table_get(ctx.ovs_idl),
ovsrec_qos_table_get(ctx.ovs_idl),
sbrec_port_binding_table_get(ctx.ovnsb_idl),
@@ -752,7 +730,12 @@ main(int argc, char *argv[])
enum mf_field_id mff_ovn_geneve = ofctrl_run(br_int,
&pending_ct_zones);
- pinctrl_run(&ctx, sbrec_dns_table_get(ctx.ovnsb_idl),
+ pinctrl_run(&ctx,
+ sbrec_datapath_binding_by_key,
+ sbrec_port_binding_by_datapath,
+ sbrec_port_binding_by_key,
+ sbrec_port_binding_by_name,
+ sbrec_dns_table_get(ctx.ovnsb_idl),
sbrec_mac_binding_table_get(ctx.ovnsb_idl),
br_int, chassis, &chassis_index,
&local_datapaths, &active_tunnels);
@@ -766,7 +749,8 @@ main(int argc, char *argv[])
commit_ct_zones(br_int, &pending_ct_zones);
struct hmap flow_table = HMAP_INITIALIZER(&flow_table);
- lflow_run(&ctx,
+ lflow_run(sbrec_multicast_group_by_name_datapath,
+ sbrec_port_binding_by_name,
sbrec_dhcp_options_table_get(ctx.ovnsb_idl),
sbrec_dhcpv6_options_table_get(ctx.ovnsb_idl),
sbrec_logical_flow_table_get(ctx.ovnsb_idl),
@@ -777,13 +761,13 @@ main(int argc, char *argv[])
&flow_table, &group_table, &meter_table);
if (chassis_id) {
- bfd_run(&ctx,
+ bfd_run(sbrec_port_binding_by_datapath,
ovsrec_interface_table_get(ctx.ovs_idl),
br_int, chassis, &local_datapaths,
&chassis_index);
}
physical_run(
- &ctx,
+ sbrec_port_binding_by_name,
sbrec_multicast_group_table_get(ctx.ovnsb_idl),
sbrec_port_binding_table_get(ctx.ovnsb_idl),
mff_ovn_geneve,
diff --git a/ovn/controller/physical.c b/ovn/controller/physical.c
index 2efe73219d89..eb2e35dafa6e 100644
--- a/ovn/controller/physical.c
+++ b/ovn/controller/physical.c
@@ -291,7 +291,7 @@ load_logical_ingress_metadata(const struct
sbrec_port_binding *binding,
}
static void
-consider_port_binding(struct controller_ctx *ctx,
+consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name,
enum mf_field_id mff_ovn_geneve,
const struct simap *ct_zones,
const struct chassis_index *chassis_index,
@@ -318,7 +318,7 @@ consider_port_binding(struct controller_ctx *ctx,
}
const struct sbrec_port_binding *peer = lport_lookup_by_name(
- ctx->ovnsb_idl, peer_name);
+ sbrec_port_binding_by_name, peer_name);
if (!peer || strcmp(peer->type, binding->type)) {
return;
}
@@ -385,7 +385,8 @@ consider_port_binding(struct controller_ctx *ctx,
const char *distributed_port = smap_get_def(&binding->options,
"distributed-port", "");
const struct sbrec_port_binding *distributed_binding
- = lport_lookup_by_name(ctx->ovnsb_idl, distributed_port);
+ = lport_lookup_by_name(sbrec_port_binding_by_name,
+ distributed_port);
if (!distributed_binding) {
/* Packet will be dropped. */
@@ -867,7 +868,7 @@ update_ofports(struct simap *old, struct simap *new)
}
void
-physical_run(struct controller_ctx *ctx,
+physical_run(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_multicast_group_table *multicast_group_table,
const struct sbrec_port_binding_table *port_binding_table,
enum mf_field_id mff_ovn_geneve,
@@ -880,7 +881,6 @@ physical_run(struct controller_ctx *ctx,
const struct sset *active_tunnels,
struct hmap *flow_table)
{
-
/* This bool tracks physical mapping changes. */
bool physical_map_changed = false;
@@ -999,7 +999,8 @@ physical_run(struct controller_ctx *ctx,
* 64 for logical-to-physical translation. */
const struct sbrec_port_binding *binding;
SBREC_PORT_BINDING_TABLE_FOR_EACH (binding, port_binding_table) {
- consider_port_binding(ctx, mff_ovn_geneve, ct_zones,
+ consider_port_binding(sbrec_port_binding_by_name,
+ mff_ovn_geneve, ct_zones,
chassis_index, active_tunnels,
local_datapaths, binding, chassis,
&ofpacts, flow_table);
@@ -1138,7 +1139,7 @@ physical_run(struct controller_ctx *ctx,
* rule with higher priority for every localport in this
* datapath. */
const struct sbrec_port_binding *pb = lport_lookup_by_name(
- ctx->ovnsb_idl, localport);
+ sbrec_port_binding_by_name, localport);
if (pb && !strcmp(pb->type, "localport")) {
match_set_reg(&match, MFF_LOG_INPORT - MFF_REG0, pb->tunnel_key);
match_set_metadata(&match, htonll(pb->datapath->tunnel_key));
diff --git a/ovn/controller/physical.h b/ovn/controller/physical.h
index 288cefb2899b..4a070a7d0128 100644
--- a/ovn/controller/physical.h
+++ b/ovn/controller/physical.h
@@ -45,7 +45,7 @@ struct sset;
#define OVN_GENEVE_LEN 4
void physical_register_ovs_idl(struct ovsdb_idl *);
-void physical_run(struct controller_ctx *,
+void physical_run(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_multicast_group_table *,
const struct sbrec_port_binding_table *,
enum mf_field_id mff_ovn_geneve,
diff --git a/ovn/controller/pinctrl.c b/ovn/controller/pinctrl.c
index a6be76889a5b..dcb90a39c6bf 100644
--- a/ovn/controller/pinctrl.c
+++ b/ovn/controller/pinctrl.c
@@ -66,20 +66,25 @@ static void pinctrl_handle_put_mac_binding(const struct
flow *md,
bool is_arp);
static void init_put_mac_bindings(void);
static void destroy_put_mac_bindings(void);
-static void run_put_mac_bindings(struct controller_ctx *,
- const struct sbrec_mac_binding_table *);
+static void run_put_mac_bindings(
+ struct controller_ctx *,
+ struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+ struct ovsdb_idl_index *sbrec_port_binding_by_key,
+ const struct sbrec_mac_binding_table *);
static void wait_put_mac_bindings(struct controller_ctx *);
static void flush_put_mac_bindings(void);
static void init_send_garps(void);
static void destroy_send_garps(void);
static void send_garp_wait(void);
-static void send_garp_run(struct controller_ctx *ctx,
- const struct ovsrec_bridge *,
- const struct sbrec_chassis *,
- const struct chassis_index *chassis_index,
- const struct hmap *local_datapaths,
- const struct sset *active_tunnels);
+static void send_garp_run(
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
+ const struct ovsrec_bridge *,
+ const struct sbrec_chassis *,
+ const struct chassis_index *chassis_index,
+ const struct hmap *local_datapaths,
+ const struct sset *active_tunnels);
static void pinctrl_handle_nd_na(const struct flow *ip_flow,
const struct match *md,
struct ofpbuf *userdata,
@@ -96,8 +101,11 @@ static void pinctrl_handle_nd_ns(const struct flow *ip_flow,
static void init_ipv6_ras(void);
static void destroy_ipv6_ras(void);
static void ipv6_ra_wait(void);
-static void send_ipv6_ras(const struct controller_ctx *,
- const struct hmap *local_datapaths);
+static void send_ipv6_ras(
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
+ const struct hmap *local_datapaths);
+;
COVERAGE_DEFINE(pinctrl_drop_put_mac_binding);
@@ -1238,6 +1246,10 @@ pinctrl_recv(const struct sbrec_dns_table *dns_table,
void
pinctrl_run(struct controller_ctx *ctx,
+ struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_key,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_dns_table *dns_table,
const struct sbrec_mac_binding_table *mac_binding_table,
const struct ovsrec_bridge *br_int,
@@ -1280,10 +1292,13 @@ pinctrl_run(struct controller_ctx *ctx,
ofpbuf_delete(msg);
}
- run_put_mac_bindings(ctx, mac_binding_table);
- send_garp_run(ctx, br_int, chassis, chassis_index, local_datapaths,
- active_tunnels);
- send_ipv6_ras(ctx, local_datapaths);
+ run_put_mac_bindings(ctx, sbrec_datapath_binding_by_key,
+ sbrec_port_binding_by_key, mac_binding_table);
+ send_garp_run(sbrec_port_binding_by_datapath,
+ sbrec_port_binding_by_name, br_int, chassis, chassis_index,
+ local_datapaths, active_tunnels);
+ send_ipv6_ras(sbrec_port_binding_by_datapath,
+ sbrec_port_binding_by_name, local_datapaths);
}
/* Table of ipv6_ra_state structures, keyed on logical port name */
@@ -1495,7 +1510,8 @@ ipv6_ra_wait(void)
}
static void
-send_ipv6_ras(const struct controller_ctx *ctx,
+send_ipv6_ras(struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct hmap *local_datapaths)
{
struct shash_node *iter, *iter_next;
@@ -1509,16 +1525,13 @@ send_ipv6_ras(const struct controller_ctx *ctx,
const struct local_datapath *ld;
HMAP_FOR_EACH (ld, hmap_node, local_datapaths) {
- struct sbrec_port_binding *lpval;
- const struct sbrec_port_binding *pb;
- struct ovsdb_idl_index_cursor cursor;
-
- lpval = sbrec_port_binding_index_init_row(ctx->ovnsb_idl,
- &sbrec_table_port_binding);
- sbrec_port_binding_index_set_datapath(lpval, ld->datapath);
- ovsdb_idl_initialize_cursor(ctx->ovnsb_idl, &sbrec_table_port_binding,
- "lport-by-datapath", &cursor);
- SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, &cursor, lpval) {
+ struct sbrec_port_binding *target = sbrec_port_binding_index_init_row(
+ sbrec_port_binding_by_datapath);
+ sbrec_port_binding_index_set_datapath(target, ld->datapath);
+
+ struct sbrec_port_binding *pb;
+ SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, target,
+ sbrec_port_binding_by_datapath) {
if (!smap_get_bool(&pb->options, "ipv6_ra_send_periodic", false))
{
continue;
}
@@ -1529,7 +1542,7 @@ send_ipv6_ras(const struct controller_ctx *ctx,
}
const struct sbrec_port_binding *peer
- = lport_lookup_by_name(ctx->ovnsb_idl, peer_s);
+ = lport_lookup_by_name(sbrec_port_binding_by_name, peer_s);
if (!peer) {
continue;
}
@@ -1566,7 +1579,7 @@ send_ipv6_ras(const struct controller_ctx *ctx,
send_ipv6_ra_time = next_ra;
}
}
- sbrec_port_binding_index_destroy_row(lpval);
+ sbrec_port_binding_index_destroy_row(target);
}
/* Remove those that are no longer in the SB database */
@@ -1691,6 +1704,8 @@ pinctrl_handle_put_mac_binding(const struct flow *md,
static void
run_put_mac_binding(struct controller_ctx *ctx,
+ struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+ struct ovsdb_idl_index *sbrec_port_binding_by_key,
const struct sbrec_mac_binding_table *mac_binding_table,
const struct put_mac_binding *pmb)
{
@@ -1699,8 +1714,9 @@ run_put_mac_binding(struct controller_ctx *ctx,
}
/* Convert logical datapath and logical port key into lport. */
- const struct sbrec_port_binding *pb
- = lport_lookup_by_key(ctx->ovnsb_idl, pmb->dp_key, pmb->port_key);
+ const struct sbrec_port_binding *pb = lport_lookup_by_key(
+ sbrec_datapath_binding_by_key, sbrec_port_binding_by_key,
+ pmb->dp_key, pmb->port_key);
if (!pb) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
@@ -1739,6 +1755,8 @@ run_put_mac_binding(struct controller_ctx *ctx,
static void
run_put_mac_bindings(struct controller_ctx *ctx,
+ struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+ struct ovsdb_idl_index *sbrec_port_binding_by_key,
const struct sbrec_mac_binding_table *mac_binding_table)
{
if (!ctx->ovnsb_idl_txn) {
@@ -1747,7 +1765,8 @@ run_put_mac_bindings(struct controller_ctx *ctx,
const struct put_mac_binding *pmb;
HMAP_FOR_EACH (pmb, hmap_node, &put_mac_bindings) {
- run_put_mac_binding(ctx, mac_binding_table, pmb);
+ run_put_mac_binding(ctx, sbrec_datapath_binding_by_key,
+ sbrec_port_binding_by_key, mac_binding_table, pmb);
}
flush_put_mac_bindings();
}
@@ -1950,13 +1969,15 @@ send_garp(struct garp_data *garp, long long int
current_time)
/* Get localnet vifs, local l3gw ports and ofport for localnet patch ports. */
static void
-get_localnet_vifs_l3gwports(struct controller_ctx *ctx,
- const struct ovsrec_bridge *br_int,
- const struct sbrec_chassis *chassis,
- const struct hmap *local_datapaths,
- struct sset *localnet_vifs,
- struct simap *localnet_ofports,
- struct sset *local_l3gw_ports)
+get_localnet_vifs_l3gwports(
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
+ const struct ovsrec_bridge *br_int,
+ const struct sbrec_chassis *chassis,
+ const struct hmap *local_datapaths,
+ struct sset *localnet_vifs,
+ struct simap *localnet_ofports,
+ struct sset *local_l3gw_ports)
{
for (int i = 0; i < br_int->n_ports; i++) {
const struct ovsrec_port *port_rec = br_int->ports[i];
@@ -1991,7 +2012,7 @@ get_localnet_vifs_l3gwports(struct controller_ctx *ctx,
continue;
}
const struct sbrec_port_binding *pb
- = lport_lookup_by_name(ctx->ovnsb_idl, iface_id);
+ = lport_lookup_by_name(sbrec_port_binding_by_name, iface_id);
if (!pb) {
continue;
}
@@ -2004,13 +2025,10 @@ get_localnet_vifs_l3gwports(struct controller_ctx *ctx,
}
}
+ struct sbrec_port_binding *target = sbrec_port_binding_index_init_row(
+ sbrec_port_binding_by_datapath);
+
const struct local_datapath *ld;
- struct ovsdb_idl_index_cursor cursor;
- struct sbrec_port_binding *lpval;
- lpval = sbrec_port_binding_index_init_row(ctx->ovnsb_idl,
- &sbrec_table_port_binding);
- ovsdb_idl_initialize_cursor(ctx->ovnsb_idl, &sbrec_table_port_binding,
- "lport-by-datapath", &cursor);
HMAP_FOR_EACH (ld, hmap_node, local_datapaths) {
const struct sbrec_port_binding *pb;
@@ -2023,27 +2041,27 @@ get_localnet_vifs_l3gwports(struct controller_ctx *ctx,
* bindings of type "patch" since they might connect to
* distributed gateway ports with NAT addresses. */
- sbrec_port_binding_index_set_datapath(lpval, ld->datapath);
-
- SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, &cursor, lpval) {
+ sbrec_port_binding_index_set_datapath(target, ld->datapath);
+ SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, target,
+ sbrec_port_binding_by_datapath) {
if ((ld->has_local_l3gateway && !strcmp(pb->type, "l3gateway"))
|| !strcmp(pb->type, "patch")) {
sset_add(local_l3gw_ports, pb->logical_port);
}
}
}
- sbrec_port_binding_index_destroy_row(lpval);
+ sbrec_port_binding_index_destroy_row(target);
}
static bool
-pinctrl_is_chassis_resident(struct controller_ctx *ctx,
+pinctrl_is_chassis_resident(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_chassis *chassis,
const struct chassis_index *chassis_index,
const struct sset *active_tunnels,
const char *port_name)
{
const struct sbrec_port_binding *pb
- = lport_lookup_by_name(ctx->ovnsb_idl, port_name);
+ = lport_lookup_by_name(sbrec_port_binding_by_name, port_name);
if (!pb || !pb->chassis) {
return false;
}
@@ -2127,7 +2145,7 @@ extract_addresses_with_port(const char *addresses,
}
static void
-consider_nat_address(struct controller_ctx *ctx,
+consider_nat_address(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const char *nat_address,
const struct sbrec_port_binding *pb,
struct sset *nat_address_keys,
@@ -2141,7 +2159,8 @@ consider_nat_address(struct controller_ctx *ctx,
if (!extract_addresses_with_port(nat_address, laddrs, &lport)
|| (!lport && !strcmp(pb->type, "patch"))
|| (lport && !pinctrl_is_chassis_resident(
- ctx, chassis, chassis_index, active_tunnels, lport))) {
+ sbrec_port_binding_by_name, chassis, chassis_index,
+ active_tunnels, lport))) {
destroy_lport_addresses(laddrs);
free(laddrs);
free(lport);
@@ -2160,7 +2179,7 @@ consider_nat_address(struct controller_ctx *ctx,
}
static void
-get_nat_addresses_and_keys(struct controller_ctx *ctx,
+get_nat_addresses_and_keys(struct ovsdb_idl_index *sbrec_port_binding_by_name,
struct sset *nat_address_keys,
struct sset *local_l3gw_ports,
const struct sbrec_chassis *chassis,
@@ -2172,14 +2191,15 @@ get_nat_addresses_and_keys(struct controller_ctx *ctx,
SSET_FOR_EACH(gw_port, local_l3gw_ports) {
const struct sbrec_port_binding *pb;
- pb = lport_lookup_by_name(ctx->ovnsb_idl, gw_port);
+ pb = lport_lookup_by_name(sbrec_port_binding_by_name, gw_port);
if (!pb) {
continue;
}
if (pb->n_nat_addresses) {
for (int i = 0; i < pb->n_nat_addresses; i++) {
- consider_nat_address(ctx, pb->nat_addresses[i], pb,
+ consider_nat_address(sbrec_port_binding_by_name,
+ pb->nat_addresses[i], pb,
nat_address_keys, chassis,
chassis_index, active_tunnels,
nat_addresses);
@@ -2190,7 +2210,8 @@ get_nat_addresses_and_keys(struct controller_ctx *ctx,
const char *nat_addresses_options = smap_get(&pb->options,
"nat-addresses");
if (nat_addresses_options) {
- consider_nat_address(ctx, nat_addresses_options, pb,
+ consider_nat_address(sbrec_port_binding_by_name,
+ nat_addresses_options, pb,
nat_address_keys, chassis,
chassis_index, active_tunnels,
nat_addresses);
@@ -2206,7 +2227,8 @@ send_garp_wait(void)
}
static void
-send_garp_run(struct controller_ctx *ctx,
+send_garp_run(struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct ovsrec_bridge *br_int,
const struct sbrec_chassis *chassis,
const struct chassis_index *chassis_index,
@@ -2221,10 +2243,14 @@ send_garp_run(struct controller_ctx *ctx,
shash_init(&nat_addresses);
- get_localnet_vifs_l3gwports(ctx, br_int, chassis, local_datapaths,
- &localnet_vifs, &localnet_ofports, &local_l3gw_ports);
+ get_localnet_vifs_l3gwports(sbrec_port_binding_by_datapath,
+ sbrec_port_binding_by_name,
+ br_int, chassis, local_datapaths,
+ &localnet_vifs, &localnet_ofports,
+ &local_l3gw_ports);
- get_nat_addresses_and_keys(ctx, &nat_ip_keys, &local_l3gw_ports,
+ get_nat_addresses_and_keys(sbrec_port_binding_by_name,
+ &nat_ip_keys, &local_l3gw_ports,
chassis, chassis_index, active_tunnels,
&nat_addresses);
/* For deleted ports and deleted nat ips, remove from send_garp_data. */
@@ -2239,9 +2265,8 @@ send_garp_run(struct controller_ctx *ctx,
/* Update send_garp_data. */
const char *iface_id;
SSET_FOR_EACH (iface_id, &localnet_vifs) {
- const struct sbrec_port_binding *pb;
-
- pb = lport_lookup_by_name(ctx->ovnsb_idl, iface_id);
+ const struct sbrec_port_binding *pb = lport_lookup_by_name(
+ sbrec_port_binding_by_name, iface_id);
if (pb) {
send_garp_update(pb, &localnet_ofports, local_datapaths,
&nat_addresses);
@@ -2251,9 +2276,8 @@ send_garp_run(struct controller_ctx *ctx,
/* Update send_garp_data for nat-addresses. */
const char *gw_port;
SSET_FOR_EACH (gw_port, &local_l3gw_ports) {
- const struct sbrec_port_binding *pb;
-
- pb = lport_lookup_by_name(ctx->ovnsb_idl, gw_port);
+ const struct sbrec_port_binding *pb
+ = lport_lookup_by_name(sbrec_port_binding_by_name, gw_port);
if (pb) {
send_garp_update(pb, &localnet_ofports, local_datapaths,
&nat_addresses);
diff --git a/ovn/controller/pinctrl.h b/ovn/controller/pinctrl.h
index a2518ebcdaec..27f51d7de65c 100644
--- a/ovn/controller/pinctrl.h
+++ b/ovn/controller/pinctrl.h
@@ -26,6 +26,7 @@ struct chassis_index;
struct controller_ctx;
struct hmap;
struct lport_index;
+struct ovsdb_idl_index;
struct ovsrec_bridge;
struct sbrec_chassis;
struct sbrec_dns_table;
@@ -33,6 +34,10 @@ struct sbrec_mac_binding_table;
void pinctrl_init(void);
void pinctrl_run(struct controller_ctx *,
+ struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
+ struct ovsdb_idl_index *sbrec_port_binding_by_datapath,
+ struct ovsdb_idl_index *sbrec_port_binding_by_key,
+ struct ovsdb_idl_index *sbrec_port_binding_by_name,
const struct sbrec_dns_table *,
const struct sbrec_mac_binding_table *,
const struct ovsrec_bridge *, const struct sbrec_chassis *,
diff --git a/ovsdb/ovsdb-idlc.in b/ovsdb/ovsdb-idlc.in
index 5a675ebba24b..14d0b0ed486b 100755
--- a/ovsdb/ovsdb-idlc.in
+++ b/ovsdb/ovsdb-idlc.in
@@ -284,24 +284,43 @@ static inline bool %(s)s_is_deleted(const struct %(s)s
*row)
}
void %(s)s_index_destroy_row(const struct %(s)s *);
-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))
+
+struct %(s)s *%(s)s_index_find(struct ovsdb_idl_index *, const struct %(s)s *);
+
+int %(s)s_index_compare(
+ struct ovsdb_idl_index *,
+ const struct %(s)s *,
+ const struct %(s)s *);
+struct ovsdb_idl_cursor %(s)s_cursor_first(struct ovsdb_idl_index *);
+struct ovsdb_idl_cursor %(s)s_cursor_first_eq(
+ struct ovsdb_idl_index *, const struct %(s)s *);
+struct ovsdb_idl_cursor %(s)s_cursor_first_ge(
+ struct ovsdb_idl_index *, const struct %(s)s *);
+
+struct %(s)s *%(s)s_cursor_data(struct ovsdb_idl_cursor *);
+
+#define %(S)s_FOR_EACH_RANGE(ROW, FROM, TO, INDEX) \\
+ for (struct ovsdb_idl_cursor cursor__ = %(s)s_cursor_first_ge(INDEX,
FROM); \\
+ (cursor__.position \\
+ && ((ROW) = %(s)s_cursor_data(&cursor__), \\
+ !(TO) || %(s)s_index_compare(INDEX, ROW, TO) <= 0)); \\
+ ovsdb_idl_cursor_next(&cursor__))
+#define %(S)s_FOR_EACH_EQUAL(ROW, KEY, INDEX) \\
+ for (struct ovsdb_idl_cursor cursor__ = %(s)s_cursor_first_eq(INDEX,
KEY); \\
+ (cursor__.position \\
+ ? ((ROW) = %(s)s_cursor_data(&cursor__), \\
+ ovsdb_idl_cursor_next_eq(&cursor__, INDEX), \\
+ true) \\
+ : false); \\
+ )
+#define %(S)s_FOR_EACH_BYINDEX(ROW, INDEX) \\
+ for (struct ovsdb_idl_cursor cursor__ = %(s)s_cursor_first(INDEX); \\
+ (cursor__.position \\
+ ? ((ROW) = %(s)s_cursor_data(&cursor__), \\
+ ovsdb_idl_cursor_next(&cursor__), \\
+ true) \\
+ : false); \\
+ )
void %(s)s_init(struct %(s)s *);
void %(s)s_delete(const struct %(s)s *);
@@ -367,7 +386,7 @@ bool %(s)s_is_updated(const struct %(s)s *, enum
%(s)s_column_id);
print("")
# Table indexes.
- print("struct %(s)s * %(s)s_index_init_row(struct ovsdb_idl *, const struct
ovsdb_idl_table_class *);" % {'s': structName})
+ print("struct %(s)s *%(s)s_index_init_row(struct ovsdb_idl_index *);"
% {'s': structName})
print
for columnName, column in sorted(table.columns.items()):
print('void %(s)s_index_set_%(c)s(const struct %(s)s *,' % {'s':
structName, 'c': columnName})
@@ -1164,80 +1183,68 @@ void
void
%(s)s_index_destroy_row(const struct %(s)s *row)
{
- ovsdb_idl_index_destroy_row__(&row->header_);
+ ovsdb_idl_index_destroy_row(&row->header_);
}
""" % { 's' : structName, 't': tableName })
print("""
/* Creates a new row of kind "%(t)s". */
struct %(s)s *
-%(s)s_index_init_row(struct ovsdb_idl *idl, const struct ovsdb_idl_table_class
*class_)
-{""" % {'s': structName, 't': tableName})
- #for columnName, column in sorted(table.columns.items()):
- # if column.type.is_smap():
- # print " smap_init(&row->%s);" % columnName
- print(" return (struct %(s)s *) ovsdb_idl_index_init_row(idl,
class_);" % {'s': structName, 't': tableName})
- print("}")
+%(s)s_index_init_row(struct ovsdb_idl_index *index)
+{
+ ovs_assert(index->table->class_ == &%(p)stable_%(tl)s);
+ return (struct %(s)s *) ovsdb_idl_index_init_row(index);
+}
- print("""
-/* This function is used to compare "%(s)s" records on table in iteration
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 *
+%(s)s_index_find(struct ovsdb_idl_index *index, const struct %(s)s *target)
{
- 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)
+ ovs_assert(index->table->class_ == &%(p)stable_%(tl)s);
+ return %(s)s_cast(ovsdb_idl_index_find(index, &target->header_));
+}
+
+/* Compares 'a' to 'b' and returns a strcmp()-type result. */
+int
+%(s)s_index_compare(
+ struct ovsdb_idl_index *index,
+ const struct %(s)s *a,
+ const struct %(s)s *b)
{
- 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 ovsdb_idl_index_compare(index, &a->header_, &b->header_);
+}
+
+struct ovsdb_idl_cursor
+%(s)s_cursor_first(struct ovsdb_idl_index *index)
{
- 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)
+ ovs_assert(index->table->class_ == &%(p)stable_%(tl)s);
+ return ovsdb_idl_cursor_first(index);
+}
+
+struct ovsdb_idl_cursor
+%(s)s_cursor_first_eq(
+ struct ovsdb_idl_index *index, const struct %(s)s *target)
{
- 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)
+ ovs_assert(index->table->class_ == &%(p)stable_%(tl)s);
+ return ovsdb_idl_cursor_first_eq(index, &target->header_);
+}
+
+struct ovsdb_idl_cursor
+%(s)s_cursor_first_ge(
+ struct ovsdb_idl_index *index, const struct %(s)s *target)
{
- 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)
+ ovs_assert(index->table->class_ == &%(p)stable_%(tl)s);
+ return ovsdb_idl_cursor_first_ge(index, &target->header_);
+}
+
+struct %(s)s *
+%(s)s_cursor_data(struct ovsdb_idl_cursor *cursor)
{
- return %(s)s_cast(ovsdb_idl_index_data(CONST_CAST(struct
ovsdb_idl_index_cursor *, cursor)));
-}""" % { 's' : structName })
+ return %(s)s_cast(ovsdb_idl_cursor_data(cursor));
+}
+""" % {'s': structName,
+ 'c': columnName,
+ 't': tableName,
+ 'tl': tableName.lower(),
+ 'p': prefix})
# Indexes Set functions
for columnName, column in sorted(table.columns.items()):
type = column.type
@@ -1270,10 +1277,10 @@ struct %(s)s *
} else {
ovsdb_datum_init_empty(datum);
}
- ovsdb_idl_index_write_(CONST_CAST(struct ovsdb_idl_row *, &row->header_),
- &%(s)s_columns[%(S)s_COL_%(C)s],
- datum,
- &%(p)stable_classes[%(P)sTABLE_%(T)s]);
+ ovsdb_idl_index_write(CONST_CAST(struct ovsdb_idl_row *, &row->header_),
+ &%(s)s_columns[%(S)s_COL_%(C)s],
+ datum,
+ &%(p)stable_classes[%(P)sTABLE_%(T)s]);
}
""" % {'t': tableName,
'p': prefix,
@@ -1317,7 +1324,7 @@ struct %(s)s *
print(" "+
type.value.assign_c_value_casting_away_const("value->%s" % type.value.type.to_string(),
valueVar))
else:
print(" datum.values = NULL;")
- txn_write_func = "ovsdb_idl_index_write_"
+ txn_write_func = "ovsdb_idl_index_write"
elif type.is_optional_pointer():
print(" union ovsdb_atom *key = xmalloc(sizeof (union
ovsdb_atom));")
print()
@@ -1330,7 +1337,7 @@ struct %(s)s *
print(" datum.keys = NULL;")
print(" }")
print(" datum.values = NULL;")
- txn_write_func = "ovsdb_idl_index_write_"
+ txn_write_func = "ovsdb_idl_index_write"
elif type.n_max == 1:
print(" union ovsdb_atom *key = xmalloc(sizeof(union
ovsdb_atom));")
print()
@@ -1343,7 +1350,7 @@ struct %(s)s *
print(" datum.keys = NULL;")
print(" }")
print(" datum.values = NULL;")
- txn_write_func = "ovsdb_idl_index_write_"
+ txn_write_func = "ovsdb_idl_index_write"
else:
print(" size_t i;")
print()
@@ -1364,7 +1371,7 @@ struct %(s)s *
valueType = "OVSDB_TYPE_VOID"
print(" ovsdb_datum_sort_unique(&datum, %s, %s);" % (
type.key.toAtomicType(), valueType))
- txn_write_func = "ovsdb_idl_index_write_"
+ txn_write_func = "ovsdb_idl_index_write"
print(" %(f)s(CONST_CAST(struct ovsdb_idl_row *, &row->header_),
&%(s)s_columns[ %(S)s_COL_%(C)s ], &datum, &%(p)stable_classes[%(P)sTABLE_%(T)s]);" \
% {'f': txn_write_func,
's': structName,
diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c
index c557c7c64520..ff5f92035603 100644
--- a/tests/test-ovsdb.c
+++ b/tests/test-ovsdb.c
@@ -2723,7 +2723,6 @@ do_idl_compound_index_with_ref(struct ovs_cmdl_context
*ctx)
struct idltest_simple4 *myRow2;
const struct ovsdb_datum *uset OVS_UNUSED;
const struct ovsdb_datum *uref OVS_UNUSED;
- struct ovsdb_idl_index_cursor cursor;
int step = 0;
idl = ovsdb_idl_create(ctx->argv[1], &idltest_idl_class, false, true);
@@ -2734,16 +2733,11 @@ do_idl_compound_index_with_ref(struct ovs_cmdl_context
*ctx)
ovsdb_idl_add_table(idl, &idltest_table_simple4);
ovsdb_idl_add_column(idl, &idltest_simple4_col_name);
- struct ovsdb_idl_index *index;
- index = ovsdb_idl_create_index(idl, &idltest_table_simple3, "uref");
- ovsdb_idl_index_add_column(index, &idltest_simple3_col_uref,
- OVSDB_INDEX_ASC, NULL);
+ struct ovsdb_idl_index *index = ovsdb_idl_index_create1(
+ idl, &idltest_simple3_col_uref);
ovsdb_idl_get_initial_snapshot(idl);
- ovsdb_idl_initialize_cursor(idl, &idltest_table_simple3, "uref",
- &cursor);
-
setvbuf(stdout, NULL, _IONBF, 0);
ovsdb_idl_run(idl);
@@ -2765,12 +2759,11 @@ do_idl_compound_index_with_ref(struct ovs_cmdl_context *ctx)
/* Use index to query the row with reference */
- struct idltest_simple3 *equal;
- equal = idltest_simple3_index_init_row(idl, &idltest_table_simple3);
+ struct idltest_simple3 *equal = idltest_simple3_index_init_row(index);
myRow2 = (struct idltest_simple4 *) idltest_simple4_first(idl);
idltest_simple3_index_set_uref(equal, &myRow2, 1);
printf("%03d: Query using index with reference\n", step++);
- IDLTEST_SIMPLE3_FOR_EACH_EQUAL (myRow, &cursor, equal) {
+ IDLTEST_SIMPLE3_FOR_EACH_EQUAL (myRow, equal, index) {
print_idl_row_simple3(myRow, step++);
}
idltest_simple3_index_destroy_row(equal);
@@ -2797,65 +2790,64 @@ do_idl_compound_index_with_ref(struct ovs_cmdl_context
*ctx)
static int
test_idl_compound_index_single_column(struct ovsdb_idl *idl,
- struct ovsdb_idl_index_cursor *sCursor,
- struct ovsdb_idl_index_cursor *iCursor)
+ struct ovsdb_idl_index *s_index,
+ struct ovsdb_idl_index *i_index)
{
const struct idltest_simple *myRow;
struct ovsdb_idl_txn *txn;
int step = 0;
- /* Display records by string index -> sCursor */
+ /* Display records by string index. */
++step;
- IDLTEST_SIMPLE_FOR_EACH_BYINDEX (myRow, sCursor) {
+ IDLTEST_SIMPLE_FOR_EACH_BYINDEX (myRow, s_index) {
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 */
+ /* Display records by integer index. */
++step;
- IDLTEST_SIMPLE_FOR_EACH_BYINDEX (myRow, iCursor) {
+ IDLTEST_SIMPLE_FOR_EACH_BYINDEX (myRow, i_index) {
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
+ /* Display records by string index -> s_index with filtering
* where s=\"List001\
*/
++step;
- struct idltest_simple *equal;
- equal = idltest_simple_index_init_row(idl, &idltest_table_simple);
+ struct idltest_simple *equal = idltest_simple_index_init_row(s_index);
idltest_simple_index_set_s(equal, "List001");
ovs_assert(strcmp(equal->s, "List001") == 0);
- IDLTEST_SIMPLE_FOR_EACH_EQUAL (myRow, sCursor, equal) {
+ IDLTEST_SIMPLE_FOR_EACH_EQUAL (myRow, equal, s_index) {
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 */
+ /* Display records by integer index -> i_index with filtering where i=5 */
++step;
idltest_simple_index_set_i(equal, 5);
ovs_assert(equal->i == 5);
- IDLTEST_SIMPLE_FOR_EACH_EQUAL (myRow, iCursor, equal) {
+ IDLTEST_SIMPLE_FOR_EACH_EQUAL (myRow, equal, i_index) {
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] */
+ /* Display records by integer index -> i_index in range i=[3,7] */
++step;
struct idltest_simple *from, *to;
- from = idltest_simple_index_init_row(idl, &idltest_table_simple);
+ from = idltest_simple_index_init_row(i_index);
idltest_simple_index_set_i(from, 3);
ovs_assert(from->i == 3);
- to = idltest_simple_index_init_row(idl, &idltest_table_simple);
+ to = idltest_simple_index_init_row(i_index);
idltest_simple_index_set_i(to, 7);
ovs_assert(to->i == 7);
- IDLTEST_SIMPLE_FOR_EACH_RANGE (myRow, iCursor, from, to) {
+ IDLTEST_SIMPLE_FOR_EACH_RANGE (myRow, from, to, i_index) {
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 */
+ /* Delete record i=4 and insert i=54 by integer index -> i_index */
++step;
struct idltest_simple *toDelete, *toInsert;
- toDelete = idltest_simple_index_init_row(idl, &idltest_table_simple);
+ toDelete = idltest_simple_index_init_row(i_index);
idltest_simple_index_set_i(toDelete, 4);
ovs_assert(toDelete->i == 4);
- myRow = idltest_simple_index_find(iCursor, toDelete);
+ myRow = idltest_simple_index_find(i_index, toDelete);
ovs_assert(myRow);
ovs_assert(myRow->i == 4);
txn = ovsdb_idl_txn_create(idl);
@@ -2868,7 +2860,7 @@ test_idl_compound_index_single_column(struct ovsdb_idl
*idl,
idltest_simple_index_set_i(to, 60);
printf("Expected 60, stored %"PRId64"\n", to->i);
ovs_assert(to->i == 60);
- IDLTEST_SIMPLE_FOR_EACH_RANGE (myRow, iCursor, from, to) {
+ IDLTEST_SIMPLE_FOR_EACH_RANGE (myRow, from, to, i_index) {
printf("%03d: i=%"PRId64" s=%s b=%s r=%f\n", step, myRow->i,
myRow->s, myRow->b?"True":"False", myRow->r);
}
@@ -2876,7 +2868,7 @@ test_idl_compound_index_single_column(struct ovsdb_idl
*idl,
/* Test special-case range, "from" and "to" are both NULL,
* which is interpreted as the range from -infinity to +infinity. */
++step;
- IDLTEST_SIMPLE_FOR_EACH_RANGE (myRow, iCursor, NULL, NULL) {
+ IDLTEST_SIMPLE_FOR_EACH_RANGE (myRow, NULL, NULL, i_index) {
printf("%03d: i=%"PRId64" s=%s b=%s r=%f\n", step, myRow->i,
myRow->s, myRow->b?"True":"False", myRow->r);
}
@@ -2885,52 +2877,50 @@ test_idl_compound_index_single_column(struct ovsdb_idl
*idl,
idltest_simple_index_destroy_row(from);
idltest_simple_index_destroy_row(to);
idltest_simple_index_destroy_row(equal);
+ idltest_simple_index_destroy_row(toDelete);
return step;
}
static int
-test_idl_compound_index_double_column(struct ovsdb_idl *idl,
- struct ovsdb_idl_index_cursor *siCursor,
- struct ovsdb_idl_index_cursor *sidCursor,
- struct ovsdb_idl_index_cursor *isCursor,
- struct ovsdb_idl_index_cursor *idsCursor)
+test_idl_compound_index_double_column(struct ovsdb_idl_index *si_index,
+ struct ovsdb_idl_index *sid_index,
+ struct ovsdb_idl_index *is_index,
+ struct ovsdb_idl_index *ids_index)
{
const struct idltest_simple *myRow;
int step = 0;
- /* Display records by string-integer index -> siCursor */
+ /* Display records by string-integer index -> si_index */
step++;
- IDLTEST_SIMPLE_FOR_EACH_BYINDEX (myRow, siCursor) {
+ IDLTEST_SIMPLE_FOR_EACH_BYINDEX (myRow, si_index) {
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 */
+ /* Display records by string-integer(down order) index -> sid_index */
step++;
- IDLTEST_SIMPLE_FOR_EACH_BYINDEX (myRow, sidCursor) {
+ IDLTEST_SIMPLE_FOR_EACH_BYINDEX (myRow, sid_index) {
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
+ /* Display records by string-integer index -> si_index with filtering
* where s="List000" and i=10
*/
step++;
- struct idltest_simple *equal;
- equal = idltest_simple_index_init_row(idl, &idltest_table_simple);
+ struct idltest_simple *equal = idltest_simple_index_init_row(si_index);
idltest_simple_index_set_s(equal, "List000");
ovs_assert(strcmp(equal->s, "List000") == 0);
idltest_simple_index_set_i(equal, 10);
ovs_assert(equal->i == 10);
- IDLTEST_SIMPLE_FOR_EACH_EQUAL (myRow, siCursor, equal) {
+ IDLTEST_SIMPLE_FOR_EACH_EQUAL (myRow, equal, si_index) {
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]
+ /* Display records by string-integer index -> si_index in range i=[0,100]
* and s=[\"List002\",\"List003\"]
*/
step++;
- struct idltest_simple *from, *to;
- from = idltest_simple_index_init_row(idl, &idltest_table_simple);
- to = idltest_simple_index_init_row(idl, &idltest_table_simple);
+ struct idltest_simple *from = idltest_simple_index_init_row(si_index);
+ struct idltest_simple *to = idltest_simple_index_init_row(si_index);
idltest_simple_index_set_i(from, 0);
ovs_assert(from->i == 0);
idltest_simple_index_set_s(from, "List001");
@@ -2939,19 +2929,19 @@ test_idl_compound_index_double_column(struct ovsdb_idl
*idl,
ovs_assert(to->i == 100);
idltest_simple_index_set_s(to, "List005");
ovs_assert(strcmp(to->s, "List005")==0);
- IDLTEST_SIMPLE_FOR_EACH_RANGE (myRow, siCursor, from, to) {
+ IDLTEST_SIMPLE_FOR_EACH_RANGE (myRow, from, to, si_index) {
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) {
+ IDLTEST_SIMPLE_FOR_EACH_BYINDEX (myRow, is_index) {
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) {
+ IDLTEST_SIMPLE_FOR_EACH_BYINDEX (myRow, ids_index) {
printf("%03d: i=%"PRId64" s=%s b=%s r=%f\n", step, myRow->i, myRow->s,
myRow->b?"True":"False", myRow->r);
}
@@ -2966,8 +2956,6 @@ 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
};
@@ -2983,60 +2971,37 @@ do_idl_compound_index(struct ovs_cmdl_context *ctx)
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);
+ struct ovsdb_idl_index *s_index
+ = ovsdb_idl_index_create1(idl, &idltest_simple_col_s);
+
+ struct ovsdb_idl_index *i_index
+ = ovsdb_idl_index_create1(idl, &idltest_simple_col_i);
+
+ struct ovsdb_idl_index *si_index
+ = ovsdb_idl_index_create2(idl, &idltest_simple_col_s,
+ &idltest_simple_col_i);
+
+ const struct ovsdb_idl_index_column sid_columns[] = {
+ { .column = &idltest_simple_col_s },
+ { .column = &idltest_simple_col_i, .order = OVSDB_INDEX_DESC },
+ };
+ struct ovsdb_idl_index *sid_index
+ = ovsdb_idl_index_create(idl, sid_columns, ARRAY_SIZE(sid_columns));
+
+ struct ovsdb_idl_index *is_index
+ = ovsdb_idl_index_create2(idl, &idltest_simple_col_i,
+ &idltest_simple_col_s);
+
+ const struct ovsdb_idl_index_column ids_columns[] = {
+ { .column = &idltest_simple_col_i, .order = OVSDB_INDEX_DESC },
+ { .column = &idltest_simple_col_s },
+ };
+ struct ovsdb_idl_index *ids_index
+ = ovsdb_idl_index_create(idl, ids_columns, ARRAY_SIZE(sid_columns));
/* 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++) {
@@ -3050,11 +3015,11 @@ do_idl_compound_index(struct ovs_cmdl_context *ctx)
switch (test_to_run) {
case IDL_COMPOUND_INDEX_WITH_SINGLE_COLUMN:
- test_idl_compound_index_single_column(idl, &sCursor, &iCursor);
+ test_idl_compound_index_single_column(idl, s_index, i_index);
break;
case IDL_COMPOUND_INDEX_WITH_DOUBLE_COLUMN:
- test_idl_compound_index_double_column(idl, &siCursor,
- &sidCursor, &isCursor, &idsCursor);
+ test_idl_compound_index_double_column(si_index, sid_index,
+ is_index, ids_index);
break;
default:
printf("%03d: Test %s not implemented.\n", step++, arg);