Code review comment: I try to use ImmutableEquivalenceSet, i found that `ImmutableEquivalenceSet` may be not suit the scene such as I want to make a relation mapping as  `RelationId#1 -> RelationId#2` which should keep the directivity。 after call` ImmutableEquivalenceSet.addEqualPair` then `tryToMap`,i found get the result is   > RelationId#2 -> RelationId#1

Code under review:
public static List<RelationMapping> generate(List<CatalogRelation> sources, List<CatalogRelation> targets) {
        
        HashMultimap<Long, MappedRelation> sourceTableRelationIdMap = HashMultimap.create();
        for (CatalogRelation relation : sources) {
            sourceTableRelationIdMap.put(getTableQualifier(relation.getTable()),
                    MappedRelation.of(relation.getRelationId(), relation));
        }
        HashMultimap<Long, MappedRelation> targetTableRelationIdMap = HashMultimap.create();
        for (CatalogRelation relation : targets) {
            targetTableRelationIdMap.put(getTableQualifier(relation.getTable()),
                    MappedRelation.of(relation.getRelationId(), relation));
        }
        Set<Long> sourceTableKeySet = sourceTableRelationIdMap.keySet();
        List<List<RelationMapping>> mappedRelations = new ArrayList<>();

        for (Long sourceTableQualifier : sourceTableKeySet) {
            Set<MappedRelation> sourceMappedRelations = sourceTableRelationIdMap.get(sourceTableQualifier);
            Set<MappedRelation> targetMappedRelations = targetTableRelationIdMap.get(sourceTableQualifier);
            if (targetMappedRelations.isEmpty()) {
                continue;
            }
            
            if (targetMappedRelations.size() == 1 && sourceMappedRelations.size() == 1) {
                ImmutableBiMap.Builder<MappedRelation, MappedRelation> biMapBuilder = ImmutableBiMap.builder();
                mappedRelations.add(ImmutableList.of(
                        RelationMapping.of(biMapBuilder.put(sourceMappedRelations.iterator().next(),
                                targetMappedRelations.iterator().next()).build())));
                continue;
            }
            
            
            
            
            
            
            
            ImmutableList<Pair<MappedRelation, MappedRelation>> relationMapping = Sets.cartesianProduct(
                            sourceMappedRelations, targetMappedRelations)
                    .stream()
                    .map(listPair -> Pair.of(listPair.get(0), listPair.get(1)))
                    .collect(ImmutableList.toImmutableList());

            
            
            
            
            
            List<RelationMapping> relationMappingPowerList = new ArrayList<>();
            int relationMappingSize = relationMapping.size();
            int relationMappingMinSize = Math.min(sourceMappedRelations.size(), targetMappedRelations.size());
            for (int i = 0; i < relationMappingSize; i++) {
                HashBiMap<MappedRelation, MappedRelation> relationBiMap = HashBiMap.create();
                relationBiMap.put(relationMapping.get(i).key(), relationMapping.get(i).value());
                for (int j = i + 1; j < relationMappingSize; j++) {
                    if (!relationBiMap.containsKey(relationMapping.get(j).key())
                            && !relationBiMap.containsValue(relationMapping.get(j).value())) {
                        relationBiMap.put(relationMapping.get(j).key(), relationMapping.get(j).value());
                    }
                }
                
                if (relationBiMap.size() >= relationMappingMinSize) {
                    relationMappingPowerList.add(RelationMapping.of(ImmutableBiMap.copyOf(relationBiMap)));
                }
            }
            mappedRelations.add(relationMappingPowerList);
        }
        
        return Lists.cartesianProduct(mappedRelations).stream()
                .map(RelationMapping::merge)
                .collect(ImmutableList.toImmutableList());
    }

Line commented on: List<List<RelationMapping>> mappedRelations = new ArrayList<>();

Revised code:
public static List<RelationMapping> generate(List<CatalogRelation> sources, List<CatalogRelation> targets) {
        
        HashMultimap<Long, MappedRelation> sourceTableRelationIdMap = HashMultimap.create();
        for (CatalogRelation relation : sources) {
            sourceTableRelationIdMap.put(getTableQualifier(relation.getTable()),
                    MappedRelation.of(relation.getRelationId(), relation));
        }
        HashMultimap<Long, MappedRelation> targetTableRelationIdMap = HashMultimap.create();
        for (CatalogRelation relation : targets) {
            targetTableRelationIdMap.put(getTableQualifier(relation.getTable()),
                    MappedRelation.of(relation.getRelationId(), relation));
        }
        Set<Long> sourceTableKeySet = sourceTableRelationIdMap.keySet();
        List<List<BiMap<MappedRelation, MappedRelation>>> mappedRelations = new ArrayList<>();

        for (Long sourceTableId : sourceTableKeySet) {
            Set<MappedRelation> sourceMappedRelations = sourceTableRelationIdMap.get(sourceTableId);
            Set<MappedRelation> targetMappedRelations = targetTableRelationIdMap.get(sourceTableId);
            if (targetMappedRelations.isEmpty()) {
                continue;
            }
            
            if (targetMappedRelations.size() == 1 && sourceMappedRelations.size() == 1) {
                ImmutableBiMap.Builder<MappedRelation, MappedRelation> biMapBuilder = ImmutableBiMap.builder();
                mappedRelations.add(ImmutableList.of(
                        biMapBuilder.put(sourceMappedRelations.iterator().next(),
                                targetMappedRelations.iterator().next()).build()));
                continue;
            }
            
            
            
            
            
            
            
            
            ImmutableList<Pair<MappedRelation, MappedRelation>> relationMapping = Sets.cartesianProduct(
                            sourceMappedRelations, targetMappedRelations)
                    .stream()
                    .map(listPair -> Pair.of(listPair.get(0), listPair.get(1)))
                    .collect(ImmutableList.toImmutableList());

            
            
            
            
            
            List<BiMap<MappedRelation, MappedRelation>> relationMappingPowerList = new ArrayList<>();
            int relationMappingSize = relationMapping.size();
            int relationMappingMinSize = Math.min(sourceMappedRelations.size(), targetMappedRelations.size());
            for (int i = 0; i < relationMappingSize; i++) {
                HashBiMap<MappedRelation, MappedRelation> relationBiMap = HashBiMap.create();
                relationBiMap.put(relationMapping.get(i).key(), relationMapping.get(i).value());
                for (int j = i + 1; j < relationMappingSize; j++) {
                    if (!relationBiMap.containsKey(relationMapping.get(j).key())
                            && !relationBiMap.containsValue(relationMapping.get(j).value())) {
                        relationBiMap.put(relationMapping.get(j).key(), relationMapping.get(j).value());
                    }
                }
                
                if (relationBiMap.size() >= relationMappingMinSize) {
                    relationMappingPowerList.add(relationBiMap);
                }
            }
            mappedRelations.add(relationMappingPowerList);
        }
        
        return Lists.cartesianProduct(mappedRelations).stream()
                .map(RelationMapping::merge)
                .collect(ImmutableList.toImmutableList());
    }