Skip to content

Commit

Permalink
Actually store collection type in Mixed (#6583)
Browse files Browse the repository at this point in the history
  • Loading branch information
jedelbo committed May 9, 2023
1 parent d7817a9 commit 29e70dd
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 59 deletions.
27 changes: 15 additions & 12 deletions src/realm/collection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ std::pair<std::string, std::string> CollectionBase::get_open_close_strings(size_
{
std::string open_str;
std::string close_str;
auto ck = get_col_key();
auto collection_type = get_collection_type();
Table* target_table = get_target_table().unchecked_ptr();
auto ck = get_col_key();
auto type = ck.get_type();
if (type == col_type_LinkList)
type = col_type_Link;
Expand All @@ -107,29 +108,31 @@ std::pair<std::string, std::string> CollectionBase::get_open_close_strings(size_

if (output_mode == output_mode_xjson_plus) {
open_str = std::string("{ ") + (is_embedded ? "\"$embedded" : "\"$link");
open_str += collection_type_name(ck, true);
open_str += collection_type_name(collection_type, true);
open_str += "\": ";
close_str += " }";
}

if ((link_depth_reached && output_mode != output_mode_xjson) || output_mode == output_mode_xjson_plus) {
open_str += "{ \"table\": \"" + std::string(target_table->get_name()) + "\", ";
open_str += ((is_embedded || ck.is_dictionary()) ? "\"value" : "\"key");
if (ck.is_collection())
open_str += "s";
open_str += ((is_embedded || collection_type == CollectionType::Dictionary) ? "\"values" : "\"keys");
open_str += "\": ";
close_str += "}";
}
}
else {
if (output_mode == output_mode_xjson_plus) {
if (ck.is_set()) {
open_str = "{ \"$set\": ";
close_str = " }";
}
else if (ck.is_dictionary()) {
open_str = "{ \"$dictionary\": ";
close_str = " }";
switch (collection_type) {
case CollectionType::List:
break;
case CollectionType::Set:
open_str = "{ \"$set\": ";
close_str = " }";
break;
case CollectionType::Dictionary:
open_str = "{ \"$dictionary\": ";
close_str = " }";
break;
}
}
}
Expand Down
30 changes: 20 additions & 10 deletions src/realm/collection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ class CollectionBase : public Collection {
/// the internal state of the accessor if it has changed.
virtual bool has_changed() const noexcept = 0;

/// Get collection type (set, list, dictionary)
virtual CollectionType get_collection_type() const noexcept = 0;

/// Returns true if the accessor is in the attached state. By default, this
/// checks if the owning object is still valid.
virtual bool is_attached() const
Expand Down Expand Up @@ -154,21 +157,23 @@ class CollectionBase : public Collection {
std::pair<std::string, std::string> get_open_close_strings(size_t link_depth, JSONOutputMode output_mode) const;
};

inline std::string_view collection_type_name(ColKey col, bool uppercase = false)
inline std::string_view collection_type_name(CollectionType col_type, bool uppercase = false)
{
if (col.is_list())
return uppercase ? "List" : "list";
if (col.is_set())
return uppercase ? "Set" : "set";
if (col.is_dictionary())
return uppercase ? "Dictionary" : "dictionary";
switch (col_type) {
case CollectionType::List:
return uppercase ? "List" : "list";
case CollectionType::Set:
return uppercase ? "Set" : "set";
case CollectionType::Dictionary:
return uppercase ? "Dictionary" : "dictionary";
}
return "";
}

inline void CollectionBase::validate_index(const char* msg, size_t index, size_t size) const
{
if (index >= size) {
throw OutOfBounds(util::format("%1 on %2 '%3.%4'", msg, collection_type_name(get_col_key()),
throw OutOfBounds(util::format("%1 on %2 '%3.%4'", msg, collection_type_name(get_collection_type()),
get_table()->get_class_name(), get_property_name()),
index, size);
}
Expand Down Expand Up @@ -382,6 +387,11 @@ class CollectionBaseImpl : public Interface, protected ArrayParent {
return false;
}

CollectionType get_collection_type() const noexcept override
{
return Interface::s_collection_type;
}

void set_owner(const Obj& obj, ColKey ck) override
{
m_obj_mem = obj;
Expand Down Expand Up @@ -471,7 +481,7 @@ class CollectionBaseImpl : public Interface, protected ArrayParent {
ref_type get_collection_ref() const noexcept
{
try {
return m_parent->get_collection_ref(m_index);
return m_parent->get_collection_ref(m_index, Interface::s_collection_type);
}
catch (const KeyNotFound&) {
return ref_type(0);
Expand All @@ -480,7 +490,7 @@ class CollectionBaseImpl : public Interface, protected ArrayParent {

void set_collection_ref(ref_type ref)
{
m_parent->set_collection_ref(m_index, ref);
m_parent->set_collection_ref(m_index, ref, Interface::s_collection_type);
}

UpdateStatus get_update_status() const noexcept
Expand Down
44 changes: 22 additions & 22 deletions src/realm/collection_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ CollectionList::CollectionList(std::shared_ptr<CollectionParent> parent, ColKey
, m_col_key(col_key)
, m_top(*m_alloc)
, m_refs(*m_alloc)
, m_key_type(coll_type == CollectionType::List ? type_Int : type_String)
, m_coll_type(coll_type)
{
m_top.set_parent(this, 0);
m_refs.set_parent(&m_top, 1);
Expand All @@ -51,7 +51,7 @@ CollectionList::CollectionList(CollectionParent* obj, ColKey col_key)
, m_col_key(col_key)
, m_top(*m_alloc)
, m_refs(*m_alloc)
, m_key_type(get_table()->get_nested_column_type(col_key, 0) == CollectionType::List ? type_Int : type_String)
, m_coll_type(get_table()->get_nested_column_type(col_key, 0))
{
m_top.set_parent(this, 0);
m_refs.set_parent(&m_top, 1);
Expand All @@ -61,14 +61,14 @@ CollectionList::~CollectionList() {}

bool CollectionList::init_from_parent(bool allow_create) const
{
auto ref = m_parent->get_collection_ref(m_index);
auto ref = m_parent->get_collection_ref(m_index, m_coll_type);
if ((ref || allow_create) && !m_keys) {
switch (m_key_type) {
case type_String: {
switch (m_coll_type) {
case CollectionType::Dictionary: {
m_keys.reset(new BPlusTree<StringData>(*m_alloc));
break;
}
case type_Int: {
case CollectionType::List: {
m_keys.reset(new BPlusTree<Int>(*m_alloc));
break;
}
Expand Down Expand Up @@ -170,19 +170,19 @@ bool CollectionList::update_if_needed() const

ref_type CollectionList::get_child_ref(size_t) const noexcept
{
return m_parent->get_collection_ref(m_col_key);
return m_parent->get_collection_ref(m_col_key, m_coll_type);
}

void CollectionList::update_child_ref(size_t, ref_type ref)
{
m_parent->set_collection_ref(m_index, ref);
m_parent->set_collection_ref(m_index, ref, m_coll_type);
}

CollectionBasePtr CollectionList::insert_collection(size_t ndx)
{
REALM_ASSERT(get_table()->get_nesting_levels(m_col_key) == m_level);
ensure_created();
REALM_ASSERT(m_key_type == type_Int);
REALM_ASSERT(m_coll_type == CollectionType::List);
auto int_keys = static_cast<BPlusTree<Int>*>(m_keys.get());
int64_t key = 0;
if (auto max = bptree_maximum(*int_keys, nullptr)) {
Expand All @@ -202,7 +202,7 @@ CollectionBasePtr CollectionList::insert_collection(StringData key)
{
REALM_ASSERT(get_table()->get_nesting_levels(m_col_key) == m_level);
ensure_created();
REALM_ASSERT(m_key_type == type_String);
REALM_ASSERT(m_coll_type == CollectionType::Dictionary);
auto string_keys = static_cast<BPlusTree<String>*>(m_keys.get());
StringData actual;
IteratorAdapter help(string_keys);
Expand Down Expand Up @@ -231,7 +231,7 @@ CollectionBasePtr CollectionList::get_collection(size_t ndx) const
if (ndx >= sz) {
throw OutOfBounds("CollectionList::get_collection_ptr()", ndx, sz);
}
if (m_key_type == type_Int) {
if (m_coll_type == CollectionType::List) {
auto int_keys = static_cast<BPlusTree<Int>*>(m_keys.get());
index = int_keys->get(ndx);
}
Expand All @@ -246,7 +246,7 @@ CollectionBasePtr CollectionList::get_collection(size_t ndx) const
CollectionListPtr CollectionList::insert_collection_list(size_t ndx)
{
ensure_created();
REALM_ASSERT(m_key_type == type_Int);
REALM_ASSERT(m_coll_type == CollectionType::List);
auto int_keys = static_cast<BPlusTree<Int>*>(m_keys.get());
int64_t key = 0;
if (auto max = bptree_maximum(*int_keys, nullptr)) {
Expand All @@ -263,7 +263,7 @@ CollectionListPtr CollectionList::insert_collection_list(size_t ndx)
CollectionListPtr CollectionList::insert_collection_list(StringData key)
{
ensure_created();
REALM_ASSERT(m_key_type == type_String);
REALM_ASSERT(m_coll_type == CollectionType::Dictionary);
auto string_keys = static_cast<BPlusTree<String>*>(m_keys.get());
StringData actual;
IteratorAdapter help(string_keys);
Expand All @@ -289,7 +289,7 @@ CollectionListPtr CollectionList::get_collection_list(size_t ndx) const
if (ndx >= sz) {
throw OutOfBounds("CollectionList::get_collection_ptr()", ndx, sz);
}
if (m_key_type == type_Int) {
if (m_coll_type == CollectionType::List) {
auto int_keys = static_cast<BPlusTree<Int>*>(m_keys.get());
index = int_keys->get(ndx);
}
Expand All @@ -303,7 +303,7 @@ CollectionListPtr CollectionList::get_collection_list(size_t ndx) const

void CollectionList::remove(size_t ndx)
{
REALM_ASSERT(m_key_type == type_Int);
REALM_ASSERT(m_coll_type == CollectionType::List);
auto int_keys = static_cast<BPlusTree<Int>*>(m_keys.get());
const auto sz = int_keys->size();
if (ndx >= sz) {
Expand Down Expand Up @@ -331,7 +331,7 @@ void CollectionList::remove(size_t ndx)

void CollectionList::remove(StringData key)
{
REALM_ASSERT(m_key_type == type_String);
REALM_ASSERT(m_coll_type == CollectionType::Dictionary);
auto string_keys = static_cast<BPlusTree<String>*>(m_keys.get());
IteratorAdapter help(string_keys);
auto it = std::lower_bound(help.begin(), help.end(), key);
Expand All @@ -347,10 +347,10 @@ void CollectionList::remove(StringData key)
bump_content_version();
}

ref_type CollectionList::get_collection_ref(Index index) const noexcept
ref_type CollectionList::get_collection_ref(Index index, CollectionType) const noexcept
{
size_t ndx;
if (m_key_type == type_Int) {
if (m_coll_type == CollectionType::List) {
auto int_keys = static_cast<BPlusTree<Int>*>(m_keys.get());
ndx = int_keys->find_first(mpark::get<int64_t>(index));
}
Expand All @@ -361,10 +361,10 @@ ref_type CollectionList::get_collection_ref(Index index) const noexcept
return ndx == realm::not_found ? 0 : m_refs.get(ndx);
}

void CollectionList::set_collection_ref(Index index, ref_type ref)
void CollectionList::set_collection_ref(Index index, ref_type ref, CollectionType)
{
size_t ndx;
if (m_key_type == type_Int) {
if (m_coll_type == CollectionType::List) {
auto int_keys = static_cast<BPlusTree<Int>*>(m_keys.get());
ndx = int_keys->find_first(mpark::get<int64_t>(index));
}
Expand All @@ -380,7 +380,7 @@ void CollectionList::set_collection_ref(Index index, ref_type ref)

auto CollectionList::get_index(size_t ndx) const noexcept -> Index
{
if (m_key_type == type_Int) {
if (m_coll_type == CollectionType::List) {
auto int_keys = static_cast<BPlusTree<Int>*>(m_keys.get());
return int_keys->get(ndx);
}
Expand Down Expand Up @@ -431,7 +431,7 @@ void CollectionList::to_json(std::ostream& out, size_t link_depth, JSONOutputMod
util::FunctionRef<void(const Mixed&)> fn) const
{
bool is_leaf = m_level == get_table()->get_nesting_levels(m_col_key);
bool is_dictionary = m_key_type == type_String;
bool is_dictionary = m_coll_type == CollectionType::Dictionary;
auto sz = size();
auto string_keys = static_cast<BPlusTree<String>*>(m_keys.get());

Expand Down
6 changes: 3 additions & 3 deletions src/realm/collection_list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ class CollectionList final : public Collection,

Index get_index(size_t ndx) const noexcept;

ref_type get_collection_ref(Index index) const noexcept final;
void set_collection_ref(Index index, ref_type ref) final;
ref_type get_collection_ref(Index index, CollectionType) const noexcept final;
void set_collection_ref(Index index, ref_type ref, CollectionType) final;

// If this list is at the outermost nesting level, use these functions to
// get the leaf collections
Expand Down Expand Up @@ -112,7 +112,7 @@ class CollectionList final : public Collection,
mutable Array m_top;
mutable std::unique_ptr<BPlusTreeBase> m_keys;
mutable BPlusTree<ref_type> m_refs;
DataType m_key_type;
CollectionType m_coll_type;
mutable uint_fast64_t m_content_version = 0;


Expand Down
10 changes: 5 additions & 5 deletions src/realm/collection_parent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@ class CollectionParent {
/// Get owning object
virtual const Obj& get_object() const noexcept = 0;
/// Get the top ref from pareht
virtual ref_type get_collection_ref(Index) const noexcept = 0;
/// Set the top ref from pareht
virtual void set_collection_ref(Index, ref_type ref) = 0;
virtual ref_type get_collection_ref(Index, CollectionType) const = 0;
/// Set the top ref in parent
virtual void set_collection_ref(Index, ref_type ref, CollectionType) = 0;

// Used when inserting a new link. You will not remove existing links in this process
void set_backlink(ColKey col_key, ObjLink new_link) const;
Expand Down Expand Up @@ -145,11 +145,11 @@ class DummyParent : public CollectionParent {
return true;
}
const Obj& get_object() const noexcept final;
ref_type get_collection_ref(Index) const noexcept final
ref_type get_collection_ref(Index, CollectionType) const final
{
return m_ref;
}
void set_collection_ref(Index, ref_type) {}
void set_collection_ref(Index, ref_type, CollectionType) {}
};

} // namespace realm
Expand Down
4 changes: 4 additions & 0 deletions src/realm/dictionary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,10 @@ class DictionaryLinkValues final : public ObjCollectionBase<CollectionBase> {
{
return m_source.has_changed();
}
CollectionType get_collection_type() const noexcept override
{
return CollectionType::List;

This comment has been minimized.

Copy link
@nicola-cab

nicola-cab May 9, 2023

Member

This is a type list because is equivalent to a list of links ... right? This is not a mistake...

}

// Overrides of ObjCollectionBase:
UpdateStatus do_update_if_needed() const final
Expand Down
5 changes: 5 additions & 0 deletions src/realm/list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class LstBase : public CollectionBase {
virtual void swap(size_t ndx1, size_t ndx2) = 0;

protected:
static constexpr CollectionType s_collection_type = CollectionType::List;
void swap_repl(Replication* repl, size_t ndx1, size_t ndx2) const;
};

Expand Down Expand Up @@ -399,6 +400,10 @@ class LnkLst final : public ObjCollectionBase<LstBase> {
const Obj& get_obj() const noexcept final;
bool has_changed() const noexcept final;
ColKey get_col_key() const noexcept final;
CollectionType get_collection_type() const noexcept override
{
return CollectionType::List;
}

// Overriding members of LstBase:
std::unique_ptr<LstBase> clone() const override
Expand Down
Loading

0 comments on commit 29e70dd

Please sign in to comment.