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:
Thomas Goyne 2015-08-26 15:07:15 -07:00 committed by Ari Lazier
parent d2a74958f0
commit 1d25766ebb
3 changed files with 32 additions and 22 deletions

View File

@ -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;
} }
} }
@ -330,7 +342,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;
} }
@ -378,7 +390,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;
@ -386,13 +398,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;
} }
@ -404,12 +416,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;
} }
@ -420,7 +432,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 {
@ -433,14 +445,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);
} }
} }
} }

View File

@ -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:

View File

@ -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();