-
Type: Task
-
Resolution: Unresolved
-
Priority: Minor - P4
-
None
-
Affects Version/s: None
-
Component/s: None
-
2 - S (<= 1 week)
-
1004
Hi,
Like issue #328 (pull req: #472), could we have some faster ways to get first object by non-primary key property value? With little knowledge about C++, I have changed object_for_primary_key to something like following and works great for indexed property.
js_realm.hpp:
void RealmClass<T>::object_for_primary_key(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) { SharedRealm realm = *get_internal<T, RealmClass<T>>(this_object); std::string object_type; auto &object_schema = validated_object_schema_for_value(ctx, realm, arguments[0], object_type); realm::TableRef table = ObjectStore::table_for_object_type(realm->read_group(), object_schema.name); auto arg1 = arguments[1]; auto prop_name = NativeAccessor::to_string(ctx, arg1); auto primary_prop = object_schema.property_for_name(prop_name); realm::Object realm_object; if (argc > 2) { auto arg2 = arguments[2]; auto arg3 = arguments[3]; std::string str_string ("string"); std::string str_int ("int"); std::string str_long ("long"); std::string str_float ("float"); std::string str_double ("double"); std::string str_binary ("binary"); std::string str_timestamp ("timestamp"); std::string str_bool ("bool"); auto type_string = NativeAccessor::to_string(ctx, arg2); size_t row_index; if (type_string.compare(str_string) == 0){ auto primary_string = NativeAccessor::to_string(ctx, arg3); row_index = table->find_first_string(primary_prop->table_column, primary_string); } else if (type_string.compare(str_int) == 0 || type_string.compare(str_long) == 0){ auto primary_string = NativeAccessor::to_long(ctx, arg3); row_index = table->find_first_int(primary_prop->table_column, primary_string); } else if (type_string.compare(str_float) == 0){ auto primary_string = NativeAccessor::to_float(ctx, arg3); row_index = table->find_first_float(primary_prop->table_column, primary_string); } else if (type_string.compare(str_double) == 0){ auto primary_string = NativeAccessor::to_double(ctx, arg3); row_index = table->find_first_double(primary_prop->table_column, primary_string); } else if (type_string.compare(str_binary) == 0){ auto primary_string = NativeAccessor::to_binary(ctx, arg3); row_index = table->find_first_binary(primary_prop->table_column, realm::BinaryData::BinaryData(primary_string)); } else if (type_string.compare(str_timestamp) == 0){ auto primary_string = NativeAccessor::to_timestamp(ctx, arg3); row_index = table->find_first_timestamp(primary_prop->table_column, primary_string); } else if (type_string.compare(str_bool) == 0){ auto primary_string = NativeAccessor::to_bool(ctx, arg3); row_index = table->find_first_bool(primary_prop->table_column, primary_string); } realm_object = realm::Object::Object(realm, object_schema, table->get(row_index)); } else{ realm_object = realm::Object::get_for_primary_key(ctx, realm, object_schema, arguments[1]); } if (realm_object.is_valid()) { return_value.set(RealmObjectClass<T>::create_instance(ctx, std::move(realm_object))); } else { return_value.set_undefined(); } }
I have tested simple 1M reads with index and memory usage before GC gone down from 3GB to 65MB and time gone down from 35 sec to 2 sec on Node.js. My test code snippets are as below.
for (var i = 0; i < 1000000; i++){ var bob = realm.objectForPrimaryKey('User', 'name', 'string', 'bob'+i); var id = bob.id; }
var users = realm.objects('User'); for (var i = 0; i < 1000000; i++){ var bob = users.filtered('name == $0', 'bob'+i); var id = bob[0].id; }
Thanks