aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/vespa/searchlib/expression/current_index_setup.cpp
blob: 6660728dea78a3ef6432e34def4b28260551eb84 (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
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "current_index_setup.h"
#include <vespa/vespalib/stllike/hash_map.hpp>
#include <cassert>

namespace search::expression {

void
CurrentIndexSetup::Usage::notify_unbound_struct_usage(vespalib::stringref name)
{
    _unbound.insert(name);
}

CurrentIndexSetup::Usage::Usage()
  : _unbound()
{
}

CurrentIndexSetup::Usage::~Usage() = default;

vespalib::stringref
CurrentIndexSetup::Usage::get_unbound_struct_name() const
{
    assert(has_single_unbound_struct());
    return *_unbound.begin();
}

CurrentIndexSetup::Usage::Bind::Bind(CurrentIndexSetup &setup, Usage &usage) noexcept
  : _setup(setup)
{
    auto prev = setup.capture(std::addressof(usage));
    assert(prev == nullptr); // no nesting
}

CurrentIndexSetup::Usage::Bind::~Bind()
{
    [[maybe_unused]] auto prev = _setup.capture(nullptr);
}

CurrentIndexSetup::CurrentIndexSetup()
  : _bound(), _usage(nullptr)
{
}

CurrentIndexSetup::~CurrentIndexSetup() = default;

const CurrentIndex *
CurrentIndexSetup::resolve(vespalib::stringref field_name) const
{
    size_t pos = field_name.rfind('.');
    if (pos > field_name.size()) {
        return nullptr;
    }
    auto struct_name = field_name.substr(0, pos);
    auto entry = _bound.find(struct_name);
    if (entry == _bound.end()) {
        if (_usage != nullptr) {
            _usage->notify_unbound_struct_usage(struct_name);
        }
        return nullptr;
    }
    return entry->second;
}

void
CurrentIndexSetup::bind(vespalib::stringref struct_name, const CurrentIndex &index)
{
    auto res = _bound.insert(std::make_pair(vespalib::string(struct_name),
                                            std::addressof(index)));
    assert(res.second); // struct must be either bound or unbound
}

}