Change realm::Schema to a vector rather than a map
Much faster to copy and destroy with no loss in lookup performance.
This commit is contained in:
parent
cae4cf2fc0
commit
e4377bb42a
|
@ -140,18 +140,24 @@ static inline bool property_has_changed(Property &p1, Property &p2) {
|
||||||
return p1.type != p2.type || p1.name != p2.name || p1.object_type != p2.object_type || p1.is_nullable != p2.is_nullable;
|
return p1.type != p2.type || p1.name != p2.name || p1.object_type != p2.object_type || p1.is_nullable != p2.is_nullable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool compare_by_name(ObjectSchema const& lft, ObjectSchema const& rgt) {
|
||||||
|
return lft.name < rgt.name;
|
||||||
|
}
|
||||||
|
|
||||||
void ObjectStore::verify_schema(Group *group, Schema &target_schema, bool allow_missing_tables) {
|
void ObjectStore::verify_schema(Group *group, Schema &target_schema, bool allow_missing_tables) {
|
||||||
|
std::sort(begin(target_schema), end(target_schema), compare_by_name);
|
||||||
|
|
||||||
std::vector<ObjectSchemaValidationException> errors;
|
std::vector<ObjectSchemaValidationException> errors;
|
||||||
for (auto &object_schema : target_schema) {
|
for (auto &object_schema : target_schema) {
|
||||||
if (!table_for_object_type(group, object_schema.first)) {
|
if (!table_for_object_type(group, object_schema.name)) {
|
||||||
if (!allow_missing_tables) {
|
if (!allow_missing_tables) {
|
||||||
errors.emplace_back(ObjectSchemaValidationException(object_schema.first,
|
errors.emplace_back(ObjectSchemaValidationException(object_schema.name,
|
||||||
"Missing table for object type '" + object_schema.first + "'."));
|
"Missing table for object type '" + object_schema.name + "'."));
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto more_errors = verify_object_schema(group, object_schema.second, target_schema);
|
auto more_errors = verify_object_schema(group, object_schema, target_schema);
|
||||||
errors.insert(errors.end(), more_errors.begin(), more_errors.end());
|
errors.insert(errors.end(), more_errors.begin(), more_errors.end());
|
||||||
}
|
}
|
||||||
if (errors.size()) {
|
if (errors.size()) {
|
||||||
|
@ -163,6 +169,12 @@ std::vector<ObjectSchemaValidationException> ObjectStore::verify_object_schema(G
|
||||||
std::vector<ObjectSchemaValidationException> exceptions;
|
std::vector<ObjectSchemaValidationException> exceptions;
|
||||||
ObjectSchema table_schema(group, target_schema.name);
|
ObjectSchema table_schema(group, target_schema.name);
|
||||||
|
|
||||||
|
ObjectSchema cmp;
|
||||||
|
auto schema_contains_table = [&](std::string const& name) {
|
||||||
|
cmp.name = name;
|
||||||
|
return std::binary_search(begin(schema), end(schema), cmp, compare_by_name);
|
||||||
|
};
|
||||||
|
|
||||||
// check to see if properties are the same
|
// check to see if properties are the same
|
||||||
Property *primary = nullptr;
|
Property *primary = nullptr;
|
||||||
for (auto& current_prop : table_schema.properties) {
|
for (auto& current_prop : table_schema.properties) {
|
||||||
|
@ -178,7 +190,7 @@ std::vector<ObjectSchemaValidationException> ObjectStore::verify_object_schema(G
|
||||||
}
|
}
|
||||||
|
|
||||||
// check object_type existence
|
// check object_type existence
|
||||||
if (current_prop.object_type.length() && schema.find(current_prop.object_type) == schema.end()) {
|
if (current_prop.object_type.length() && !schema_contains_table(current_prop.object_type)) {
|
||||||
exceptions.emplace_back(MissingObjectTypeException(table_schema.name, current_prop));
|
exceptions.emplace_back(MissingObjectTypeException(table_schema.name, current_prop));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,11 +261,11 @@ bool ObjectStore::create_tables(Group *group, Schema &target_schema, bool update
|
||||||
std::vector<ObjectSchema *> to_update;
|
std::vector<ObjectSchema *> to_update;
|
||||||
for (auto& object_schema : target_schema) {
|
for (auto& object_schema : target_schema) {
|
||||||
bool created = false;
|
bool created = false;
|
||||||
ObjectStore::table_for_object_type_create_if_needed(group, object_schema.first, created);
|
ObjectStore::table_for_object_type_create_if_needed(group, object_schema.name, created);
|
||||||
|
|
||||||
// we will modify tables for any new objectSchema (table was created) or for all if update_existing is true
|
// we will modify tables for any new objectSchema (table was created) or for all if update_existing is true
|
||||||
if (update_existing || created) {
|
if (update_existing || created) {
|
||||||
to_update.push_back(&object_schema.second);
|
to_update.push_back(&object_schema);
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,7 +341,7 @@ bool ObjectStore::realm_requires_update(Group *group, uint64_t version, Schema &
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (auto& target_schema : schema) {
|
for (auto& target_schema : schema) {
|
||||||
TableRef table = table_for_object_type(group, target_schema.first);
|
TableRef table = table_for_object_type(group, target_schema.name);
|
||||||
if (!table) {
|
if (!table) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -377,7 +389,7 @@ Schema ObjectStore::schema_from_group(Group *group) {
|
||||||
for (size_t i = 0; i < group->size(); i++) {
|
for (size_t i = 0; i < group->size(); i++) {
|
||||||
std::string object_type = object_type_for_table_name(group->get_table_name(i));
|
std::string object_type = object_type_for_table_name(group->get_table_name(i));
|
||||||
if (object_type.length()) {
|
if (object_type.length()) {
|
||||||
schema.emplace(object_type, std::move(ObjectSchema(group, object_type)));
|
schema.emplace_back(group, object_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return schema;
|
return schema;
|
||||||
|
@ -385,13 +397,13 @@ Schema ObjectStore::schema_from_group(Group *group) {
|
||||||
|
|
||||||
bool ObjectStore::indexes_are_up_to_date(Group *group, Schema &schema) {
|
bool ObjectStore::indexes_are_up_to_date(Group *group, Schema &schema) {
|
||||||
for (auto &object_schema : schema) {
|
for (auto &object_schema : schema) {
|
||||||
TableRef table = table_for_object_type(group, object_schema.first);
|
TableRef table = table_for_object_type(group, object_schema.name);
|
||||||
if (!table) {
|
if (!table) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_column_mapping(group, object_schema.second);
|
update_column_mapping(group, object_schema);
|
||||||
for (auto& property : object_schema.second.properties) {
|
for (auto& property : object_schema.properties) {
|
||||||
if (property.requires_index() != table->has_search_index(property.table_column)) {
|
if (property.requires_index() != table->has_search_index(property.table_column)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -403,12 +415,12 @@ bool ObjectStore::indexes_are_up_to_date(Group *group, Schema &schema) {
|
||||||
bool ObjectStore::update_indexes(Group *group, Schema &schema) {
|
bool ObjectStore::update_indexes(Group *group, Schema &schema) {
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
for (auto& object_schema : schema) {
|
for (auto& object_schema : schema) {
|
||||||
TableRef table = table_for_object_type(group, object_schema.first);
|
TableRef table = table_for_object_type(group, object_schema.name);
|
||||||
if (!table) {
|
if (!table) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& property : object_schema.second.properties) {
|
for (auto& property : object_schema.properties) {
|
||||||
if (property.requires_index() == table->has_search_index(property.table_column)) {
|
if (property.requires_index() == table->has_search_index(property.table_column)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -419,7 +431,7 @@ bool ObjectStore::update_indexes(Group *group, Schema &schema) {
|
||||||
table->add_search_index(property.table_column);
|
table->add_search_index(property.table_column);
|
||||||
}
|
}
|
||||||
catch (LogicError const&) {
|
catch (LogicError const&) {
|
||||||
throw PropertyTypeNotIndexableException(object_schema.first, property);
|
throw PropertyTypeNotIndexableException(object_schema.name, property);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -432,14 +444,14 @@ bool ObjectStore::update_indexes(Group *group, Schema &schema) {
|
||||||
|
|
||||||
void ObjectStore::validate_primary_column_uniqueness(Group *group, Schema &schema) {
|
void ObjectStore::validate_primary_column_uniqueness(Group *group, Schema &schema) {
|
||||||
for (auto& object_schema : schema) {
|
for (auto& object_schema : schema) {
|
||||||
auto primary_prop = object_schema.second.primary_key_property();
|
auto primary_prop = object_schema.primary_key_property();
|
||||||
if (!primary_prop) {
|
if (!primary_prop) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TableRef table = table_for_object_type(group, object_schema.first);
|
TableRef table = table_for_object_type(group, object_schema.name);
|
||||||
if (table->get_distinct_view(primary_prop->table_column).size() != table->size()) {
|
if (table->get_distinct_view(primary_prop->table_column).size() != table->size()) {
|
||||||
throw DuplicatePrimaryKeyValueException(object_schema.first, *primary_prop);
|
throw DuplicatePrimaryKeyValueException(object_schema.name, *primary_prop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#ifndef REALM_OBJECT_STORE_HPP
|
#ifndef REALM_OBJECT_STORE_HPP
|
||||||
#define REALM_OBJECT_STORE_HPP
|
#define REALM_OBJECT_STORE_HPP
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <realm/link_view.hpp>
|
#include <realm/link_view.hpp>
|
||||||
|
@ -30,8 +29,7 @@
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
class ObjectSchemaValidationException;
|
class ObjectSchemaValidationException;
|
||||||
class Schema : public std::map<std::string, ObjectSchema> {
|
using Schema = std::vector<ObjectSchema>;
|
||||||
};
|
|
||||||
|
|
||||||
class ObjectStore {
|
class ObjectStore {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -284,7 +284,7 @@ bool Realm::compact()
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &object_schema : *m_config.schema) {
|
for (auto &object_schema : *m_config.schema) {
|
||||||
ObjectStore::table_for_object_type(read_group(), object_schema.first)->optimize();
|
ObjectStore::table_for_object_type(read_group(), object_schema.name)->optimize();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_shared_group->end_read();
|
m_shared_group->end_read();
|
||||||
|
|
Loading…
Reference in New Issue