24
24
#include " AqlCallList.h"
25
25
26
26
#include " Basics/StaticStrings.h"
27
+ #include " Basics/debugging.h"
27
28
#include " Basics/voc-errors.h"
28
29
#include " Containers/Enumerate.h"
29
30
#include " Logger/LogMacros.h"
30
31
#include " Logger/Logger.h"
31
32
32
33
#include < velocypack/Builder.h>
33
- #include < velocypack/Collection .h>
34
+ #include < velocypack/Iterator .h>
34
35
#include < velocypack/Slice.h>
35
36
37
+ #include < algorithm>
38
+ #include < array>
36
39
#include < iostream>
37
- #include < map>
38
40
#include < string_view>
39
41
40
42
using namespace arangodb ;
41
43
using namespace arangodb ::aql;
42
44
43
- namespace {
44
- // hack for MSVC
45
- auto getStringView (VPackSlice slice) -> std::string_view {
46
- std::string_view ref = slice.stringView ();
47
- return std::string_view (ref.data (), ref.size ());
48
- }
49
- } // namespace
50
-
51
45
AqlCallList::AqlCallList (AqlCall const & call) : _specificCalls{call} {
52
46
// We can never create a new CallList with existing skipCounter
53
47
TRI_ASSERT (call.getSkipCount () == 0 );
@@ -66,7 +60,7 @@ AqlCallList::AqlCallList(AqlCall const& specificCall,
66
60
if (!_specificCalls.empty ()) {
67
61
// We only implemented for a single given call.
68
62
TRI_ASSERT (_specificCalls.size () == 1 );
69
- auto res = _specificCalls.back ();
63
+ auto res = std::move ( _specificCalls.back () );
70
64
_specificCalls.pop_back ();
71
65
return res;
72
66
}
@@ -121,9 +115,13 @@ auto AqlCallList::fromVelocyPack(VPackSlice slice) -> ResultT<AqlCallList> {
121
115
slice.typeName ());
122
116
}
123
117
124
- auto expectedPropertiesFound = std::map<std::string_view, bool >{};
125
- expectedPropertiesFound.emplace (StaticStrings::AqlCallListSpecific, false );
126
- expectedPropertiesFound.emplace (StaticStrings::AqlCallListDefault, false );
118
+ // we only have 2 different keys to check. using an std::map requires
119
+ // dynamic memory allocation and would be wasteful. instead, use a simple
120
+ // std::array here to get rid of any allocations
121
+ auto expectedPropertiesFound =
122
+ std::array<std::pair<std::string_view, bool >, 2 >{
123
+ {{StaticStrings::AqlCallListSpecific, false },
124
+ {StaticStrings::AqlCallListDefault, false }}};
127
125
128
126
auto const readSpecific =
129
127
[](velocypack::Slice slice) -> ResultT<std::vector<AqlCall>> {
@@ -137,7 +135,7 @@ auto AqlCallList::fromVelocyPack(VPackSlice slice) -> ResultT<AqlCallList> {
137
135
}
138
136
std::vector<AqlCall> res;
139
137
res.reserve (slice.length ());
140
- for (VPackSlice const c : VPackArrayIterator (slice)) {
138
+ for (VPackSlice c : VPackArrayIterator (slice)) {
141
139
auto maybeAqlCall = AqlCall::fromVelocyPack (c);
142
140
if (ADB_UNLIKELY (maybeAqlCall.fail ())) {
143
141
auto message = std::string{" When deserializing AqlCallList: entry " };
@@ -146,14 +144,17 @@ auto AqlCallList::fromVelocyPack(VPackSlice slice) -> ResultT<AqlCallList> {
146
144
message += maybeAqlCall.errorMessage ();
147
145
return Result (TRI_ERROR_TYPE_ERROR, std::move (message));
148
146
}
149
- res.emplace_back (maybeAqlCall.get ());
147
+ res.emplace_back (std::move ( maybeAqlCall.get () ));
150
148
}
151
149
return res;
152
150
};
153
151
154
152
auto const readDefault =
155
153
[](velocypack::Slice slice) -> ResultT<std::optional<AqlCall>> {
156
- if (ADB_UNLIKELY (!slice.isObject () && !slice.isNull ())) {
154
+ if (slice.isNull ()) {
155
+ return {std::nullopt};
156
+ }
157
+ if (ADB_UNLIKELY (!slice.isObject ())) {
157
158
auto message =
158
159
std::string{" When deserializating AqlCallList: When reading " +
159
160
StaticStrings::AqlCallListDefault +
@@ -162,9 +163,6 @@ auto AqlCallList::fromVelocyPack(VPackSlice slice) -> ResultT<AqlCallList> {
162
163
message += slice.typeName ();
163
164
return Result (TRI_ERROR_TYPE_ERROR, std::move (message));
164
165
}
165
- if (slice.isNull ()) {
166
- return {std::nullopt};
167
- }
168
166
auto maybeAqlCall = AqlCall::fromVelocyPack (slice);
169
167
if (ADB_UNLIKELY (maybeAqlCall.fail ())) {
170
168
auto message = std::string{" When deserializing AqlCallList: default " };
@@ -177,20 +175,13 @@ auto AqlCallList::fromVelocyPack(VPackSlice slice) -> ResultT<AqlCallList> {
177
175
AqlCallList result{AqlCall{}};
178
176
179
177
for (auto const it : velocypack::ObjectIterator (slice)) {
180
- auto const keySlice = it.key ;
181
- if (ADB_UNLIKELY (!keySlice.isString ())) {
182
- return Result (TRI_ERROR_TYPE_ERROR,
183
- " When deserializating AqlCallList: Key is not a string" );
184
- }
185
- auto const key = getStringView (keySlice);
178
+ auto key = it.key .stringView ();
186
179
187
- if (auto propIt = expectedPropertiesFound.find (key);
180
+ if (auto propIt = std::find_if (
181
+ expectedPropertiesFound.begin (), expectedPropertiesFound.end (),
182
+ [&key](auto const & epf) { return epf.first == key; });
188
183
ADB_LIKELY (propIt != expectedPropertiesFound.end ())) {
189
- if (ADB_UNLIKELY (propIt->second )) {
190
- return Result (
191
- TRI_ERROR_TYPE_ERROR,
192
- " When deserializating AqlCallList: Encountered duplicate key" );
193
- }
184
+ TRI_ASSERT (!propIt->second );
194
185
propIt->second = true ;
195
186
}
196
187
0 commit comments