Skip to content

Commit 7d58894

Browse files
committed
use bulk conversion
1 parent 3a77f95 commit 7d58894

File tree

4 files changed

+132
-62
lines changed

4 files changed

+132
-62
lines changed

Framework/Core/include/Framework/ExpressionJSONHelpers.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
namespace o2::framework
1717
{
1818
struct ExpressionJSONHelpers {
19-
static std::unique_ptr<expressions::Node> read(std::istream& s);
20-
static void write(std::ostream& o, expressions::Node* n);
19+
// static std::unique_ptr<expressions::Node> read(std::istream& s);
20+
static std::vector<expressions::Projector> read(std::istream& s);
21+
static void write(std::ostream& o, std::vector<expressions::Projector>& projectors);
2122
};
2223
} // namespace o2::framework
2324

Framework/Core/src/AODReaderHelpers.cxx

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,28 +44,6 @@ auto setEOSCallback(InitContext& ic)
4444
});
4545
}
4646

47-
template <typename... Ts>
48-
static inline auto doExtractOriginal(framework::pack<Ts...>, ProcessingContext& pc)
49-
{
50-
if constexpr (sizeof...(Ts) == 1) {
51-
return pc.inputs().get<TableConsumer>(aod::MetadataTrait<framework::pack_element_t<0, framework::pack<Ts...>>>::metadata::tableLabel())->asArrowTable();
52-
} else {
53-
return std::vector{pc.inputs().get<TableConsumer>(aod::MetadataTrait<Ts>::metadata::tableLabel())->asArrowTable()...};
54-
}
55-
}
56-
57-
template <typename... Os>
58-
static inline auto extractOriginalsTuple(framework::pack<Os...>, ProcessingContext& pc)
59-
{
60-
return std::make_tuple(extractTypedOriginal<Os>(pc)...);
61-
}
62-
63-
template <typename... Os>
64-
static inline auto extractOriginalsVector(framework::pack<Os...>, ProcessingContext& pc)
65-
{
66-
return std::vector{extractOriginal<Os>(pc)...};
67-
}
68-
6947
template <size_t N, std::array<soa::TableRef, N> refs>
7048
static inline auto extractOriginals(ProcessingContext& pc)
7149
{

Framework/Core/src/ExpressionJSONHelpers.cxx

Lines changed: 110 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222

2323
namespace o2::framework
2424
{
25-
25+
namespace
26+
{
2627
using nodes = expressions::Node::self_t;
2728
enum struct Nodes : int {
2829
NLITERAL = 0,
@@ -46,7 +47,8 @@ struct Entry {
4647
ToWrite toWrite = ToWrite::FULL;
4748
};
4849

49-
std::array<std::string_view, 10> validKeys{
50+
std::array<std::string_view, 11> validKeys{
51+
"projectors",
5052
"kind",
5153
"binding",
5254
"index",
@@ -58,30 +60,30 @@ std::array<std::string_view, 10> validKeys{
5860
"right",
5961
"condition"};
6062

61-
namespace
62-
{
6363
struct ExpressionReader : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>, ExpressionReader> {
6464
using Ch = rapidjson::UTF8<>::Ch;
6565
using SizeType = rapidjson::SizeType;
6666

6767
enum struct State {
68-
IN_START,
69-
IN_STOP,
70-
IN_NODE_LITERAL,
71-
IN_NODE_BINDING,
72-
IN_NODE_OP,
73-
IN_NODE_CONDITIONAL,
74-
IN_ROOT,
75-
IN_LEFT,
76-
IN_RIGHT,
77-
IN_COND,
78-
IN_ERROR
68+
IN_START, // global start
69+
IN_LIST, // opening brace of the list
70+
IN_ROOT, // after encountering the opening of the expression object
71+
IN_LEFT, // in "left" key - subexpression
72+
IN_RIGHT, // in "right" key - subexpression
73+
IN_COND, // in "condition" key - subexpression
74+
IN_NODE_LITERAL, // in literal node
75+
IN_NODE_BINDING, // in binding node
76+
IN_NODE_OP, // in operation node
77+
IN_NODE_CONDITIONAL, // in conditional node
78+
IN_ERROR // generic error state
7979
};
8080

8181
std::stack<State> states;
8282
std::stack<Entry> path;
8383
std::ostringstream debug;
8484

85+
std::vector<expressions::Projector> result;
86+
8587
std::unique_ptr<expressions::Node> rootNode = nullptr;
8688
std::unique_ptr<expressions::Node> node = nullptr;
8789
expressions::LiteralValue::stored_type value;
@@ -101,6 +103,28 @@ struct ExpressionReader : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
101103
states.push(State::IN_START);
102104
}
103105

106+
bool StartArray()
107+
{
108+
debug << "Starting array" << std::endl;
109+
if (states.top() == State::IN_START) {
110+
states.push(State::IN_LIST);
111+
return true;
112+
}
113+
states.push(State::IN_ERROR);
114+
return false;
115+
}
116+
117+
bool EndArray(SizeType)
118+
{
119+
debug << "Ending array" << std::endl;
120+
if (states.top() == State::IN_LIST) {
121+
states.pop();
122+
return true;
123+
}
124+
states.push(State::IN_ERROR);
125+
return false;
126+
}
127+
104128
bool Key(const Ch* str, SizeType, bool)
105129
{
106130
debug << "Key(" << str << ")" << std::endl;
@@ -112,8 +136,13 @@ struct ExpressionReader : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
112136
}
113137

114138
if (states.top() == State::IN_START) {
139+
if (currentKey.compare("projectors") == 0) {
140+
return true;
141+
}
142+
}
143+
144+
if (states.top() == State::IN_ROOT) {
115145
if (currentKey.compare("kind") == 0) {
116-
states.push(State::IN_ROOT);
117146
return true;
118147
} else {
119148
states.push(State::IN_ERROR); // should start from root node
@@ -228,38 +257,62 @@ struct ExpressionReader : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
228257

229258
bool StartObject()
230259
{
260+
// opening brace encountered
231261
debug << "StartObject()" << std::endl;
232-
if (states.top() == State::IN_LEFT || states.top() == State::IN_RIGHT || states.top() == State::IN_COND) { // ready to start a new node
262+
// the first opening brace in the input
263+
if (states.top() == State::IN_START) {
233264
return true;
234265
}
235-
if (states.top() == State::IN_START) {
266+
// the opening of an expression
267+
if (states.top() == State::IN_LIST) {
268+
states.push(State::IN_ROOT);
236269
return true;
237270
}
271+
// if we are looking at subexpression
272+
if (states.top() == State::IN_LEFT || states.top() == State::IN_RIGHT || states.top() == State::IN_COND) { // ready to start a new node
273+
return true;
274+
}
275+
// no other object starts are expected
238276
states.push(State::IN_ERROR);
239277
return false;
240278
}
241279

242280
bool EndObject(SizeType)
243281
{
282+
// closing brace encountered
244283
debug << "EndObject()" << std::endl;
284+
// we are closing up an expression
245285
if (states.top() == State::IN_NODE_LITERAL || states.top() == State::IN_NODE_OP || states.top() == State::IN_NODE_BINDING || states.top() == State::IN_NODE_CONDITIONAL) { // finalize node
246286
// finalize the current node and pop it from the stack (the pointers should be already set
247287
states.pop();
288+
// subexpression
248289
if (states.top() == State::IN_LEFT || states.top() == State::IN_RIGHT || states.top() == State::IN_COND) {
249290
states.pop();
291+
return true;
292+
}
293+
294+
// expression
295+
if (states.top() == State::IN_ROOT) {
296+
result.emplace_back(std::move(rootNode));
297+
states.pop();
298+
return true;
250299
}
251-
return true;
252300
}
253-
if (states.top() == State::IN_ROOT) {
301+
302+
// we are closing the list
303+
if (states.top() == State::IN_START) {
254304
return true;
255305
}
306+
// no other object ends are expectedd
256307
states.push(State::IN_ERROR);
257308
return false;
258309
}
259310

260311
bool Null()
261312
{
313+
// null value
262314
debug << "Null()" << std::endl;
315+
// the subexpression can be empty
263316
if (states.top() == State::IN_LEFT || states.top() == State::IN_RIGHT || states.top() == State::IN_COND) {
264317
// empty node, nothing to do
265318
// move the path state to the next
@@ -281,6 +334,7 @@ struct ExpressionReader : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
281334
bool Bool(bool b)
282335
{
283336
debug << "Bool(" << b << ")" << std::endl;
337+
// can be a value in a literal node
284338
if (states.top() == State::IN_NODE_LITERAL && currentKey.compare("value") == 0) {
285339
value = b;
286340
return true;
@@ -292,6 +346,7 @@ struct ExpressionReader : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
292346
bool Int(int i)
293347
{
294348
debug << "Int(" << i << ")" << std::endl;
349+
// can be a value in a literal node
295350
if (states.top() == State::IN_NODE_LITERAL && currentKey.compare("value") == 0) { // literal
296351
switch (type) {
297352
case atype::INT8:
@@ -312,12 +367,19 @@ struct ExpressionReader : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
312367
case atype::UINT32:
313368
value = i;
314369
break;
370+
case atype::UINT64:
371+
value = (uint64_t)i;
372+
break;
373+
case atype::INT64:
374+
value = (int64_t)i;
375+
break;
315376
default:
316377
states.push(State::IN_ERROR);
317378
return false;
318379
}
319380
return true;
320381
}
382+
// can be a node kind designator
321383
if (states.top() == State::IN_ROOT || states.top() == State::IN_LEFT || states.top() == State::IN_RIGHT || states.top() == State::IN_COND) {
322384
if (currentKey.compare("kind") == 0) {
323385
kind = (Nodes)i;
@@ -347,18 +409,21 @@ struct ExpressionReader : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
347409
}
348410
}
349411
}
412+
// can be node index
350413
if (states.top() == State::IN_NODE_BINDING || states.top() == State::IN_NODE_CONDITIONAL || states.top() == State::IN_NODE_LITERAL || states.top() == State::IN_NODE_OP) {
351414
if (currentKey.compare("index") == 0) {
352415
index = (size_t)i;
353416
return true;
354417
}
355418
}
419+
// can be a node type designator
356420
if (states.top() == State::IN_NODE_LITERAL || states.top() == State::IN_NODE_BINDING) {
357421
if (currentKey.compare("arrow_type") == 0) {
358422
type = (atype::type)i;
359423
return true;
360424
}
361425
}
426+
// can be a node operation designato
362427
if (states.top() == State::IN_NODE_OP && currentKey.compare("operation") == 0) {
363428
operation = (BasicOp)i;
364429
return true;
@@ -370,17 +435,20 @@ struct ExpressionReader : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
370435
bool Uint(unsigned i)
371436
{
372437
debug << "Uint(" << i << ")" << std::endl;
438+
// can be node hash
373439
if (states.top() == State::IN_NODE_BINDING && currentKey.compare("hash") == 0) {
374440
hash = i;
375441
return true;
376442
}
443+
// any positive value will be first read as unsigned, however the actual type is determined by node's arrow_type
377444
debug << ">> falling back to Int" << std::endl;
378445
return Int(i);
379446
}
380447

381448
bool Int64(int64_t i)
382449
{
383450
debug << "Int64(" << i << ")" << std::endl;
451+
// can only be a literal node value
384452
if (states.top() == State::IN_NODE_LITERAL && currentKey.compare("value") == 0) {
385453
value = i;
386454
return true;
@@ -392,6 +460,7 @@ struct ExpressionReader : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
392460
bool Uint64(uint64_t i)
393461
{
394462
debug << "Uint64(" << i << ")" << std::endl;
463+
// can only be a literal node value
395464
if (states.top() == State::IN_NODE_LITERAL && currentKey.compare("value") == 0) {
396465
value = i;
397466
return true;
@@ -403,6 +472,7 @@ struct ExpressionReader : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
403472
bool Double(double d)
404473
{
405474
debug << "Double(" << d << ")" << std::endl;
475+
// can only be a literal node value
406476
if (states.top() == State::IN_NODE_LITERAL) {
407477
switch (type) {
408478
case atype::FLOAT:
@@ -424,6 +494,7 @@ struct ExpressionReader : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
424494
bool String(const Ch* str, SizeType, bool)
425495
{
426496
debug << "String(" << str << ")" << std::endl;
497+
// can only be a binding node
427498
if (states.top() == State::IN_NODE_BINDING && currentKey.compare("binding") == 0) {
428499
binding = str;
429500
return true;
@@ -434,7 +505,7 @@ struct ExpressionReader : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>,
434505
};
435506
} // namespace
436507

437-
std::unique_ptr<expressions::Node> o2::framework::ExpressionJSONHelpers::read(std::istream& s)
508+
std::vector<expressions::Projector> o2::framework::ExpressionJSONHelpers::read(std::istream& s)
438509
{
439510
rapidjson::Reader reader;
440511
rapidjson::IStreamWrapper isw(s);
@@ -446,9 +517,11 @@ std::unique_ptr<expressions::Node> o2::framework::ExpressionJSONHelpers::read(st
446517
error << "Cannot parse serialized Expression, error: " << rapidjson::GetParseError_En(reader.GetParseErrorCode()) << " at offset: " << reader.GetErrorOffset();
447518
throw std::runtime_error(error.str());
448519
}
449-
return std::move(ereader.rootNode);
520+
return std::move(ereader.result);
450521
}
451522

523+
namespace
524+
{
452525
void writeNodeHeader(rapidjson::Writer<rapidjson::OStreamWrapper>& w, expressions::Node const* node)
453526
{
454527
w.Key("kind");
@@ -491,11 +564,8 @@ void writeNodeHeader(rapidjson::Writer<rapidjson::OStreamWrapper>& w, expression
491564
node->self);
492565
}
493566

494-
void writeExpression(std::ostream& o, expressions::Node* n)
567+
void writeExpression(rapidjson::Writer<rapidjson::OStreamWrapper>& w, expressions::Node* n)
495568
{
496-
rapidjson::OStreamWrapper osw(o);
497-
rapidjson::Writer<rapidjson::OStreamWrapper> w(osw);
498-
499569
std::stack<Entry> path;
500570
path.emplace(n, ToWrite::FULL);
501571
while (!path.empty()) {
@@ -551,9 +621,20 @@ void writeExpression(std::ostream& o, expressions::Node* n)
551621
}
552622
}
553623
}
554-
} // namespace o2::framework
624+
} // namespace
555625

556-
void o2::framework::ExpressionJSONHelpers::write(std::ostream& o, expressions::Node* n)
626+
void o2::framework::ExpressionJSONHelpers::write(std::ostream& o, std::vector<o2::framework::expressions::Projector>& projectors)
557627
{
558-
writeExpression(o, n);
628+
rapidjson::OStreamWrapper osw(o);
629+
rapidjson::Writer<rapidjson::OStreamWrapper> w(osw);
630+
w.StartObject();
631+
w.Key("projectors");
632+
w.StartArray();
633+
for (auto& p : projectors) {
634+
writeExpression(w, p.node.get());
635+
}
636+
w.EndArray();
637+
w.EndObject();
559638
}
639+
640+
} // namespace o2::framework

0 commit comments

Comments
 (0)