private void link(Object o1, Object o2, boolean mayMerge) {

    Set<Object> keySet = Collections.newSetFromMap(new IdentityHashMap<Object, Boolean>());
    keySet.add(o1);
    keySet.add(o2);
    keySet.add(getKeyFor(o1));
    keySet.add(getKeyFor(o2));

    Set<EquivGroup> mGroups = Collections.newSetFromMap(new IdentityHashMap<EquivGroup, Boolean>());

    for (Object object : keySet) {
      EquivGroup group = objectMap.get(object);
      if (group != null) {
        mGroups.add(group);
      }
    }
    if (mGroups.size() > 1) {
      if (!mayMerge) {
        LOG.warn("Illegally linking {} and {}", o1, o2);
        mGroups.forEach(g -> g.add(new OperatorStats.IncorrectRuntimeStatsMarker()));
        return;
      }
      EquivGroup newGrp = new EquivGroup();
      newGrp.add(o1);
      newGrp.add(o2);
      for (EquivGroup g : mGroups) {
        for (Object o : g.members) {
          newGrp.add(o);
        }
      }
      groups.add(newGrp);
      groups.removeAll(mGroups);
    } else {
      EquivGroup targetGroup = mGroups.isEmpty() ? new EquivGroup() : mGroups.iterator().next();
      groups.add(targetGroup);
      targetGroup.add(o1);
      targetGroup.add(o2);
    }

  }
Links and optionally merges the groups identified by the two objects.
ql/src/java/org/apache/hadoop/hive/ql/plan/mapper/PlanMapper.java