Skip to content

Commit

Permalink
Use std::optional to store cached leaves in query nodes (#6653)
Browse files Browse the repository at this point in the history
Our use of aligned_storage was basically a complicated manual version of this.
I was hoping this'd have binary size benefits, but it ended up making the
library 100 bytes larger instead. Nonetheless, it greatly simplifies things.
  • Loading branch information
tgoyne authored May 23, 2023
1 parent dcf925e commit 0ac57c5
Show file tree
Hide file tree
Showing 15 changed files with 223 additions and 465 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
-----------

### Internals
* None.
* Simplify the implementation of query expression nodes which have a btree leaf cache.

----------------------------------------------

Expand Down
1 change: 0 additions & 1 deletion src/realm/metrics/query_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include <realm/group.hpp>
#include <realm/table.hpp>
#include <realm/query.hpp>
#include <realm/query_engine.hpp>

using namespace realm;
using namespace realm::metrics;
Expand Down
1 change: 0 additions & 1 deletion src/realm/metrics/query_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

#include <memory>
#include <string>
#include <sstream>

#include <realm/array.hpp>
#include <realm/util/features.h>
Expand Down
17 changes: 15 additions & 2 deletions src/realm/query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,14 @@
#include <realm/query.hpp>

#include <realm/array.hpp>
#include <realm/column_fwd.hpp>
#include <realm/array_integer_tpl.hpp>
#include <realm/transaction.hpp>
#include <realm/dictionary.hpp>
#include <realm/query_conditions_tpl.hpp>
#include <realm/query_engine.hpp>
#include <realm/query_expression.hpp>
#include <realm/table_view.hpp>
#include <realm/set.hpp>
#include <realm/array_integer_tpl.hpp>

#include <algorithm>

Expand Down Expand Up @@ -1056,6 +1055,20 @@ size_t Query::find_best_node(ParentNode* pn) const
void Query::aggregate_internal(ParentNode* pn, QueryStateBase* st, size_t start, size_t end,
ArrayPayload* source_column) const
{
// Number of matches to find in best condition loop before breaking out to probe other conditions. Too low value
// gives too many constant time overheads everywhere in the query engine. Too high value makes it adapt less
// rapidly to changes in match frequencies.
constexpr size_t findlocals = 64;

// Average match distance in linear searches where further increase in distance no longer increases query speed
// (because time spent on handling each match becomes insignificant compared to time spent on the search).
constexpr size_t bestdist = 512;

// Minimum number of matches required in a certain condition before it can be used to compute statistics. Too high
// value can spent too much time in a bad node (with high match frequency). Too low value gives inaccurate
// statistics.
constexpr size_t probe_matches = 4;

while (start < end) {
// Executes start...end range of a query and will stay inside the condition loop of the node it was called
// on. Can be called on any node; yields same result, but different performance. Returns prematurely if
Expand Down
19 changes: 9 additions & 10 deletions src/realm/query.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,28 +35,27 @@
#endif

#include <realm/aggregate_ops.hpp>
#include <realm/obj_list.hpp>
#include <realm/table_ref.hpp>
#include <realm/binary_data.hpp>
#include <realm/timestamp.hpp>
#include <realm/column_type_traits.hpp>
#include <realm/handover_defs.hpp>
#include <realm/util/serializer.hpp>
#include <realm/obj_list.hpp>
#include <realm/table_ref.hpp>
#include <realm/util/bind_ptr.hpp>
#include <realm/column_type_traits.hpp>
#include <realm/util/serializer.hpp>

namespace realm {


// Pre-declarations
class ParentNode;
class Table;
class TableView;
class TableView;
class Array;
class Expression;
class Group;
class Transaction;
class LinkMap;
class ParentNode;
class Table;
class TableView;
class Timestamp;
class Transaction;

namespace metrics {
class QueryInfo;
Expand Down
25 changes: 12 additions & 13 deletions src/realm/query_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ size_t MixedNode<Equal>::find_first_local(size_t start, size_t end)
return m_index_evaluator->do_search_index(m_cluster, start, end);
}
else {
return m_leaf_ptr->find_first(m_value, start, end);
return m_leaf->find_first(m_value, start, end);
}

return not_found;
Expand Down Expand Up @@ -246,7 +246,7 @@ size_t MixedNode<EqualIns>::find_first_local(size_t start, size_t end)
EqualIns cond;
if (m_value.is_type(type_String)) {
for (size_t i = start; i < end; i++) {
QueryValue val(m_leaf_ptr->get(i));
QueryValue val(m_leaf->get(i));
StringData val_as_str;
if (val.is_type(type_String)) {
val_as_str = val.get<StringData>();
Expand All @@ -261,7 +261,7 @@ size_t MixedNode<EqualIns>::find_first_local(size_t start, size_t end)
}
else {
for (size_t i = start; i < end; i++) {
QueryValue val(m_leaf_ptr->get(i));
QueryValue val(m_leaf->get(i));
if (cond(val, m_value))
return i;
}
Expand Down Expand Up @@ -416,13 +416,13 @@ bool StringNode<Equal>::do_consume_condition(ParentNode& node)
size_t StringNode<Equal>::_find_first_local(size_t start, size_t end)
{
if (m_needles.empty()) {
return m_leaf_ptr->find_first(m_value, start, end);
return m_leaf->find_first(m_value, start, end);
}
else {
if (end == npos)
end = m_leaf_ptr->size();
end = m_leaf->size();
REALM_ASSERT_3(start, <=, end);
return find_first_haystack<20>(*m_leaf_ptr, m_needles, start, end);
return find_first_haystack<20>(*m_leaf, m_needles, start, end);
}
}

Expand Down Expand Up @@ -826,7 +826,7 @@ size_t LinksToNode<Equal>::find_first_local(size_t start, size_t end)

BPlusTree<ObjKey> links(m_table.unchecked_ptr()->get_alloc());
for (size_t i = start; i < end; i++) {
if (ref_type ref = LinkMap::get_ref(m_leaf_ptr, m_column_type, i)) {
if (ref_type ref = get_ref(i)) {
links.init_from_ref(ref);
for (auto& key : m_target_keys) {
if (key) {
Expand All @@ -837,9 +837,9 @@ size_t LinksToNode<Equal>::find_first_local(size_t start, size_t end)
}
}
}
else if (m_column_type == col_type_Link) {
else if (m_list) {
for (auto& key : m_target_keys) {
auto pos = static_cast<const ArrayKey*>(m_leaf_ptr)->find_first(key, start, end);
auto pos = m_list->find_first(key, start, end);
if (pos != realm::npos) {
return pos;
}
Expand All @@ -859,7 +859,7 @@ size_t LinksToNode<NotEqual>::find_first_local(size_t start, size_t end)
if (m_column_type == col_type_LinkList || m_condition_column_key.is_set()) {
BPlusTree<ObjKey> links(m_table.unchecked_ptr()->get_alloc());
for (size_t i = start; i < end; i++) {
if (ref_type ref = LinkMap::get_ref(m_leaf_ptr, m_column_type, i)) {
if (ref_type ref = get_ref(i)) {
links.init_from_ref(ref);
auto sz = links.size();
for (size_t j = 0; j < sz; j++) {
Expand All @@ -870,10 +870,9 @@ size_t LinksToNode<NotEqual>::find_first_local(size_t start, size_t end)
}
}
}
else if (m_column_type == col_type_Link) {
auto leaf = static_cast<const ArrayKey*>(m_leaf_ptr);
else if (m_list) {
for (size_t i = start; i < end; i++) {
if (leaf->get(i) != key) {
if (m_list->get(i) != key) {
return i;
}
}
Expand Down
Loading

0 comments on commit 0ac57c5

Please sign in to comment.