Project
Loading...
Searching...
No Matches
test_TableBuilder.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include <catch_amalgamated.hpp>
13
15#include "Framework/Output.h"
16#include <arrow/table.h>
17#include <arrow/ipc/writer.h>
18#include <arrow/io/memory.h>
19#include <arrow/ipc/writer.h>
20#include <arrow/ipc/reader.h>
21
22using namespace o2::framework;
23
24// We use a different namespace to avoid clashes with the
25// test_ASoA.cxx test.
26namespace test2
27{
28DECLARE_SOA_COLUMN_FULL(X, x, uint64_t, "x");
29DECLARE_SOA_COLUMN_FULL(Y, y, uint64_t, "y");
30DECLARE_SOA_COLUMN_FULL(Pos, pos, int[4], "pos");
31} // namespace test2
32
35
36TEST_CASE("TestTableBuilder")
37{
38 using namespace o2::framework;
39 TableBuilder builder;
40 auto rowWriter = builder.persist<uint64_t, uint64_t>({"x", "y"});
41 rowWriter(0, 0, 0);
42 rowWriter(0, 10, 1);
43 rowWriter(0, 20, 2);
44 rowWriter(0, 30, 3);
45 rowWriter(0, 40, 4);
46 rowWriter(0, 50, 5);
47 rowWriter(0, 60, 6);
48 rowWriter(0, 70, 7);
49 auto table = builder.finalize();
50 REQUIRE(table->num_columns() == 2);
51 REQUIRE(table->num_rows() == 8);
52 REQUIRE(table->schema()->field(0)->name() == "x");
53 REQUIRE(table->schema()->field(1)->name() == "y");
54 REQUIRE(table->schema()->field(0)->type()->id() == arrow::uint64()->id());
55 REQUIRE(table->schema()->field(1)->type()->id() == arrow::uint64()->id());
56
57 auto readBack = TestTable{table};
58
59 auto readBackTable = readBack.asArrowTable();
60 REQUIRE(readBackTable->num_columns() == 2);
61 REQUIRE(readBackTable->num_rows() == 8);
62 REQUIRE(readBackTable->schema()->field(0)->name() == "x");
63 REQUIRE(readBackTable->schema()->field(1)->name() == "y");
64 REQUIRE(readBackTable->schema()->field(0)->type()->id() == arrow::uint64()->id());
65 REQUIRE(readBackTable->schema()->field(1)->type()->id() == arrow::uint64()->id());
66 size_t i = 0;
67 SECTION("Check")
68 {
69 for (auto const& row : readBack) {
70 REQUIRE(row.x() == i * 10);
71 REQUIRE(row.y() == i);
72 ++i;
73 }
74 }
75}
76
77TEST_CASE("TestTableBuilderArray")
78{
79 using namespace o2::framework;
80 TableBuilder builder;
81 const int numElem = 4;
82 auto rowWriter = builder.persist<int[numElem]>({"pos"});
83 int a[numElem] = {1, 10, 300, 350};
84 int b[numElem] = {0, 20, 30, 40};
85 rowWriter(0, a);
86 rowWriter(0, b);
87 using v3 = std::array<int, numElem>;
88 rowWriter(0, v3{0, 11, 123, 256}.data());
89 auto table = builder.finalize();
90
91 REQUIRE(table->num_columns() == 1);
92 REQUIRE(table->num_rows() == 3);
93 REQUIRE(table->schema()->field(0)->name() == "pos");
94 REQUIRE(table->schema()->field(0)->type()->id() == arrow::fixed_size_list(arrow::int32(), numElem)->id());
95
96 auto chunkToUse = table->column(0)->chunk(0);
97 chunkToUse = std::static_pointer_cast<arrow::FixedSizeListArray>(chunkToUse)->values();
98 auto data = chunkToUse->data();
99
100 REQUIRE(data->GetValues<int>(1)[0] == 1);
101 REQUIRE(data->GetValues<int>(1)[1] == 10);
102 REQUIRE(data->GetValues<int>(1)[2] == 300);
103 REQUIRE(data->GetValues<int>(1)[3] == 350);
104 REQUIRE(data->GetValues<int>(1)[4] == 0);
105 REQUIRE(data->GetValues<int>(1)[5] == 20);
106 REQUIRE(data->GetValues<int>(1)[6] == 30);
107 REQUIRE(data->GetValues<int>(1)[7] == 40);
108
109 auto readBack = ArrayTable{table};
110 auto row = readBack.begin();
111
112 REQUIRE(row.pos()[0] == 1);
113 REQUIRE(row.pos()[1] == 10);
114 REQUIRE(row.pos()[2] == 300);
115 REQUIRE(row.pos()[3] == 350);
116
117 row++;
118 REQUIRE(row.pos()[0] == 0);
119 REQUIRE(row.pos()[1] == 20);
120 REQUIRE(row.pos()[2] == 30);
121 REQUIRE(row.pos()[3] == 40);
122
123 row++;
124 REQUIRE(row.pos()[0] == 0);
125 REQUIRE(row.pos()[1] == 11);
126 REQUIRE(row.pos()[2] == 123);
127 REQUIRE(row.pos()[3] == 256);
128}
129
130TEST_CASE("TestTableBuilderStruct")
131{
132 using namespace o2::framework;
133 TableBuilder builder;
134 struct Foo {
135 uint64_t x;
136 uint64_t y;
137 };
138 auto rowWriter = builder.persist<Foo>({"x", "y"});
139 rowWriter(0, Foo{0, 0});
140 rowWriter(0, Foo{10, 1});
141 rowWriter(0, Foo{20, 2});
142 rowWriter(0, Foo{30, 3});
143 rowWriter(0, Foo{40, 4});
144 rowWriter(0, Foo{50, 5});
145 rowWriter(0, Foo{60, 6});
146 rowWriter(0, Foo{70, 7});
147 auto table = builder.finalize();
148 REQUIRE(table->num_columns() == 2);
149 REQUIRE(table->num_rows() == 8);
150 REQUIRE(table->schema()->field(0)->name() == "x");
151 REQUIRE(table->schema()->field(1)->name() == "y");
152 REQUIRE(table->schema()->field(0)->type()->id() == arrow::uint64()->id());
153 REQUIRE(table->schema()->field(1)->type()->id() == arrow::uint64()->id());
154
155 auto readBack = TestTable{table};
156
157 size_t i = 0;
158 for (auto& row : readBack) {
159 REQUIRE(row.x() == i * 10);
160 REQUIRE(row.y() == i);
161 ++i;
162 }
163}
164
165TEST_CASE("TestTableBuilderBulk")
166{
167 using namespace o2::framework;
168 TableBuilder builder;
169 auto bulkWriter = builder.bulkPersist<int, int>({"x", "y"}, 10);
170 int x[] = {0, 1, 2, 3, 4, 5, 6, 7};
171 int y[] = {0, 1, 2, 3, 4, 5, 6, 7};
172
173 bulkWriter(0, 8, x, y);
174
175 auto table = builder.finalize();
176 REQUIRE(table->num_columns() == 2);
177 REQUIRE(table->num_rows() == 8);
178 REQUIRE(table->schema()->field(0)->name() == "x");
179 REQUIRE(table->schema()->field(1)->name() == "y");
180 REQUIRE(table->schema()->field(0)->type()->id() == arrow::int32()->id());
181 REQUIRE(table->schema()->field(1)->type()->id() == arrow::int32()->id());
182
183 for (int64_t i = 0; i < 8; ++i) {
184 auto p = std::dynamic_pointer_cast<arrow::NumericArray<arrow::Int32Type>>(table->column(0)->chunk(0));
185 REQUIRE(p->Value(i) == i);
186 }
187}
188
189TEST_CASE("TestTableBuilderMore")
190{
191 using namespace o2::framework;
192 TableBuilder builder;
193 auto rowWriter = builder.persist<int, float, std::string, bool>({"x", "y", "s", "b"});
195 rowWriter(0, 0, 0., "foo", true);
196 rowWriter(0, 1, 1., "bar", false);
197 rowWriter(0, 2, 2., "fbr", false);
198 rowWriter(0, 3, 3., "bar", false);
199 rowWriter(0, 4, 4., "abr", true);
200 rowWriter(0, 5, 5., "aaa", false);
201 rowWriter(0, 6, 6., "bbb", true);
202 rowWriter(0, 7, 7., "ccc", false);
203 auto table = builder.finalize();
204 REQUIRE(table->num_columns() == 4);
205 REQUIRE(table->num_rows() == 8);
206 REQUIRE(table->schema()->field(0)->name() == "x");
207 REQUIRE(table->schema()->field(1)->name() == "y");
208 REQUIRE(table->schema()->field(2)->name() == "s");
209 REQUIRE(table->schema()->field(3)->name() == "b");
210 REQUIRE(table->schema()->field(0)->type()->id() == arrow::int32()->id());
211 REQUIRE(table->schema()->field(1)->type()->id() == arrow::float32()->id());
212 REQUIRE(table->schema()->field(2)->type()->id() == arrow::utf8()->id());
213 REQUIRE(table->schema()->field(3)->type()->id() == arrow::boolean()->id());
214}
215
216TEST_CASE("TestSoAIntegration")
217{
218 TableBuilder builder;
219 auto rowWriter = builder.cursor<TestTable>();
220 rowWriter(0, 0, 0);
221 rowWriter(0, 10, 1);
222 rowWriter(0, 20, 2);
223 rowWriter(0, 30, 3);
224 rowWriter(0, 40, 4);
225 rowWriter(0, 50, 5);
226 auto table = builder.finalize();
227 auto readBack = TestTable{table};
228
229 size_t i = 0;
230 for (auto& row : readBack) {
231 REQUIRE(row.x() == i * 10);
232 REQUIRE(row.y() == i);
233 ++i;
234 }
235}
236
237TEST_CASE("TestDataAllocatorReturnType")
238{
239 const Output output{"TST", "DUMMY", 0};
240}
241
242TEST_CASE("TestPodInjestion")
243{
244 struct A {
245 uint64_t x;
246 uint64_t y;
247 };
248 TableBuilder builder;
249 auto rowWriter = builder.cursor<TestTable, A>();
250 rowWriter(0, A{0, 0});
251 rowWriter(0, A{10, 1});
252 rowWriter(0, A{20, 2});
253 rowWriter(0, A{30, 3});
254 rowWriter(0, A{40, 4});
255 rowWriter(0, A{50, 5});
256 auto table = builder.finalize();
257 auto readBack = TestTable{table};
258
259 size_t i = 0;
260 for (auto& row : readBack) {
261 REQUIRE(row.x() == i * 10);
262 REQUIRE(row.y() == i);
263 ++i;
264 }
265}
266
267TEST_CASE("TestColumnCount")
268{
269 struct Foo {
270 int x;
271 int y;
272 };
273 struct Bar {
274 int x;
275 int y;
276 std::string s;
277 };
278 struct FooBar {
279 int x;
280 int y;
281 float f;
282 };
283 REQUIRE(TableBuilder::countColumns<Foo>() == 2);
284 REQUIRE(TableBuilder::countColumns<Bar>() == 3);
285 REQUIRE(TableBuilder::countColumns<FooBar>() == 3);
286 int count = TableBuilder::countColumns<float, int>();
287 REQUIRE(count == 2);
288 int count2 = TableBuilder::countColumns<float, int, char[3]>();
289 REQUIRE(count2 == 3);
290}
291
292TEST_CASE("TestMakeFields")
293{
294 auto fields = TableBuilderHelpers::makeFields<int, float>({"i", "f"});
295 REQUIRE(fields.size() == 2);
296 REQUIRE(fields[0]->name() == "i");
297 REQUIRE(fields[1]->name() == "f");
298 REQUIRE(fields[0]->type()->name() == "int32");
299 REQUIRE(fields[1]->type()->name() == "float");
300}
#define DECLARE_SOA_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_)
Definition ASoA.h:2285
int32_t i
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
uint16_t pos
Definition RawData.h:3
Definition A.h:16
auto bulkPersist(std::array< char const *, NCOLUMNS > const &columnNames, size_t nRows)
auto reserve(o2::framework::pack< ARGS... > &&, int s)
auto persist(std::array< char const *, sizeof...(ARGS)+1 > const &columnNames)
std::shared_ptr< arrow::Table > finalize()
unfiltered_iterator begin()
Definition ASoA.h:1966
std::shared_ptr< arrow::Table > asArrowTable() const
Return a type erased arrow table backing store for / the type safe table.
Definition ASoA.h:2008
GLint GLenum GLint x
Definition glcorearb.h:403
GLint GLsizei count
Definition glcorearb.h:399
GLuint const GLchar * name
Definition glcorearb.h:781
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLint y
Definition glcorearb.h:270
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLboolean * data
Definition glcorearb.h:298
GLfloat GLfloat GLfloat GLfloat v3
Definition glcorearb.h:814
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
TEST_CASE("test_prepareArguments")
o2::soa::InPlaceTable< 0, test2::X, test2::Y > TestTable
std::vector< int > row