All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yahoo.vespa.model.container.search.DeclaredQueryProfileVariants Maven / Gradle / Ivy

There is a newer version: 8.409.18
Show newest version
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.container.search;

import com.yahoo.search.query.profile.OverridableQueryProfile;
import com.yahoo.search.query.profile.QueryProfile;
import com.yahoo.search.query.profile.QueryProfileVariants;

import java.util.*;

/**
 * Represents a set of query profile variants (more or less) as they were declared -
 * a helper to produce config, which is also using the "declared" representation
 *
 * @author bratseth
 */
public class DeclaredQueryProfileVariants {

    private final Map variantQueryProfiles = new LinkedHashMap<>();

    public DeclaredQueryProfileVariants(QueryProfile profile) {
        // Recreates the declared view (settings per set of dimensions)
        // from the runtime view (dimension-value pairs per variable)
        // yes, this is a little backwards, but the complexity of two representations
        // is contained right here...
        // TODO: This has become unnecessary as the variants now retains the original structure
        for (Map.Entry fieldValueEntry : profile.getVariants().getFieldValues().entrySet()) {
            for (QueryProfileVariants.FieldValue fieldValue : fieldValueEntry.getValue().asList()) {
                addVariant(fieldValueEntry.getKey(),
                           fieldValue.getValue(),
                           profile.getVariants().getVariant(fieldValue.getDimensionValues(), false).isOverridable(fieldValueEntry.getKey()),
                           fieldValue.getDimensionValues().getValues());
            }
        }

        for (QueryProfileVariants.FieldValue fieldValue : profile.getVariants().getInherited().asList()) {
            for (QueryProfile inherited : (List)fieldValue.getValue())
                addVariantInherited(inherited,fieldValue.getDimensionValues().getValues());
        }

        dereferenceCompoundedVariants(profile, "");
    }

    private void addVariant(String name, Object value, Boolean overridable, String[] dimensionValues) {
        String dimensionString = toCanonicalString(dimensionValues);
        VariantQueryProfile variant = variantQueryProfiles.get(dimensionString);
        if (variant == null) {
            variant = new VariantQueryProfile(dimensionValues);
            variantQueryProfiles.put(dimensionString, variant);
        }
        variant.getValues().put(name, value);
        if (overridable != null)
            variant.getOverriable().put(name, overridable);
    }

    private void addVariantInherited(QueryProfile inherited,String[] dimensionValues) {
        String dimensionString = toCanonicalString(dimensionValues);
        VariantQueryProfile variant = variantQueryProfiles.get(dimensionString);
        if (variant == null) {
            variant = new VariantQueryProfile(dimensionValues);
            variantQueryProfiles.put(dimensionString, variant);
        }
        variant.inherit(inherited);
    }

    private void dereferenceCompoundedVariants(QueryProfile profile,String prefix) {
        // A variant of a.b is represented as the value a pointing to an anonymous profile a
        // having the variants
        for (Map.Entry entry : profile.declaredContent().entrySet()) {
            if ( ! (entry.getValue() instanceof QueryProfile)) continue;
            QueryProfile subProfile = (QueryProfile)entry.getValue();
            // Export if defined implicitly in this, or if this contains overrides
            if (!subProfile.isExplicit() || subProfile instanceof OverridableQueryProfile) {
                String entryPrefix = prefix + entry.getKey() + ".";
                dereferenceCompoundedVariants(subProfile.getVariants(), entryPrefix);
                dereferenceCompoundedVariants(subProfile, entryPrefix);
            }
        }

        if (profile.getVariants() == null) return;
        // We need to do the same dereferencing to overridables pointed to by variants of this
        for (Map.Entry fieldValueEntry : profile.getVariants().getFieldValues().entrySet()) {
            for (QueryProfileVariants.FieldValue fieldValue : fieldValueEntry.getValue().asList()) {
                if ( ! (fieldValue.getValue() instanceof QueryProfile)) continue;
                QueryProfile subProfile = (QueryProfile)fieldValue.getValue();
                // Export if defined implicitly in this, or if this contains overrides
                if (!subProfile.isExplicit() || subProfile instanceof OverridableQueryProfile) {
                    String entryPrefix = prefix + fieldValueEntry.getKey() + ".";
                    dereferenceCompoundedVariants(subProfile.getVariants(), entryPrefix);
                    dereferenceCompoundedVariants(subProfile, entryPrefix);
                }
            }
        }
    }

    private void dereferenceCompoundedVariants(QueryProfileVariants profileVariants, String prefix) {
        if (profileVariants == null) return;
        for (Map.Entry fieldVariant : profileVariants.getFieldValues().entrySet()) {
            for (QueryProfileVariants.FieldValue variantValue : fieldVariant.getValue().asList()) {
                addVariant(prefix + fieldVariant.getKey(), variantValue.getValue(), null, variantValue.getDimensionValues().getValues());
            }
        }
    }

    public String toCanonicalString(String[] dimensionValues) {
        StringBuilder b = new StringBuilder();
        for (String dimensionValue : dimensionValues) {
            if (dimensionValue != null)
                b.append(dimensionValue);
            else
                b.append("*");
            b.append(",");
        }
        b.deleteCharAt(b.length() - 1); // Remove last,
        return b.toString();
    }

    public Map getVariantQueryProfiles() { return variantQueryProfiles; }

    public static class VariantQueryProfile {

        private final Map values = new LinkedHashMap<>();

        private final Map overridable = new HashMap<>();

        private final List inherited = new ArrayList<>();

        private final String[] dimensionValues;

        public VariantQueryProfile(String[] dimensionValues) {
            this.dimensionValues = dimensionValues;
        }

        public String[] getDimensionValues() { return dimensionValues; }

        public void inherit(QueryProfile inheritedProfile) {
            inherited.add(inheritedProfile);
        }

        public List inherited() { return inherited; }

        public Map getValues() { return values; }

        public Map getOverriable() { return overridable; }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy