Skip to content

Commit 7d3d51b

Browse files
authored
Optimize IntegerNode::find_first_local (#7772)
If you are just testing one element, use simple compare instead of find_first<Cond>. This will speed up queries where secondary nodes are IntegerNodes.
1 parent 06b658b commit 7d3d51b

File tree

5 files changed

+18
-14
lines changed

5 files changed

+18
-14
lines changed

src/realm/array.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,11 @@ class Array : public Node, public ArrayParent {
392392
template <class cond>
393393
size_t find_first(int64_t value, size_t start = 0, size_t end = size_t(-1)) const
394394
{
395+
static cond c;
395396
REALM_ASSERT(start <= m_size && (end <= m_size || end == size_t(-1)) && start <= end);
397+
if (end - start == 1) {
398+
return c(get(start), value) ? start : realm::not_found;
399+
}
396400
// todo, would be nice to avoid this in order to speed up find_first loops
397401
QueryStateFindFirst state;
398402
Finder finder = m_vtable->finder[cond::condition];

src/realm/array_integer_tpl.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,17 @@ bool ArrayIntNull::find_impl(value_type opt_value, size_t start, size_t end, Que
104104
template <class cond>
105105
size_t ArrayIntNull::find_first(value_type value, size_t start, size_t end) const
106106
{
107+
static cond c;
108+
REALM_ASSERT(start <= m_size && (end <= m_size || end == size_t(-1)) && start <= end);
109+
if (end - start == 1) {
110+
std::optional<int64_t> opt_int = get(start);
111+
return c(opt_int, value, !opt_int, !value) ? start : realm::not_found;
112+
}
113+
107114
QueryStateFindFirst state;
108115
find_impl<cond>(value, start, end, &state);
109116

110-
if (state.match_count() > 0)
111-
return to_size_t(state.m_state);
112-
else
113-
return not_found;
117+
return static_cast<size_t>(state.m_state);
114118
}
115119

116120
template <class cond>

src/realm/query_engine.hpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -577,11 +577,6 @@ class IntegerNode<LeafType, Equal> : public IntegerNodeBase<LeafType> {
577577
else if (m_index_evaluator) {
578578
return m_index_evaluator->do_search_index(BaseType::m_cluster, start, end);
579579
}
580-
else if (end - start == 1) {
581-
if (this->m_leaf->get(start) == this->m_value) {
582-
s = start;
583-
}
584-
}
585580
else {
586581
s = this->m_leaf->template find_first<Equal>(this->m_value, start, end);
587582
}

test/test_query.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -706,17 +706,18 @@ TEST(Query_NextGenSyntaxMonkey0)
706706
}
707707
}
708708

709-
TEST(Query_NextGenSyntaxMonkey)
709+
TEST_TYPES(Query_NextGenSyntaxMonkey, std::true_type, std::false_type)
710710
{
711+
static const bool nullable = TEST_TYPE::value;
711712
Random random(random_int<unsigned long>()); // Seed from slow global generator
712713
for (int iter = 1; iter < 5 * (TEST_DURATION * TEST_DURATION * TEST_DURATION + 1); iter++) {
713714
// Set 'rows' to at least '* 20' else some tests will give 0 matches and bad coverage
714715
const size_t rows = 1 + random.draw_int_mod<size_t>(REALM_MAX_BPNODE_SIZE * 20 *
715716
(TEST_DURATION * TEST_DURATION * TEST_DURATION + 1));
716717
Table table;
717-
auto col_int0 = table.add_column(type_Int, "first");
718-
auto col_int1 = table.add_column(type_Int, "second");
719-
auto col_int2 = table.add_column(type_Int, "third");
718+
auto col_int0 = table.add_column(type_Int, "first", nullable);
719+
auto col_int1 = table.add_column(type_Int, "second", nullable);
720+
auto col_int2 = table.add_column(type_Int, "third", nullable);
720721

721722
for (size_t r = 0; r < rows; r++) {
722723
Obj obj = table.create_object();

test/util/test_path.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ bool initialize_test_path(int argc, const char* argv[])
148148
return false;
149149
}
150150
g_resource_path = File::resolve("resources", directory) + "/";
151-
g_path_prefix = directory;
151+
g_path_prefix = std::string(directory) + "/";
152152
#endif
153153

154154
if (argc > 0) {

0 commit comments

Comments
 (0)