On Mon, Jun 03, 2024 at 12:20:36AM -0400, Mike Pattrick wrote:
> Currently all OVSDB database queries except for UUID lookups all result
> in linear lookups over the entire table, even if an index is present.
>
> This patch modifies ovsdb_query() to attempt an index lookup first, if
> possible. If no matching indexes are present then a linear index is
> still conducted.
>
> Reported-at: https://issues.redhat.com/browse/FDP-590
> Signed-off-by: Mike Pattrick <[email protected]>
...
> diff --git a/ovsdb/query.c b/ovsdb/query.c
> index eebe56412..e3e50a034 100644
> --- a/ovsdb/query.c
> +++ b/ovsdb/query.c
> @@ -21,32 +21,116 @@
> #include "condition.h"
> #include "row.h"
> #include "table.h"
> +#include "transaction.h"
> +
> +static bool
> +ovsdb_query_index(struct ovsdb_table *table,
> + const struct ovsdb_condition *cnd,
> + const struct ovsdb_row **out)
> +{
> + for (size_t idx = 0; idx < table->schema->n_indexes; idx++) {
> + const struct ovsdb_column_set *index = &table->schema->indexes[idx];
> + struct hmap_node *node;
> + size_t matches = 0;
> + uint32_t hash = 0;
> +
> + if (index->n_columns != cnd->n_clauses) {
> + continue;
> + }
> +
> + /* The conditions may not be in the same order as the index. */
> + for (size_t c = 0; c < cnd->n_clauses; c++) {
> + const struct ovsdb_clause *cnd_cls = &cnd->clauses[c];
> +
> + if (cnd_cls->function != OVSDB_F_EQ) {
> + return false;
> + }
> +
> + for (size_t i = 0; i < index->n_columns; i++) {
> + const struct ovsdb_column *idx_col = index->columns[i];
> +
> + if (cnd_cls->index == idx_col->index) {
> + hash = ovsdb_datum_hash(&cnd_cls->arg, &idx_col->type,
> + hash);
> + matches++;
> + break;
> + }
> + }
> +
> + /* If none of the indexed columns match, continue to the next
> + * index. */
> + if (matches == c) {
> + break;
> + }
> + }
> +
> + if (matches != cnd->n_clauses) {
> + continue;
> + }
> +
> + for (node = hmap_first_with_hash(&table->indexes[idx], hash); node;
> + node = hmap_next_with_hash(node)) {
> + struct ovsdb_row *irow = ovsdb_row_from_index_node(node, table,
> + idx);
> +
> + for (size_t c = 0; c < cnd->n_clauses; c++) {
> + const struct ovsdb_clause *cnd_cls = &cnd->clauses[c];
> +
> + if (!ovsdb_datum_equals(&cnd_cls->arg,
> + &irow->fields[cnd_cls->index],
> + &cnd_cls->column->type)) {
> + irow = NULL;
> + break;
> + }
> + }
> +
> + if (irow) {
> + *out = irow;
> + return true;
> + }
> + }
> +
> + /* In the case that there was a matching index but no matching row,
> the
> + * index check is still considered to be a success. */
> + return true;
Hi Mike,
Maybe I misread it, but it seems that the code above implements:
1. If a row is found, return true
2. Otherwise, returns true
If so, then is there a need 1?
> + }
> + return false;
> +}
...
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev