Uploaded image for project: 'Realm JavaScript SDK'
  1. Realm JavaScript SDK
  2. RJS-48

Faster way to get first object by non-primary key property (like objectForPrimaryKey)

    • Type: Icon: Task Task
    • Resolution: Unresolved
    • Priority: Icon: Minor - P4 Minor - P4
    • None
    • Affects Version/s: None
    • Component/s: None

      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

            Assignee:
            Unassigned Unassigned
            Reporter:
            unitosyncbot Unito Sync Bot
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: