Skip to content

Commit 57d9f29

Browse files
authored
Avoid copying the result of a successful outcome (#100)
Adding rvalue ref-qualifiers to the 'outcome' class getters enables moving out the result instead of copying it. In this case, we can avoid copying the request payload. * Remove static modifier from inline header functions static inline makes no sense in a header file.
1 parent 17473f8 commit 57d9f29

File tree

3 files changed

+41
-17
lines changed

3 files changed

+41
-17
lines changed

include/aws/lambda-runtime/outcome.h

+36-12
Original file line numberDiff line numberDiff line change
@@ -23,48 +23,72 @@ namespace lambda_runtime {
2323
template <typename TResult, typename TFailure>
2424
class outcome {
2525
public:
26-
outcome(TResult const& s) : s(s), m_success(true) {}
26+
outcome(TResult const& s) : m_s(s), m_success(true) {}
27+
outcome(TResult&& s) : m_s(std::move(s)), m_success(true) {}
2728

28-
outcome(TFailure const& f) : f(f), m_success(false) {}
29+
outcome(TFailure const& f) : m_f(f), m_success(false) {}
30+
outcome(TFailure&& f) : m_f(std::move(f)), m_success(false) {}
31+
32+
outcome(outcome const& other) : m_success(other.m_success)
33+
{
34+
if (m_success) {
35+
new (&m_s) TResult(other.m_s);
36+
}
37+
else {
38+
new (&m_f) TFailure(other.m_f);
39+
}
40+
}
2941

3042
outcome(outcome&& other) noexcept : m_success(other.m_success)
3143
{
3244
if (m_success) {
33-
s = std::move(other.s);
45+
new (&m_s) TResult(std::move(other.m_s));
3446
}
3547
else {
36-
f = std::move(other.f);
48+
new (&m_f) TFailure(std::move(other.m_f));
3749
}
3850
}
3951

4052
~outcome()
4153
{
4254
if (m_success) {
43-
s.~TResult();
55+
m_s.~TResult();
4456
}
4557
else {
46-
f.~TFailure();
58+
m_f.~TFailure();
4759
}
4860
}
4961

50-
TResult const& get_result() const
62+
TResult const& get_result() const&
5163
{
5264
assert(m_success);
53-
return s;
65+
return m_s;
66+
}
67+
68+
TResult&& get_result() &&
69+
{
70+
assert(m_success);
71+
return std::move(m_s);
72+
}
73+
74+
TFailure const& get_failure() const&
75+
{
76+
assert(!m_success);
77+
return m_f;
5478
}
5579

56-
TFailure const& get_failure() const
80+
TFailure&& get_failure() &&
5781
{
5882
assert(!m_success);
59-
return f;
83+
return std::move(m_f);
6084
}
6185

6286
bool is_success() const { return m_success; }
6387

6488
private:
6589
union {
66-
TResult s;
67-
TFailure f;
90+
TResult m_s;
91+
TFailure m_f;
6892
};
6993
bool m_success;
7094
};

include/aws/logging/logging.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ enum class verbosity {
2727

2828
void log(verbosity v, char const* tag, char const* msg, va_list args);
2929

30-
[[gnu::format(printf, 2, 3)]] static inline void log_error(char const* tag, char const* msg, ...)
30+
[[gnu::format(printf, 2, 3)]] inline void log_error(char const* tag, char const* msg, ...)
3131
{
3232
va_list args;
3333
va_start(args, msg);
@@ -37,7 +37,7 @@ void log(verbosity v, char const* tag, char const* msg, va_list args);
3737
(void)msg;
3838
}
3939

40-
[[gnu::format(printf, 2, 3)]] static inline void log_info(char const* tag, char const* msg, ...)
40+
[[gnu::format(printf, 2, 3)]] inline void log_info(char const* tag, char const* msg, ...)
4141
{
4242
#if AWS_LAMBDA_LOG >= 1
4343
va_list args;
@@ -50,7 +50,7 @@ void log(verbosity v, char const* tag, char const* msg, va_list args);
5050
#endif
5151
}
5252

53-
[[gnu::format(printf, 2, 3)]] static inline void log_debug(char const* tag, char const* msg, ...)
53+
[[gnu::format(printf, 2, 3)]] inline void log_debug(char const* tag, char const* msg, ...)
5454
{
5555
#if AWS_LAMBDA_LOG >= 2
5656
va_list args;

src/runtime.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ void run_handler(std::function<invocation_response(invocation_request const&)> c
412412
size_t const max_retries = 3;
413413

414414
while (retries < max_retries) {
415-
const auto next_outcome = rt.get_next();
415+
auto next_outcome = rt.get_next();
416416
if (!next_outcome.is_success()) {
417417
if (next_outcome.get_failure() == aws::http::response_code::REQUEST_NOT_MADE) {
418418
++retries;
@@ -429,7 +429,7 @@ void run_handler(std::function<invocation_response(invocation_request const&)> c
429429

430430
retries = 0;
431431

432-
auto const& req = next_outcome.get_result();
432+
auto const req = std::move(next_outcome).get_result();
433433
logging::log_info(LOG_TAG, "Invoking user handler");
434434
invocation_response res = handler(req);
435435
logging::log_info(LOG_TAG, "Invoking user handler completed.");

0 commit comments

Comments
 (0)