Ejemplo n.º 1
0
  /**
   * Fetches the equivalent object information for a whole batch of objects.
   *
   * @param batch the objects
   * @throws ObjectStoreException if something goes wrong
   */
  protected void getEquivalentsFor(List<ResultsRow<Object>> batch) throws ObjectStoreException {
    long time = System.currentTimeMillis();
    long time1 = time;
    boolean databaseEmpty = hints.databaseEmpty();
    if (savedDatabaseEmptyFetch == -1) {
      savedDatabaseEmptyFetch = System.currentTimeMillis() - time;
    }
    if (databaseEmpty) {
      savedDatabaseEmpty++;
      return;
    }
    // TODO: add all the objects that are referenced by these objects, and follow primary keys
    // We can make use of the ObjectStoreFastCollectionsForTranslatorImpl's ability to work this
    // all out for us.
    Set<InterMineObject> objects = new HashSet<InterMineObject>();
    for (ResultsRow<Object> row : batch) {
      for (Object object : row) {
        if (object instanceof InterMineObject) {
          InterMineObject imo = (InterMineObject) object;
          if (idMap.get(imo.getId()) == null) {
            objects.add(imo);
            for (String fieldName : TypeUtil.getFieldInfos(imo.getClass()).keySet()) {
              Object fieldValue;
              try {
                fieldValue = imo.getFieldProxy(fieldName);
              } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
              }
              if ((fieldValue instanceof InterMineObject)
                  && (!(fieldValue instanceof ProxyReference))) {
                objects.add((InterMineObject) fieldValue);
              } else if (fieldValue instanceof Collection<?>) {
                for (Object collectionElement : ((Collection<?>) fieldValue)) {
                  if ((collectionElement instanceof InterMineObject)
                      && (!(collectionElement instanceof ProxyReference))) {
                    objects.add((InterMineObject) collectionElement);
                  }
                }
              }
            }
          }
        }
      }
    }
    objects.removeAll(equivalents.keySet());
    // Now objects contains all the objects we need to fetch data for.
    Map<InterMineObject, Set<InterMineObject>> results =
        new HashMap<InterMineObject, Set<InterMineObject>>();
    for (InterMineObject object : objects) {
      results.put(object, Collections.synchronizedSet(new HashSet<InterMineObject>()));
    }

    Map<PrimaryKey, ClassDescriptor> pksToDo = new IdentityHashMap<PrimaryKey, ClassDescriptor>();
    Map<ClassDescriptor, List<InterMineObject>> cldToObjectsForCld =
        new IdentityHashMap<ClassDescriptor, List<InterMineObject>>();
    Map<Class<?>, List<InterMineObject>> categorised = CollectionUtil.groupByClass(objects, false);
    Map<ClassDescriptor, Boolean> cldsDone = new IdentityHashMap<ClassDescriptor, Boolean>();
    for (Class<?> c : categorised.keySet()) {
      Set<ClassDescriptor> classDescriptors = model.getClassDescriptorsForClass(c);
      for (ClassDescriptor cld : classDescriptors) {
        if (!cldsDone.containsKey(cld)) {
          cldsDone.put(cld, Boolean.TRUE);
          Set<PrimaryKey> keysForClass;
          if (source == null) {
            keysForClass = new HashSet<PrimaryKey>(PrimaryKeyUtil.getPrimaryKeys(cld).values());
          } else {
            keysForClass = DataLoaderHelper.getPrimaryKeys(cld, source, lookupOs);
          }
          if (!keysForClass.isEmpty()) {
            time = System.currentTimeMillis();
            boolean classNotExists = hints.classNotExists(cld.getType());
            String className = Util.getFriendlyName(cld.getType());
            if (!savedTimes.containsKey(className)) {
              savedTimes.put(className, new Long(System.currentTimeMillis() - time));
            }
            if (!classNotExists) {
              // LOG.error("Inspecting class " + className);
              List<InterMineObject> objectsForCld = new ArrayList<InterMineObject>();
              for (Map.Entry<Class<?>, List<InterMineObject>> category : categorised.entrySet()) {
                if (cld.getType().isAssignableFrom(category.getKey())) {
                  objectsForCld.addAll(category.getValue());
                }
              }
              cldToObjectsForCld.put(cld, objectsForCld);
              // So now we have a list of objects for this CLD.
              for (PrimaryKey pk : keysForClass) {
                // LOG.error("Adding pk " + cld.getName() + "." + pk.getName());
                pksToDo.put(pk, cld);
              }
            } else {
              // LOG.error("Empty class " + className);
            }
          }
        }
      }
    }
    doPks(pksToDo, results, cldToObjectsForCld, time1);
    batchQueried += results.size();
    equivalents.putAll(results);
  }