Skip to content

Commit

Permalink
works for strings
Browse files Browse the repository at this point in the history
  • Loading branch information
nicola-cab committed Jul 19, 2024
1 parent 7d62244 commit 88f9194
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 20 deletions.
7 changes: 4 additions & 3 deletions src/realm/obj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -629,14 +629,15 @@ BinaryData Obj::_get<BinaryData>(ColKey::Idx col_ndx) const
return ArrayBinary::get(alloc.translate(ref), m_row_ndx, alloc);
}

std::optional<StringID> Obj::get_compressed_string(ColKey col_key) const
std::optional<StringID> Obj::get_string_id(ColKey col_key) const
{
// we may hit this only if the property is a string or mixed.
m_table->check_column(col_key);

// only strings and mixed can have an interner
if (col_key.get_type() != col_type_Mixed && col_key.get_type() != col_type_String)
return {};

// we may hit this only if the property is a string or mixed.
m_table->check_column(col_key);
_update_if_needed();

const auto col_ndx = col_key.get_index();
Expand Down
6 changes: 3 additions & 3 deletions src/realm/obj.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,10 @@ class Obj {
U get(ColKey col_key) const;

using StringID = size_t;
std::optional<StringID> get_compressed_string(ColKey) const;
std::optional<StringID> get_compressed_string(StringData col_name) const
std::optional<StringID> get_string_id(ColKey) const;
std::optional<StringID> get_string_id(StringData col_name) const
{
return get_compressed_string(get_column_key(col_name));
return get_string_id(get_column_key(col_name));
}
Mixed get_any(ColKey col_key) const;
Mixed get_any(StringData col_name) const
Expand Down
43 changes: 29 additions & 14 deletions src/realm/sort_descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@ Mixed ExtendedColumnKey::get_value(const Obj& obj) const

std::optional<StringID> ExtendedColumnKey::get_string_id(const Obj& obj) const
{
if (m_colkey.get_type() != col_type_String && m_colkey.get_type() != col_type_Mixed)
if (m_colkey.get_type() != col_type_String)
return {};

if (!has_index())
return obj.get_compressed_string(m_colkey);
return obj.get_string_id(m_colkey);

return {};
}
Expand Down Expand Up @@ -408,15 +408,27 @@ inline int compare(const T& i, const T& j, const U& col)
{
const ColKey col_key{col.col_key};
const auto table = col.table;
const auto has_interner = col_key.get_type() == col_type_Mixed || col_key.get_type() == col_type_String;
const auto has_interner = col_key.get_type() == col_type_String;

if (has_interner) {
const auto id_i = i.cached_string_id;
const auto id_j = j.cached_string_id;
const auto interner = table->get_string_interner(col_key);
if (id_i && id_j) {
const auto interner = table->get_string_interner(col_key);
return interner->compare(*id_i, *id_j);
}
else if (id_j) {
const auto str = i.get_value().template get_if<StringData>();
if (str)
return interner->compare(*str, *id_j);
}
else {
const auto str = j.get_value().template get_if<StringData>();
if (str)
// reverse result. EG -1 means that J is < than I (then I > J), thus return 1, since we are comparing
// I vs J.
return -interner->compare(*str, *id_i);
}
}
return i.get_value().compare(j.get_value());
}
Expand Down Expand Up @@ -464,23 +476,25 @@ bool BaseDescriptor::Sorter::operator()(IndexPair i, IndexPair j, bool total_ord
const auto& col_key = m_columns[t].col_key;

// store stringID instead of the actual string if possible
cache_i.key = key_i;
cache_i.cached_string_id = col_key.get_string_id(obj);
if (!cache_i.cached_string_id) {
if (!cache_i.cached_string_id)
cache_i.value = col_key.get_value(obj);
}
cache_i.key = key_i;
else
cache_j.value = {};
}

if (cache_j.key != key_j) {
const auto& obj = m_columns[t].table->get_object(key_j);
const auto& col_key = m_columns[t].col_key;

// store stringID instead of the actual string if possible
cache_j.key = key_j;
cache_j.cached_string_id = col_key.get_string_id(obj);
if (!cache_j.cached_string_id) {
if (!cache_j.cached_string_id)
cache_j.value = col_key.get_value(obj);
}
cache_j.key = key_j;
else
cache_j.value = {};
}

c = compare(cache_i, cache_j, m_columns[t]);
Expand Down Expand Up @@ -514,11 +528,12 @@ void BaseDescriptor::Sorter::cache_first_column(IndexPairs& v)
}

const auto obj = col.table->get_object(key);
const auto string_id = ck.get_string_id(obj);
// avoid to decompress the whole string if the col_key is String or Mixed type and the underline string is
// compressed.
if (string_id) {
const auto col_type = ColKey{ck}.get_type();
const auto can_be_compressed = col_type == col_type_String;

if (const auto string_id = ck.get_string_id(obj); can_be_compressed && string_id) {
index.cached_string_id = *string_id;
index.cached_value = {};
}
else {
index.cached_value = ck.get_value(obj);
Expand Down

0 comments on commit 88f9194

Please sign in to comment.