aboutsummaryrefslogtreecommitdiffstats
path: root/config-model/src/main/java/com/yahoo/vespa/model/container/search/searchchain/defaultsearchchains/VespaSearchChainsCreator.java
blob: d9c3beaaf0ec7847945506718c4b6a5fe191b6dd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.container.search.searchchain.defaultsearchchains;

import com.yahoo.component.ComponentId;
import com.yahoo.component.ComponentSpecification;
import com.yahoo.component.chain.Phase;
import com.yahoo.component.chain.model.ChainSpecification;
import com.yahoo.component.chain.model.ChainedComponentModel;
import com.yahoo.search.searchchain.PhaseNames;
import com.yahoo.search.searchchain.model.VespaSearchers;
import com.yahoo.search.searchchain.model.federation.FederationSearcherModel;
import com.yahoo.vespa.model.container.search.searchchain.FederationSearcher;
import com.yahoo.vespa.model.container.search.searchchain.SearchChain;
import com.yahoo.vespa.model.container.search.searchchain.SearchChains;
import com.yahoo.vespa.model.container.search.searchchain.Searcher;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.Optional;


/**
 * Creates the search chains vespaPhases, vespa and native.
 *
 * @author Tony Vaagenes
 */
// TODO: refactor
public class VespaSearchChainsCreator {

    private static class PhasesCreator {

        private static Set<String> set(String successor) {
            return successor == null ? null : new LinkedHashSet<>(List.of(successor));
        }

        private static String lastElement(String[] phases) {
            return phases[phases.length - 1];
        }

        private static Phase createPhase(String phase, String before) {
            return new Phase(phase, set(before), null);
        }

        static Collection<Phase> linearPhases(String... phases) {
            List<Phase> result = new ArrayList<>();

            for (int i=0; i < phases.length - 1; ++i) {
                result.add(createPhase(phases[i], phases[i+1]));
            }

            if (phases.length > 0) {
                result.add(createPhase(lastElement(phases), null));
            }

            return result;
        }
    }

    private static Set<ComponentSpecification> noSearcherReferences() {
        return Set.of();
    }

    private static Collection<Phase> noPhases() {
        return Set.of();
    }

    private static ChainSpecification.Inheritance inherits(ComponentId chainId) {
        Set<ComponentSpecification> inheritsSet = new LinkedHashSet<>();
        inheritsSet.add(chainId.toSpecification());
        return new ChainSpecification.Inheritance(inheritsSet, null);
    }

    static ChainSpecification.Inheritance inheritsVespaPhases() {
        return inherits(vespaPhasesSpecification().componentId);
    }

    private static void addInnerSearchers(SearchChain searchChain, Collection<ChainedComponentModel> searcherModels) {
        for (ChainedComponentModel searcherModel : searcherModels) {
            searchChain.addInnerComponent(createSearcher(searcherModel));
        }
    }

    private static Searcher<? extends ChainedComponentModel> createSearcher(ChainedComponentModel searcherModel) {
        if (searcherModel instanceof FederationSearcherModel) {
            return new FederationSearcher((FederationSearcherModel) searcherModel, Optional.empty());
        } else {
            return new Searcher<>(searcherModel);
        }
    }

    private static ChainSpecification nativeSearchChainSpecification() {
        return new ChainSpecification(new ComponentId("native"),
                                      inheritsVespaPhases(),
                                      noPhases(),
                                      noSearcherReferences());
    }

    private static ChainSpecification vespaSearchChainSpecification() {
        return new ChainSpecification(new ComponentId("vespa"),
                                      inherits(nativeSearchChainSpecification().componentId),
                                      noPhases(),
                                      noSearcherReferences());
    }

    private static ChainSpecification vespaPhasesSpecification() {
        return new ChainSpecification(new ComponentId("vespaPhases"),
                                      new ChainSpecification.Inheritance(null, null),
                                      PhasesCreator.linearPhases(
                                              PhaseNames.RAW_QUERY,
                                              PhaseNames.TRANSFORMED_QUERY,
                                              PhaseNames.BLENDED_RESULT,
                                              PhaseNames.UNBLENDED_RESULT,
                                              PhaseNames.BACKEND),
                                      noSearcherReferences());
    }

    private static SearchChain createVespaPhases() {
        return new SearchChain(vespaPhasesSpecification());
    }

    private static SearchChain createNative() {
        SearchChain nativeChain = new SearchChain(nativeSearchChainSpecification());
        addInnerSearchers(nativeChain, VespaSearchers.nativeSearcherModels);
        return nativeChain;
    }

    private static SearchChain createVespa() {
        SearchChain vespaChain = new SearchChain(vespaSearchChainSpecification());
        addInnerSearchers(vespaChain, VespaSearchers.vespaSearcherModels);
        return vespaChain;
    }

    public static void addVespaSearchChains(SearchChains searchChains) {
        searchChains.add(createVespaPhases());
        searchChains.add(createNative());
        searchChains.add(createVespa());
    }

}