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
|