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