Skip to content

Commit

Permalink
Change realm::Schema to a vector rather than a map
Browse files Browse the repository at this point in the history
Much faster to copy and destroy with no loss in lookup performance.
  • Loading branch information
tgoyne committed Sep 9, 2015
1 parent cae4cf2 commit e4377bb
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 22 deletions.
48 changes: 30 additions & 18 deletions object_store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

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) {
std::sort(begin(target_schema), end(target_schema), compare_by_name);

std::vector<ObjectSchemaValidationException> errors;
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) {
errors.emplace_back(ObjectSchemaValidationException(object_schema.first,
"Missing table for object type '" + object_schema.first + "'."));
errors.emplace_back(ObjectSchemaValidationException(object_schema.name,
"Missing table for object type '" + object_schema.name + "'."));
}
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());
}
if (errors.size()) {
Expand All @@ -163,6 +169,12 @@ std::vector<ObjectSchemaValidationException> ObjectStore::verify_object_schema(G
std::vector<ObjectSchemaValidationException> exceptions;
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
Property *primary = nullptr;
for (auto& current_prop : table_schema.properties) {
Expand All @@ -178,7 +190,7 @@ std::vector<ObjectSchemaValidationException> ObjectStore::verify_object_schema(G
}

// 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));
}

Expand Down Expand Up @@ -249,11 +261,11 @@ bool ObjectStore::create_tables(Group *group, Schema &target_schema, bool update
std::vector<ObjectSchema *> to_update;
for (auto& object_schema : target_schema) {
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
if (update_existing || created) {
to_update.push_back(&object_schema.second);
to_update.push_back(&object_schema);
changed = true;
}
}
Expand Down Expand Up @@ -329,7 +341,7 @@ bool ObjectStore::realm_requires_update(Group *group, uint64_t version, Schema &
return true;
}
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) {
return true;
}
Expand Down Expand Up @@ -377,21 +389,21 @@ Schema ObjectStore::schema_from_group(Group *group) {
for (size_t i = 0; i < group->size(); i++) {
std::string object_type = object_type_for_table_name(group->get_table_name(i));
if (object_type.length()) {
schema.emplace(object_type, std::move(ObjectSchema(group, object_type)));
schema.emplace_back(group, object_type);
}
}
return schema;
}

bool ObjectStore::indexes_are_up_to_date(Group *group, 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) {
continue;
}

update_column_mapping(group, object_schema.second);
for (auto& property : object_schema.second.properties) {
update_column_mapping(group, object_schema);
for (auto& property : object_schema.properties) {
if (property.requires_index() != table->has_search_index(property.table_column)) {
return false;
}
Expand All @@ -403,12 +415,12 @@ bool ObjectStore::indexes_are_up_to_date(Group *group, Schema &schema) {
bool ObjectStore::update_indexes(Group *group, Schema &schema) {
bool changed = false;
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) {
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)) {
continue;
}
Expand All @@ -419,7 +431,7 @@ bool ObjectStore::update_indexes(Group *group, Schema &schema) {
table->add_search_index(property.table_column);
}
catch (LogicError const&) {
throw PropertyTypeNotIndexableException(object_schema.first, property);
throw PropertyTypeNotIndexableException(object_schema.name, property);
}
}
else {
Expand All @@ -432,14 +444,14 @@ bool ObjectStore::update_indexes(Group *group, Schema &schema) {

void ObjectStore::validate_primary_column_uniqueness(Group *group, 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) {
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()) {
throw DuplicatePrimaryKeyValueException(object_schema.first, *primary_prop);
throw DuplicatePrimaryKeyValueException(object_schema.name, *primary_prop);
}
}
}
Expand Down
4 changes: 1 addition & 3 deletions object_store.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
#ifndef REALM_OBJECT_STORE_HPP
#define REALM_OBJECT_STORE_HPP

#include <map>
#include <vector>
#include <functional>
#include <realm/link_view.hpp>
Expand All @@ -30,8 +29,7 @@

namespace realm {
class ObjectSchemaValidationException;
class Schema : public std::map<std::string, ObjectSchema> {
};
using Schema = std::vector<ObjectSchema>;

class ObjectStore {
public:
Expand Down
2 changes: 1 addition & 1 deletion shared_realm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ bool Realm::compact()
}

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();
Expand Down

0 comments on commit e4377bb

Please sign in to comment.