Skip to content

Commit

Permalink
fix handling for array mixed when it holds strings
Browse files Browse the repository at this point in the history
  • Loading branch information
nicola-cab committed Jul 18, 2024
1 parent d94c474 commit 87b3d1a
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 19 deletions.
16 changes: 16 additions & 0 deletions src/realm/array_mixed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,22 @@ void ArrayMixed::set_null(size_t ndx)
}
}

std::optional<StringID> ArrayMixed::get_string_id(size_t ndx) const
{
int64_t val = m_composite.get(ndx);
if (val) {
int64_t int_val = val >> s_data_shift;
size_t payload_ndx = size_t(int_val);
DataType type = DataType((val & s_data_type_mask) - 1);
if (type == type_String) {
ensure_string_array();
REALM_ASSERT(size_t(int_val) < m_strings.size());
return m_strings.get_string_id(payload_ndx);
}
}
return {};
}

Mixed ArrayMixed::get(size_t ndx) const
{
int64_t val = m_composite.get(ndx);
Expand Down
1 change: 1 addition & 0 deletions src/realm/array_mixed.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class ArrayMixed : public ArrayPayload, private Array {
{
return m_composite.get(ndx) == 0;
}
std::optional<StringID> get_string_id(size_t ndx) const;

void clear();
void erase(size_t ndx);
Expand Down
3 changes: 1 addition & 2 deletions src/realm/array_string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,7 @@ std::optional<StringID> ArrayString::get_string_id(size_t ndx) const
if (m_type == Type::interned_strings) {
return StringID(static_cast<Array*>(m_arr)->get(ndx));
}
return {};
// return m_string_interner->lookup(get(ndx));
return m_string_interner->lookup(get(ndx));
}

Mixed ArrayString::get_any(size_t ndx) const
Expand Down
22 changes: 13 additions & 9 deletions src/realm/obj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -632,27 +632,31 @@ BinaryData Obj::_get<BinaryData>(ColKey::Idx col_ndx) const
std::optional<StringID> Obj::get_compressed_string(ColKey col_key) const
{
// only strings and mixed can have an interner
if (col_key.get_type() != col_type_String && col_key.get_type() != col_type_Mixed)
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();
const auto interner = m_table->get_string_interner(col_ndx);
ref_type ref = to_ref(Array::get(m_mem.get_addr(), col_ndx.val + 1));

auto& alloc = _get_alloc();
auto current_version = alloc.get_storage_version();
if (current_version != m_storage_version) {
update();
if (col_key.get_type() == col_type_Mixed) {
// mixed handling. Only strings in mixed may have a string id
ArrayMixed values(get_alloc());
values.set_string_interner(interner);
values.init_from_ref(ref);
return values.get_string_id(m_row_ndx);
}

ref_type ref = to_ref(Array::get(m_mem.get_addr(), col_ndx.val + 1));
// must be string.
ArrayString values(get_alloc());
const auto interner = m_table->get_string_interner(col_key);
values.set_string_interner(interner);
values.init_from_ref(ref);
return values.get_string_id(m_row_ndx);
}


Mixed Obj::get_any(ColKey col_key) const
{
m_table->check_column(col_key);
Expand Down
7 changes: 4 additions & 3 deletions src/realm/path.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,10 @@ class ExtendedColumnKey {
ObjKey get_link_target(const Obj& obj) const;
Mixed get_value(const Obj& obj) const;

// get compressed string view for the obj, it makes sense to call this method only
// if the col_key type is either Mixed or String.
std::optional<size_t> get_compressed_string_id(const Obj& obj) const;
// get String ID for the obj, it makes sense to call this method only if the col_key type is either Mixed or
// String.
using StringID = size_t;
std::optional<StringID> get_string_id(const Obj& obj) const;

private:
ColKey m_colkey;
Expand Down
16 changes: 11 additions & 5 deletions src/realm/sort_descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,15 @@ Mixed ExtendedColumnKey::get_value(const Obj& obj) const
return {};
}

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

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

return {};
}

LinkPathPart::LinkPathPart(ColKey col_key, ConstTableRef source)
Expand Down Expand Up @@ -471,7 +477,7 @@ 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.cached_string_id = col_key.get_compressed_string_id(obj);
cache_i.cached_string_id = col_key.get_string_id(obj);
if (cache_i.cached_string_id) {
cache_i.value = {};
}
Expand All @@ -486,7 +492,7 @@ 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_j.cached_string_id = col_key.get_compressed_string_id(obj);
cache_j.cached_string_id = col_key.get_string_id(obj);
if (cache_j.cached_string_id) {
cache_j.value = {};
}
Expand Down Expand Up @@ -527,7 +533,7 @@ void BaseDescriptor::Sorter::cache_first_column(IndexPairs& v)
}

const auto obj = col.table->get_object(key);
const auto string_id = ck.get_compressed_string_id(obj);
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) {
Expand Down

0 comments on commit 87b3d1a

Please sign in to comment.