aboutsummaryrefslogtreecommitdiffstats
path: root/slobrok/src/vespa/slobrok/server/service_map_mirror.cpp
blob: 02eaa319a6e0993eb01569da849be99a6f2aa304 (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
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "service_map_mirror.h"
#include <vespa/log/log.h>
LOG_SETUP(".slobrok.server.service_map_mirror");

namespace slobrok {

ServiceMapMirror::ServiceMapMirror()
  : _map(),
    _currGen(0)
{}

ServiceMapMirror::~ServiceMapMirror() {
    LOG_ASSERT(_listeners.size() == 0);
}

void ServiceMapMirror::apply(const MapDiff &diff) {
    LOG(debug, "Applying diff from gen %u", diff.fromGen.getAsInt());
    LOG_ASSERT(diff.fromGen == _currGen);
    for (const auto & name : diff.removed) {
        auto iter = _map.find(name);
        if (iter != _map.end()) {
            LOG(debug, "Apply remove %s->%s", name.c_str(), iter->second.c_str());
            ServiceMapping mapping(name, iter->second);
            for (auto * listener : _listeners) {
                listener->remove(mapping);
            }
            _map.erase(iter);
        } else {
            LOG(debug, "Apply remove %s [already removed]", name.c_str());
        }
    }
    for (const auto & mapping : diff.updated) {
        LOG(debug, "Apply update %s->%s", mapping.name.c_str(), mapping.spec.c_str());
        auto iter = _map.find(mapping.name);
        if (iter != _map.end()) {
            ServiceMapping old{mapping.name, iter->second};
            iter->second = mapping.spec;
            for (auto * listener : _listeners) {
                listener->update(old, mapping);
            }
        } else {
            _map.emplace(mapping.name, mapping.spec);
            for (auto * listener : _listeners) {
                listener->add(mapping);
            }
        }
    }
    LOG(debug, "Apply diff complete to gen %u", diff.toGen.getAsInt());
    _currGen = diff.toGen;
}

void ServiceMapMirror::clear() {
    for (const auto & [ k, v ] : _map) {
        ServiceMapping mapping{k, v};
        for (auto * listener : _listeners) {
            listener->remove(mapping);
        }
    }
    _map.clear();
    _currGen.reset();
}

ServiceMappingList ServiceMapMirror::allMappings() const {
    ServiceMappingList result;
    result.reserve(_map.size());
    for (const auto & [ k, v ] : _map) {
        result.emplace_back(k, v);
    }
    return result;
}

void ServiceMapMirror::registerListener(MapListener &listener) {
    _listeners.insert(&listener);
}

void ServiceMapMirror::unregisterListener(MapListener &listener) {
    _listeners.erase(&listener);
}


} // namespace slobrok