@@ -57,27 +57,30 @@ BufferingConsumer::BufferingConsumer(const std::vector<oid_t> &cols,
57
57
for (oid_t col_id : cols) {
58
58
output_ais_.push_back (context.Find (col_id));
59
59
}
60
- state.output = &tuples_;
61
60
}
62
61
63
- // Append the array of values (i.e., a tuple) into the consumer's buffer of
64
- // output tuples.
65
- void BufferingConsumer::BufferTuple (char *state, char *tuple,
62
+ // Append the array of row attributes to the buffer of tuples
63
+ //
64
+ // Note: buffering consumers rely on an ugly mutex to protect access to the
65
+ // output buffer. This is ugly AF. We don't actually use it for primary
66
+ // query processing, so it's okay.
67
+ void BufferingConsumer::BufferTuple (char *opaque_state, char *tuple,
66
68
uint32_t num_cols) {
67
- BufferingState *buffer_state = reinterpret_cast <BufferingState *>(state);
68
- buffer_state->output ->emplace_back (
69
- reinterpret_cast <peloton::type::Value *>(tuple), num_cols);
69
+ auto *buffer = reinterpret_cast <Buffer *>(opaque_state);
70
+ std::lock_guard<std::mutex> lock{buffer->mutex };
71
+ buffer->output .emplace_back (reinterpret_cast <peloton::type::Value *>(tuple),
72
+ num_cols);
70
73
}
71
74
72
75
// Create two pieces of state: a pointer to the output tuple vector and an
73
76
// on-stack value array representing a single tuple.
74
- void BufferingConsumer::Prepare (CompilationContext &ctx ) {
77
+ void BufferingConsumer::Prepare (CompilationContext &compilation_ctx ) {
75
78
// Be sure to call our parent
76
- ExecutionConsumer::Prepare (ctx );
79
+ ExecutionConsumer::Prepare (compilation_ctx );
77
80
78
81
// Install a little char* for the state we need
79
- CodeGen &codegen = ctx .GetCodeGen ();
80
- QueryState &query_state = ctx .GetQueryState ();
82
+ CodeGen &codegen = compilation_ctx .GetCodeGen ();
83
+ QueryState &query_state = compilation_ctx .GetQueryState ();
81
84
consumer_state_id_ =
82
85
query_state.RegisterState (" consumerState" , codegen.CharPtrType ());
83
86
}
@@ -137,12 +140,23 @@ void BufferingConsumer::ConsumeResult(ConsumerContext &ctx,
137
140
codegen.CallFunc (output_func, args);
138
141
}
139
142
143
+ auto &query_state = ctx.GetQueryState ();
144
+ llvm::Value *buffer_ptr =
145
+ query_state.LoadStateValue (codegen, consumer_state_id_);
146
+
140
147
// Append the tuple to the output buffer (by calling BufferTuple(...))
141
- auto *consumer_state = GetStateValue (ctx, consumer_state_id_);
142
- std::vector<llvm::Value *> args = {consumer_state, tuple_buffer_,
148
+ std::vector<llvm::Value *> args = {buffer_ptr, tuple_buffer_,
143
149
codegen.Const32 (output_ais_.size ())};
144
150
codegen.Call (BufferingConsumerProxy::BufferTuple, args);
145
151
}
146
152
153
+ char *BufferingConsumer::GetConsumerState () {
154
+ return reinterpret_cast <char *>(&buffer_);
155
+ }
156
+
157
+ const std::vector<WrappedTuple> &BufferingConsumer::GetOutputTuples () const {
158
+ return buffer_.output ;
159
+ }
160
+
147
161
} // namespace codegen
148
162
} // namespace peloton
0 commit comments