18
18
19
19
namespace swift {
20
20
21
- // / A CRTP write-once multi-map cache that can be small. It uses a DenseMap
21
+ // / A write-once multi-map cache that can be small. It uses a DenseMap
22
22
// / internally, so it can be used as a cache without needing to be frozen like
23
- // / FrozenMultiMap (which uses only a vector internally). The Impl class
24
- // / implements the method constructValuesForKey that is used to compute the
25
- // / actual cache value.
26
- // /
27
- // / NOTE: constructValuesForKeys is assumed to take a KeyTy and a
28
- // / SmallVectorImpl<ValueTy>. It must append all results to that accumulator and
29
- // / not read any contents of the accumulator.
23
+ // / FrozenMultiMap (which uses only a vector internally). The cached value is
24
+ // / computed by a passed in std::function. The std::function is able to map
25
+ // / multiple values to a specific key via the out array.
30
26
// /
31
27
// / NOTE: We store the (size, length) of each ArrayRef<ValueTy> instead of
32
28
// / storing the ArrayRef to avoid data invalidation issues caused by SmallVector
33
29
// / switching from small to large representations.
34
30
// /
35
31
// / For an example of a subclass implementation see:
36
32
// / unittests/Basic/MultiMapCacheTest.cpp.
37
- template <typename ImplType, typename KeyTy, typename ValueTy,
33
+ template <typename KeyTy, typename ValueTy,
38
34
typename MapTy =
39
35
llvm::DenseMap<KeyTy, Optional<std::tuple<unsigned , unsigned >>>,
40
36
typename VectorTy = std::vector<ValueTy>,
41
37
typename VectorTyImpl = VectorTy>
42
38
class MultiMapCache {
39
+ std::function<bool (const KeyTy &, VectorTyImpl &)> function;
43
40
MapTy valueToDataOffsetIndexMap;
44
41
VectorTy data;
45
42
46
43
constexpr static unsigned ArrayStartOffset = 0 ;
47
44
constexpr static unsigned ArrayLengthOffset = 1 ;
48
45
49
- constexpr ImplType &asImpl () const {
50
- auto *self = const_cast <MultiMapCache *>(this );
51
- return reinterpret_cast <ImplType &>(*self);
52
- }
53
-
54
46
public:
47
+ MultiMapCache (std::function<bool (const KeyTy &, VectorTyImpl &)> function)
48
+ : function(function) {}
49
+
55
50
void clear () {
56
51
valueToDataOffsetIndexMap.clear ();
57
52
data.clear ();
@@ -81,7 +76,7 @@ class MultiMapCache {
81
76
82
77
// We assume that constructValuesForKey /only/ inserts to the end of data
83
78
// and does not inspect any other values in the data array.
84
- if (!asImpl (). constructValuesForKey (key, data)) {
79
+ if (!function (key, data)) {
85
80
return None;
86
81
}
87
82
@@ -94,9 +89,9 @@ class MultiMapCache {
94
89
}
95
90
};
96
91
97
- template <typename ImplType, typename KeyTy, typename ValueTy>
92
+ template <typename KeyTy, typename ValueTy>
98
93
using SmallMultiMapCache = MultiMapCache<
99
- ImplType, KeyTy, ValueTy,
94
+ KeyTy, ValueTy,
100
95
llvm::SmallDenseMap<KeyTy, Optional<std::tuple<unsigned , unsigned >>, 8 >,
101
96
SmallVector<ValueTy, 32 >, SmallVectorImpl<ValueTy>>;
102
97
0 commit comments