001package gudusoft.gsqlparser.dlineage.dataflow.model;
002
003import java.util.HashSet;
004import java.util.Set;
005
006/**
007 * Target star links remembered across the relations of one target column: the links that already have an explicit
008 * (non-star) source, so that a star-expanded source of the same column is not added again. A link is found by the
009 * target link's folded display, as the analyzer's set of names did; while star links are grouped by identity, a link
010 * that has an identifier is found by it, and by the display only where a label is involved.
011 *
012 * <p>Internal contract of the lineage analyzer.
013 */
014public final class StarLinkNameSet {
015
016        private final Set<String> folded = new HashSet<String>();
017
018        private final Set<StarLinkKey> identifiers = StarLinkStore.IDENTITY ? new HashSet<StarLinkKey>() : null;
019
020        private final Set<String> labels = StarLinkStore.IDENTITY ? new HashSet<String>() : null;
021
022        /** Remembers the target link {@code target}. */
023        public void add(StarLinkMatcher target) {
024                folded.add(target.foldedDisplay());
025                if (identifiers != null) {
026                        if (target.identity() != null && target.identity().isIdentifier()) {
027                                identifiers.add(target.identity());
028                        } else {
029                                labels.add(target.foldedDisplay());
030                        }
031                }
032        }
033
034        /** Whether the star link at {@code ordinal} of {@code source} is a remembered target link. */
035        public boolean contains(Column source, int ordinal) {
036                String display = source.starLinkDisplay(ordinal);
037                boolean legacy = folded.contains(display);
038                if (identifiers == null) {
039                        return legacy;
040                }
041                Object key = source.starLinkKey(ordinal);
042                if (!(key instanceof StarLinkKey) || !((StarLinkKey) key).isIdentifier()) {
043                        return legacy;
044                }
045                return decided(identifiers.contains(key) || labels.contains(display), legacy, display);
046        }
047
048        /** Whether {@code target} is a remembered target link. */
049        public boolean contains(StarLinkMatcher target) {
050                boolean legacy = folded.contains(target.foldedDisplay());
051                if (identifiers == null || target.identity() == null || !target.identity().isIdentifier()) {
052                        return legacy;
053                }
054                return decided(identifiers.contains(target.identity()) || labels.contains(target.foldedDisplay()), legacy,
055                                target.foldedDisplay());
056        }
057
058        private static boolean decided(boolean identity, boolean legacy, String display) {
059                if (identity != legacy) {
060                        StarLinkStore.census("PREDICATE_DIFF explicitSource", display + " " + legacy + " -> " + identity);
061                }
062                return identity;
063        }
064}