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

com.yahoo.schema.RankProfileRegistry 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.schema;

import com.yahoo.schema.document.SDDocumentType;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Mapping from name to {@link RankProfile} as well as a reverse mapping of {@link RankProfile} to {@link Schema}.
 * Having both of these mappings consolidated here make it easier to remove dependencies on these mappings at
 * run time, since it is essentially only used when building rank profile config at deployment time.
 *
 * Global rank profiles are represented by the Search key null.
 *
 * @author Ulf Lilleengen
 */
public class RankProfileRegistry {

    private final Map> rankProfiles = new LinkedHashMap<>();
    private static final String globalRankProfilesKey = "[global]";

    /* These rank profiles can be overridden: 'default' rank profile, as that is documented to work. And 'unranked'. */
    static final Set overridableRankProfileNames = Set.of("default", "unranked");

    public static RankProfileRegistry createRankProfileRegistryWithBuiltinRankProfiles(Schema schema) {
        RankProfileRegistry rankProfileRegistry = new RankProfileRegistry();
        rankProfileRegistry.add(new DefaultRankProfile(schema, rankProfileRegistry));
        rankProfileRegistry.add(new UnrankedRankProfile(schema, rankProfileRegistry));
        return rankProfileRegistry;
    }

    private String extractName(ImmutableSchema search) {
        return search != null ? search.getName() : globalRankProfilesKey;
    }

    /** Adds a rank profile to this registry */
    public void add(RankProfile rankProfile) {
        String schemaName = extractName(rankProfile.schema());
        if ( ! rankProfiles.containsKey(schemaName)) {
            rankProfiles.put(schemaName, new LinkedHashMap<>());
        }
        checkForDuplicate(rankProfile);
        rankProfiles.get(schemaName).put(rankProfile.name(), rankProfile);
    }

    private void checkForDuplicate(RankProfile rankProfile) {
        String rankProfileName = rankProfile.name();
        RankProfile existingRankProfileWithSameName = rankProfiles.get(extractName(rankProfile.schema())).get(rankProfileName);
        if (existingRankProfileWithSameName == null) return;

        if ( ! overridableRankProfileNames.contains(rankProfileName)) {
            throw new IllegalArgumentException("Duplicate rank profile '" + rankProfileName + "' in " +
                                               rankProfile.schema());
        }
    }

    /**
     * Returns a named rank profile, null if the search definition doesn't have one with the given name
     *
     * @param schema the {@link Schema} that owns the rank profile
     * @param name the name of the rank profile
     * @return the RankProfile to return.
     */
    public RankProfile get(String schema, String name) {
        Map profiles = rankProfiles.get(schema);
        if (profiles == null) return null;
        return profiles.get(name);
    }

    public RankProfile get(ImmutableSchema schema, String name) {
        var profile = get(schema.getName(), name);
        if (profile != null) return profile;
        if (schema.inherited().isPresent()) return get(schema.inherited().get(), name);
        return null;
    }

    public RankProfile getGlobal(String name) {
        Map profiles = rankProfiles.get(globalRankProfilesKey);
        if (profiles == null) return null;
        return profiles.get(name);
    }

    public RankProfile resolve(SDDocumentType docType, String name) {
        RankProfile rankProfile = get(docType.getName(), name);
        if (rankProfile != null) return rankProfile;
        for (var parent : docType.getInheritedTypes()) {
            RankProfile parentProfile = resolve(parent, name);
            if (parentProfile != null) return parentProfile;
        }
        return get(globalRankProfilesKey, name);
    }

    /**
     * Rank profiles that are collected across clusters.
     *
     * @return a set of global {@link RankProfile} instances
     */
    public Collection all() {
        List all = new ArrayList<>();
        for (var entry : rankProfiles.values()) {
            all.addAll(entry.values());
        }
        return all;
    }

    /**
     * Retrieve all rank profiles for a schema
     *
     * @param schema the schema to fetch rank profiles for, or null for the global ones
     * @return a collection of {@link RankProfile} instances
     */
    public Collection rankProfilesOf(ImmutableSchema schema) {
        String key = schema == null ? globalRankProfilesKey : schema.getName();

        if ( ! rankProfiles.containsKey(key)) return List.of();

        var profiles = new LinkedHashMap<>(rankProfiles.get(key));
        // Add all profiles in inherited schemas, unless they are already present (overridden)
        while (schema != null && schema.inherited().isPresent()) {
            schema = schema.inherited().get();
            var inheritedProfiles = rankProfiles.get(schema.getName());
            if (inheritedProfiles != null) {
                for (Map.Entry inheritedProfile : inheritedProfiles.entrySet()) {
                    profiles.putIfAbsent(inheritedProfile.getKey(), inheritedProfile.getValue());
                }
            }
        }
        return profiles.values();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy