26
26
27
27
#include < thrift/lib/cpp2/Flags.h>
28
28
#include < thrift/lib/cpp2/async/RpcOptions.h>
29
+ #include < thrift/lib/cpp2/transport/rocket/framing/parser/AlignedParserStrategy.h>
29
30
#include < thrift/lib/cpp2/transport/rocket/framing/parser/AllocatingParserStrategy.h>
30
31
#include < thrift/lib/cpp2/transport/rocket/framing/parser/FrameLengthParserStrategy.h>
31
32
#include < thrift/lib/cpp2/transport/rocket/framing/parser/ParserStrategy.h>
@@ -35,33 +36,42 @@ THRIFT_FLAG_DECLARE_string(rocket_frame_parser);
35
36
namespace apache ::thrift::rocket {
36
37
37
38
namespace detail {
38
- enum class ParserMode { STRATEGY, ALLOCATING };
39
+ enum class ParserMode { STRATEGY, ALLOCATING, ALIGNED };
39
40
ParserMode stringToMode (const std::string& modeStr) noexcept ;
40
41
ParserAllocatorType& getDefaultAllocator ();
41
42
} // namespace detail
42
43
43
- // TODO (T160861572): deprecate most of logic in this class and replace with
44
- // either AllocatingParserStrategy or FrameLengthParserStrategy
45
44
template <class T >
46
45
class Parser final : public folly::AsyncTransport::ReadCallback {
46
+ using FrameLengthParser = ParserStrategy<T, FrameLengthParserStrategy>;
47
+ using AllocatingParser =
48
+ ParserStrategy<T, AllocatingParserStrategy, ParserAllocatorType>;
49
+ using AlignedParser = ParserStrategy<T, AlignedParserStrategy>;
50
+ using ParserVariant = std::variant<
51
+ std::monostate,
52
+ FrameLengthParser,
53
+ AllocatingParser,
54
+ AlignedParser>;
55
+
47
56
public:
48
57
explicit Parser (
49
58
T& owner, std::shared_ptr<ParserAllocatorType> alloc = nullptr )
50
59
: owner_(owner),
51
60
mode_(detail::stringToMode(THRIFT_FLAG(rocket_frame_parser))) {
52
- if (mode_ == detail::ParserMode::STRATEGY) {
53
- frameLengthParser_ =
54
- std::make_unique<ParserStrategy<T, FrameLengthParserStrategy>>(
55
- owner_);
56
- }
57
- if (mode_ == detail::ParserMode::ALLOCATING) {
58
- allocatingParser_ = std::make_unique<
59
- ParserStrategy<T, AllocatingParserStrategy, ParserAllocatorType>>(
60
- owner_, alloc ? *alloc : detail::getDefaultAllocator ());
61
+ switch (mode_) {
62
+ case detail::ParserMode::STRATEGY: {
63
+ parser_.template emplace <FrameLengthParser>(owner_);
64
+ } break ;
65
+ case detail::ParserMode::ALLOCATING: {
66
+ parser_.template emplace <AllocatingParser>(
67
+ owner_, alloc ? *alloc : detail::getDefaultAllocator ());
68
+ } break ;
69
+ case detail::ParserMode::ALIGNED:
70
+ parser_.template emplace <AlignedParser>(owner_);
71
+ break ;
61
72
}
62
73
}
63
74
64
- // AsyncTransport::ReadCallback implementation
65
75
FOLLY_NOINLINE void getReadBuffer (void ** bufout, size_t * lenout) override ;
66
76
FOLLY_NOINLINE void readDataAvailable (size_t nbytes) noexcept override ;
67
77
FOLLY_NOINLINE void readEOF () noexcept override ;
@@ -80,37 +90,46 @@ class Parser final : public folly::AsyncTransport::ReadCallback {
80
90
T& owner_;
81
91
82
92
detail::ParserMode mode_;
83
- std::unique_ptr<ParserStrategy<T, FrameLengthParserStrategy>>
84
- frameLengthParser_;
85
- std::unique_ptr<
86
- ParserStrategy<T, AllocatingParserStrategy, ParserAllocatorType>>
87
- allocatingParser_;
93
+ ParserVariant parser_;
94
+
95
+ template <typename DelegateFunc>
96
+ FOLLY_ALWAYS_INLINE decltype (auto ) visit(DelegateFunc&& delegate);
88
97
};
89
98
90
99
template <class T >
91
- void Parser<T>::getReadBuffer(void ** bufout, size_t * lenout) {
100
+ template <typename DelegateFunc>
101
+ FOLLY_ALWAYS_INLINE decltype (auto ) Parser<T>::visit(DelegateFunc&& delegate) {
102
+ FOLLY_SAFE_DCHECK (
103
+ std::holds_alternative<std::monostate>(parser_) == false ,
104
+ " parser variant must be set" );
92
105
switch (mode_) {
93
- case (detail::ParserMode::STRATEGY):
94
- frameLengthParser_->getReadBuffer (bufout, lenout);
95
- break ;
96
- case (detail::ParserMode::ALLOCATING):
97
- allocatingParser_->getReadBuffer (bufout, lenout);
98
- break ;
106
+ case detail::ParserMode::STRATEGY:
107
+ return std::invoke (
108
+ std::forward<DelegateFunc>(delegate),
109
+ std::get<FrameLengthParser>(parser_));
110
+ case detail::ParserMode::ALLOCATING:
111
+ return std::invoke (
112
+ std::forward<DelegateFunc>(delegate),
113
+ std::get<AllocatingParser>(parser_));
114
+ case detail::ParserMode::ALIGNED:
115
+ return std::invoke (
116
+ std::forward<DelegateFunc>(delegate),
117
+ std::get<AlignedParser>(parser_));
118
+ default :
119
+ LOG (FATAL) << " Unknown parser type" ;
99
120
}
100
121
}
101
122
123
+ template <class T >
124
+ void Parser<T>::getReadBuffer(void ** bufout, size_t * lenout) {
125
+ visit ([&](auto & parser) { parser.getReadBuffer (bufout, lenout); });
126
+ }
127
+
102
128
template <class T >
103
129
void Parser<T>::readDataAvailable(size_t nbytes) noexcept {
104
130
folly::DelayedDestruction::DestructorGuard dg (&this ->owner_ );
105
131
try {
106
- switch (mode_) {
107
- case (detail::ParserMode::STRATEGY):
108
- frameLengthParser_->readDataAvailable (nbytes);
109
- break ;
110
- case (detail::ParserMode::ALLOCATING):
111
- allocatingParser_->readDataAvailable (nbytes);
112
- break ;
113
- }
132
+ visit ([&](auto & parser) { parser.readDataAvailable (nbytes); });
114
133
} catch (...) {
115
134
auto exceptionStr =
116
135
folly::exceptionStr (folly::current_exception ()).toStdString ();
@@ -140,15 +159,7 @@ void Parser<T>::readBufferAvailable(
140
159
std::unique_ptr<folly::IOBuf> buf) noexcept {
141
160
folly::DelayedDestruction::DestructorGuard dg (&this ->owner_ );
142
161
try {
143
- switch (mode_) {
144
- case (detail::ParserMode::STRATEGY):
145
- frameLengthParser_->readBufferAvailable (std::move (buf));
146
- break ;
147
- case (detail::ParserMode::ALLOCATING):
148
- // Will throw not implemented runtime exception
149
- allocatingParser_->readBufferAvailable (std::move (buf));
150
- break ;
151
- }
162
+ visit ([&](auto & parser) { parser.readBufferAvailable (std::move (buf)); });
152
163
} catch (...) {
153
164
auto exceptionStr =
154
165
folly::exceptionStr (folly::current_exception ()).toStdString ();
0 commit comments