From 2f615fe1ffe60c58d5d75de0c3dc50eb494413d3 Mon Sep 17 00:00:00 2001 From: Harpreet Sangar Date: Wed, 26 Apr 2023 20:26:45 +0530 Subject: [PATCH] Fix memory leaks: * Handle deletion of `filter_tree_root` in `sort_fields_guard_t`. * Handle `filter_tree_root` being updated in `Index::static_filter_query_eval`. * Handle deletion of `phrase_result_ids` in `Index::search`. --- include/field.h | 2 +- include/index.h | 2 +- src/collection.cpp | 7 +++++++ src/index.cpp | 9 +++++++-- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/include/field.h b/include/field.h index 03c7015a..8b4fe04e 100644 --- a/include/field.h +++ b/include/field.h @@ -545,7 +545,7 @@ struct sort_by { }; struct eval_t { - filter_node_t* filter_tree_root; + filter_node_t* filter_tree_root = nullptr; uint32_t* ids = nullptr; uint32_t size = 0; }; diff --git a/include/index.h b/include/index.h index 9b9c1d2e..fb2dfd82 100644 --- a/include/index.h +++ b/include/index.h @@ -644,7 +644,7 @@ public: Option search(std::vector& field_query_tokens, const std::vector& the_fields, const text_match_type_t match_type, - filter_node_t* filter_tree_root, std::vector& facets, facet_query_t& facet_query, + filter_node_t*& filter_tree_root, std::vector& facets, facet_query_t& facet_query, const std::vector>& included_ids, const std::vector& excluded_ids, std::vector& sort_fields_std, const std::vector& num_typos, Topster* topster, Topster* curated_topster, diff --git a/src/collection.cpp b/src/collection.cpp index dddbf66b..5eab45f0 100644 --- a/src/collection.cpp +++ b/src/collection.cpp @@ -28,6 +28,8 @@ struct sort_fields_guard_t { ~sort_fields_guard_t() { for(auto& sort_by_clause: sort_fields_std) { + delete sort_by_clause.eval.filter_tree_root; + if(sort_by_clause.eval.ids) { delete [] sort_by_clause.eval.ids; sort_by_clause.eval.ids = nullptr; @@ -1523,6 +1525,11 @@ Option Collection::search(std::string raw_query, std::unique_ptr search_params_guard(search_params); auto search_op = index->run_search(search_params, name); + + // filter_tree_root might be updated in Index::static_filter_query_eval. + filter_tree_root_guard.release(); + filter_tree_root_guard.reset(filter_tree_root); + if (!search_op.ok()) { return Option(search_op.code(), search_op.error()); } diff --git a/src/index.cpp b/src/index.cpp index 569eb7ec..ed3873b7 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -2325,7 +2325,7 @@ bool Index::static_filter_query_eval(const override_t* override, if (filter_tree_root == nullptr) { filter_tree_root = new_filter_tree_root; } else { - filter_node_t* root = new filter_node_t(AND, filter_tree_root, + auto root = new filter_node_t(AND, filter_tree_root, new_filter_tree_root); filter_tree_root = root; } @@ -2688,7 +2688,7 @@ void Index::search_infix(const std::string& query, const std::string& field_name Option Index::search(std::vector& field_query_tokens, const std::vector& the_fields, const text_match_type_t match_type, - filter_node_t* filter_tree_root, std::vector& facets, facet_query_t& facet_query, + filter_node_t*& filter_tree_root, std::vector& facets, facet_query_t& facet_query, const std::vector>& included_ids, const std::vector& excluded_ids, std::vector& sort_fields_std, const std::vector& num_typos, Topster* topster, Topster* curated_topster, @@ -2774,6 +2774,8 @@ Option Index::search(std::vector& field_query_tokens, cons // handle phrase searches uint32_t* phrase_result_ids = nullptr; uint32_t phrase_result_count = 0; + std::unique_ptr phrase_result_ids_guard; + if (!field_query_tokens[0].q_phrases.empty()) { do_phrase_search(num_search_fields, the_fields, field_query_tokens, sort_fields_std, searched_queries, group_limit, group_by_fields, @@ -2782,6 +2784,9 @@ Option Index::search(std::vector& field_query_tokens, cons excluded_result_ids, excluded_result_ids_size, excluded_group_ids, curated_topster, included_ids_map, is_wildcard_query, phrase_result_ids, phrase_result_count); + + phrase_result_ids_guard.reset(phrase_result_ids); + if (phrase_result_count == 0) { goto process_search_results; }