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
|
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
#include "iroutablefactory.h"
#include <vespa/messagebus/blobref.h>
#include <vespa/vespalib/component/versionspecification.h>
#include <mutex>
#include <map>
namespace documentapi {
/**
* This class encapsulates the logic required to map routable type and version to a corresponding {@link
* RoutableFactory}. It is owned and accessed through a {@link DocumentProtocol} instance. This class uses a
* factory cache to reduce the latency of matching version specifications to actual versions when resolving
* factories.
*/
class RoutableRepository {
private:
/**
* Internal helper class that implements a map from {@link VersionSpecification} to {@link
* RoutableFactory}.
*/
class VersionMap {
private:
std::map<vespalib::VersionSpecification, IRoutableFactory::SP> _factoryVersions;
public:
VersionMap();
bool putFactory(const vespalib::VersionSpecification &version, IRoutableFactory::SP factory);
IRoutableFactory::SP getFactory(const vespalib::Version &version) const;
};
using CacheKey = std::pair<vespalib::Version, uint32_t>;
using FactoryCache = std::map<CacheKey, IRoutableFactory::SP>;
using TypeMap = std::map<uint32_t, VersionMap>;
mutable std::mutex _lock;
TypeMap _factoryTypes;
mutable FactoryCache _cache;
public:
RoutableRepository(const RoutableRepository &) = delete;
RoutableRepository & operator = (const RoutableRepository &) = delete;
/**
* Constructs a new routable repository.
*/
RoutableRepository();
/**
* Decodes a {@link Routable} from the given byte array. This uses the content of the byte array to
* dispatch the decode request to the appropriate {@link RoutableFactory} that was previously registered.
*
* If a routable can not be decoded, this method returns an empty blob.
*
* @param version The version of the encoded routable.
* @param data The byte array containing the encoded routable.
* @return The decoded routable.
*/
mbus::Routable::UP decode(const vespalib::Version &version, mbus::BlobRef data) const;
/**
* Encodes a {@link Routable} into a byte array. This dispatches the encode request to the appropriate
* {@link RoutableFactory} that was previously registered.
*
* If a routable can not be encoded, this method returns an empty byte array.
*
* @param version The version to encode the routable as.
* @param obj The routable to encode.
* @return The byte array containing the encoded routable.
*/
mbus::Blob encode(const vespalib::Version &version, const mbus::Routable &obj) const;
/**
* Registers a routable factory for a given version and routable type.
*
* @param version The version specification that the given factory supports.
* @param type The routable type that the given factory supports.
* @param factory The routable factory to register.
*/
void putFactory(const vespalib::VersionSpecification &version,
uint32_t type, IRoutableFactory::SP factory);
/**
* Returns the routable factory for a given version and routable type.
*
* @param version The version that the factory must support.
* @param type The routable type that the factory must support.
* @return The routable factory matching the criteria, or null.
*/
IRoutableFactory::SP getFactory(const vespalib::Version &version, uint32_t type) const;
/**
* Returns a list of routable types that support the given version.
*
* @param version The version to return types for.
* @param out The list to write to.
* @return The number of supported types.
*/
uint32_t getRoutableTypes(const vespalib::Version &version, std::vector<uint32_t> &out) const;
};
}
|