Skip to content

Commit

Permalink
opt4: simplify_minof (#223)
Browse files Browse the repository at this point in the history
  • Loading branch information
msm-cert authored Oct 1, 2024
1 parent 18a45d8 commit c76a118
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
29 changes: 29 additions & 0 deletions libursa/QueryOptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

#include <vector>

// Returns a query that represents every element in the dataset.
// There's no magic here, AND() just behaves like this.
Query q_everything() {
std::vector<Query> queries;
return std::move(q_and(std::move(queries)));
}

// Run the optimization pases on subqueries.
// After this step, every subquery should be maximally optimized,
// So I believe there's no need to run this in a loop.
Expand Down Expand Up @@ -76,6 +83,27 @@ Query deduplicate_primitives(Query &&q, bool *changed) {
return std::move(Query(q.get_type(), std::move(newqueries)));
}

// Minof is the slowest operation, so replace it by others if possible.
// This may also enable other optimizations to take place.
// MIN 5 OF (a, b, c, d, e) --> AND(a, b, c, d, e)
// MIN 1 OF (a, b, c, d, e) --> OR(a, b, c, d, e)
// MIN 0 OF (a, b, c, d, e) --> everything()
Query simplify_minof(Query &&q, bool *changed) {
if (q.get_type() == QueryType::MIN_OF) {
if (q.as_count() == q.as_queries().size()) {
*changed = true;
return std::move(q_and(std::move(q.as_queries())));
} else if (q.as_count() == 1) {
*changed = true;
return std::move(q_or(std::move(q.as_queries())));
} else if (q.as_count() == 0) {
*changed = true;
return std::move(q_everything());
}
}
return std::move(q);
}

Query q_optimize(Query &&q) {
if (q.get_type() == QueryType::PRIMITIVE) {
// Nothing to improve here.
Expand All @@ -89,6 +117,7 @@ Query q_optimize(Query &&q) {
q = flatten_trivial_operations(std::move(q), &changed);
q = inline_suboperations(std::move(q), &changed);
q = deduplicate_primitives(std::move(q), &changed);
q = simplify_minof(std::move(q), &changed);
}

return std::move(q);
Expand Down
2 changes: 1 addition & 1 deletion libursa/Version.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ constexpr std::string_view ursadb_format_version = "1.5.0";
// Project version.
// Consider updating the version tag when doing PRs.
// clang-format off
constexpr std::string_view ursadb_version_string = "@PROJECT_VERSION@+opt3";
constexpr std::string_view ursadb_version_string = "@PROJECT_VERSION@+opt4";
// clang-format on

0 comments on commit c76a118

Please sign in to comment.