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

Reply via email to