aboutsummaryrefslogtreecommitdiffstats
path: root/streamingvisitors/src/vespa/vsm/vsm/vsm-adapter.cpp
blob: e17ca40e5f1809d04aeddb80c79d25940d5ef8ac (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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "vsm-adapter.hpp"
#include "docsum_field_writer_factory.h"
#include "i_matching_elements_filler.h"
#include "query_term_filter_factory.h"
#include <vespa/searchlib/common/matching_elements.h>
#include <vespa/searchsummary/config/config-juniperrc.h>

#include <vespa/log/log.h>
LOG_SETUP(".vsm.vsm-adapter");

using search::docsummary::IQueryTermFilterFactory;
using search::docsummary::ResConfigEntry;
using search::MatchingElements;
using config::ConfigSnapshot;
using vespa::config::search::SummaryConfig;
using vespa::config::search::summary::JuniperrcConfig;

namespace vsm {

GetDocsumsStateCallback::GetDocsumsStateCallback() :
    _summaryFeatures(),
    _rankFeatures(),
    _matching_elements_filler()
{ }

void GetDocsumsStateCallback::fillSummaryFeatures(GetDocsumsState& state)
{
    if (_summaryFeatures) { // set the summary features to write to the docsum
        state._summaryFeatures = _summaryFeatures;
    }
}

void GetDocsumsStateCallback::fillRankFeatures(GetDocsumsState& state)
{
    if (_rankFeatures) { // set the rank features to write to the docsum
        state._rankFeatures = _rankFeatures;
    }
}

std::unique_ptr<MatchingElements>
GetDocsumsStateCallback::fill_matching_elements(const search::MatchingElementsFields& fields)
{
    if (_matching_elements_filler) {
        return _matching_elements_filler->fill_matching_elements(fields);
    }
    return std::make_unique<MatchingElements>();
}

void
GetDocsumsStateCallback::set_matching_elements_filler(std::unique_ptr<IMatchingElementsFiller> matching_elements_filler)
{
    _matching_elements_filler = std::move(matching_elements_filler);
}

GetDocsumsStateCallback::~GetDocsumsStateCallback() = default;

DocsumTools::FieldSpec::FieldSpec() noexcept :
    _outputName(),
    _inputNames(),
    _command(VsmsummaryConfig::Fieldmap::Command::NONE)
{ }

DocsumTools::FieldSpec::~FieldSpec() = default;

DocsumTools::DocsumTools()
    : IDocsumEnvironment(),
      _writer(),
      _juniper(),
      _resultClass(),
      _fieldSpecs()
{
}


DocsumTools::~DocsumTools() = default;

void
DocsumTools::set_writer(std::unique_ptr<DynamicDocsumWriter> writer)
{
    _writer = std::move(writer);
}

bool
DocsumTools::obtainFieldNames(const FastS_VsmsummaryHandle &cfg)
{
    uint32_t defaultSummaryId = getResultConfig()->lookupResultClassId(cfg->outputclass);
    _resultClass = getResultConfig()->lookupResultClass(defaultSummaryId);
    if (_resultClass != nullptr) {
        for (uint32_t i = 0; i < _resultClass->getNumEntries(); ++i) {
            const ResConfigEntry * entry = _resultClass->getEntry(i);
            _fieldSpecs.emplace_back();
            _fieldSpecs.back().setOutputName(entry->name());
            bool found = false;
            if (cfg) {
                // check if we have this summary field in the vsmsummary config
                for (uint32_t j = 0; j < cfg->fieldmap.size() && !found; ++j) {
                    if (entry->name() == cfg->fieldmap[j].summary.c_str()) {
                        for (uint32_t k = 0; k < cfg->fieldmap[j].document.size(); ++k) {
                            _fieldSpecs.back().getInputNames().push_back(cfg->fieldmap[j].document[k].field);
                        }
                        _fieldSpecs.back().setCommand(cfg->fieldmap[j].command);
                        found = true;
                    }
                }
            }
            if (!found) {
                // use yourself as input
                _fieldSpecs.back().getInputNames().push_back(entry->name());
            }
        }
    } else {
        LOG(warning, "could not locate result class: '%s'", cfg->outputclass.c_str());
    }
    return true;
}

void
VSMAdapter::configure(const VSMConfigSnapshot & snapshot)
{
    std::lock_guard guard(_lock);
    LOG(debug, "(re-)configure VSM (docsum tools)");

    std::shared_ptr<SummaryConfig>      summary(snapshot.getConfig<SummaryConfig>());
    std::shared_ptr<VsmsummaryConfig>   vsmSummary(snapshot.getConfig<VsmsummaryConfig>());
    std::shared_ptr<JuniperrcConfig>    juniperrc(snapshot.getConfig<JuniperrcConfig>());

    _fieldsCfg.set(snapshot.getConfig<VsmfieldsConfig>().release());
    _fieldsCfg.latch();

    LOG(debug, "configureFields(): Size of cfg fieldspec: %zd", _fieldsCfg.get()->fieldspec.size()); // UlfC: debugging
    LOG(debug, "configureFields(): Size of cfg documenttype: %zd", _fieldsCfg.get()->documenttype.size()); // UlfC: debugging
    LOG(debug, "configureSummary(): Size of cfg classes: %zd", summary->classes.size()); // UlfC: debugging
    LOG(debug, "configureVsmSummary(): Size of cfg fieldmap: %zd", vsmSummary->fieldmap.size()); // UlfC: debugging
    LOG(debug, "configureVsmSummary(): outputclass='%s'", vsmSummary->outputclass.c_str()); // UlfC: debugging

    // create new docsum tools
    auto docsumTools = std::make_unique<DocsumTools>();

    // configure juniper (used by search::docsummary::DocsumFieldWriterFactory)
    _juniperProps = std::make_unique<JuniperProperties>(*juniperrc);
    auto juniper = std::make_unique<juniper::Juniper>(_juniperProps.get(), &_wordFolder);
    docsumTools->setJuniper(std::move(juniper));

    // init result config
    auto resCfg = std::make_unique<ResultConfig>();
    std::unique_ptr<IQueryTermFilterFactory> query_term_filter_factory = std::make_unique<QueryTermFilterFactory>(*_fieldsCfg.get(), *vsmSummary);
    auto docsum_field_writer_factory = std::make_unique<DocsumFieldWriterFactory>(summary.get()->usev8geopositions, *docsumTools, *query_term_filter_factory, *_fieldsCfg.get());
    if ( !resCfg->readConfig(*summary.get(), _configId.c_str(), *docsum_field_writer_factory)) {
        throw std::runtime_error("(re-)configuration of VSM (docsum tools) failed due to bad summary config");
    }
    docsum_field_writer_factory.reset();
    query_term_filter_factory.reset();

    // create dynamic docsum writer
    auto writer = std::make_unique<DynamicDocsumWriter>(std::move(resCfg));
    docsumTools->set_writer(std::move(writer));

    // configure new docsum tools
    if (docsumTools->obtainFieldNames(vsmSummary)) {
        // latch new docsum tools into production
        _docsumTools.set(docsumTools.release());
        _docsumTools.latch();
    } else {
        throw std::runtime_error("(re-)configuration of VSM (docsum tools) failed");
    }
}

VSMConfigSnapshot::VSMConfigSnapshot(const vespalib::string & configId, const config::ConfigSnapshot & snapshot)
    : _configId(configId),
      _snapshot(std::make_unique<config::ConfigSnapshot>(snapshot))
{ }
VSMConfigSnapshot::~VSMConfigSnapshot() = default;

VSMAdapter::VSMAdapter(const vespalib::string & configId, const Fast_WordFolder& wordFolder)
    : _configId(configId),
      _wordFolder(wordFolder),
      _fieldsCfg(),
      _docsumTools(),
      _juniperProps(),
      _lock()
{
}


VSMAdapter::~VSMAdapter() = default;

}