github.com/rohankumardubey/aresdb@v0.0.2-0.20190517170215-e54e3ca06b9c/query/algorithm_unittest.cu (about) 1 // Copyright (c) 2017-2018 Uber Technologies, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <thrust/transform.h> 16 #include <cstdint> 17 #include <cfloat> 18 #include <algorithm> 19 #include <cmath> 20 #include <exception> 21 #include <iterator> 22 #include <iostream> 23 #include <type_traits> 24 #include "gtest/gtest.h" 25 #include "query/algorithm.hpp" 26 #include "query/iterator.hpp" 27 #include "query/time_series_aggregate.h" 28 #include "query/transform.hpp" 29 #include "query/unittest_utils.hpp" 30 31 namespace ares { 32 33 template<typename TypeA, typename TypeB, typename ExpectedType> 34 void checkCommonTypeAsExpected() { 35 bool isSame = std::is_same<typename common_type<TypeA, TypeB>::type, 36 ExpectedType>::value; 37 EXPECT_TRUE(isSame); 38 } 39 40 // cppcheck-suppress * 41 TEST(CommonTypeTraitsTest, CheckCommonType) { 42 checkCommonTypeAsExpected<float_t, float_t, float_t>(); 43 checkCommonTypeAsExpected<int16_t, float_t, float_t>(); 44 checkCommonTypeAsExpected<float_t, float_t, float_t>(); 45 checkCommonTypeAsExpected<float_t, uint32_t, float_t>(); 46 checkCommonTypeAsExpected<int16_t, uint32_t, int32_t>(); 47 checkCommonTypeAsExpected<int32_t, uint32_t, int32_t>(); 48 checkCommonTypeAsExpected<int32_t, bool, int32_t>(); 49 checkCommonTypeAsExpected<uint32_t, bool, uint32_t>(); 50 checkCommonTypeAsExpected<uint16_t, bool, uint32_t>(); 51 } 52 53 // cppcheck-suppress * 54 TEST(CGoCallResHandleTest, CheckCGoCallResHandle) { 55 CGoCallResHandle resHandle = {0, nullptr}; 56 try { 57 throw std::invalid_argument("test"); 58 } 59 catch (std::exception &e) { 60 resHandle.pStrErr = strdup(e.what()); 61 } 62 63 EXPECT_STREQ(resHandle.pStrErr, "test"); 64 EXPECT_TRUE(resHandle.pStrErr != nullptr); 65 free(const_cast<char *>(resHandle.pStrErr)); 66 CGoCallResHandle resHandle2 = {0, nullptr}; 67 try { 68 printf("test CGoCallResHandle\n"); 69 } 70 catch (std::exception &e) { 71 resHandle2.pStrErr = strdup(e.what()); 72 } 73 74 EXPECT_TRUE(resHandle2.pStrErr == nullptr); 75 } 76 77 // cppcheck-suppress * 78 TEST(UnaryTransformTest, CheckInt) { 79 const int size = 3; 80 uint32_t indexVectorH[size * 2] = {0, 1, 2}; 81 int inputValuesH[size] = {-1, 1, 0}; 82 // T T F 83 uint8_t inputNullsH[1 + ((size - 1) / 8)] = {0x03}; 84 85 int outputValuesH[size] = {0, 0, 0}; 86 bool outputNullsH[size] = {false, false, false}; 87 88 uint32_t *indexVector = allocate(&indexVectorH[0], size * 2); 89 uint8_t *basePtr = 90 allocate_column(nullptr, &inputNullsH[0], &inputValuesH[0], 0, 1, 12); 91 92 uint8_t *outputBasePtr = 93 allocate_column(nullptr, reinterpret_cast<uint8_t *>(&outputValuesH[0]), 94 &outputNullsH[0], 0, 12, 3); 95 96 DefaultValue defaultValue = {false, {.Int32Val = 0}}; 97 VectorPartySlice inputVP = {basePtr, 0, 8, 0, Int32, defaultValue}; 98 99 ScratchSpaceVector outputScratchSpace = {outputBasePtr, 16, Int32}; 100 101 InputVector input = {{.VP = inputVP}, VectorPartyInput}; 102 OutputVector output = 103 {{.ScratchSpace = outputScratchSpace}, ScratchSpaceOutput}; 104 105 UnaryTransform(input, output, indexVector, size, nullptr, 0, 106 Negate, 0, 0); 107 108 int expectedValues[size] = {1, -1, 0}; 109 bool expectedNulls[size] = {true, true, false}; 110 int *outputValues = reinterpret_cast<int *>(outputBasePtr); 111 bool *outputNulls = reinterpret_cast<bool *>(outputBasePtr) + 16; 112 EXPECT_TRUE( 113 equal(outputValues, outputValues + size, 114 &expectedValues[0])); 115 116 EXPECT_TRUE( 117 equal(outputNulls, outputNulls + size, 118 &expectedNulls[0])); 119 120 release(basePtr); 121 release(outputBasePtr); 122 release(indexVector); 123 } 124 125 // cppcheck-suppress * 126 TEST(UnaryTransformTest, CheckConstant) { 127 const int size = 3; 128 uint32_t indexVectorH[size * 2] = {0, 1, 2}; 129 ConstantVector constant = { 130 {.IntVal = 1}, true, ConstInt, 131 }; 132 133 int outputValuesH[size] = {0, 0, 0}; 134 bool outputNullsH[size] = {false, false, false}; 135 136 uint32_t *indexVector = allocate(&indexVectorH[0], size * 2); 137 138 uint8_t *outputBasePtr = 139 allocate_column(nullptr, reinterpret_cast<uint8_t *>(&outputValuesH[0]), 140 &outputNullsH[0], 0, 12, 3); 141 ScratchSpaceVector outputScratchSpace = {outputBasePtr, 16, Int32}; 142 143 InputVector input = {{.Constant = constant}, ConstantInput}; 144 OutputVector output = 145 {{.ScratchSpace = outputScratchSpace}, ScratchSpaceOutput}; 146 147 UnaryTransform(input, output, &indexVector[0], size, nullptr, 0, 148 Negate, 0, 0); 149 int expectedValues[3] = {-1, -1, -1}; 150 bool expectedNulls[3] = {true, true, true}; 151 int *outputValues = reinterpret_cast<int *>(outputBasePtr); 152 bool *outputNulls = reinterpret_cast<bool *>(outputBasePtr) + 16; 153 EXPECT_TRUE( 154 equal(outputValues, outputValues + size, 155 &expectedValues[0])); 156 157 EXPECT_TRUE( 158 equal(outputNulls, outputNulls + size, 159 &expectedNulls[0])); 160 161 release(outputBasePtr); 162 release(indexVector); 163 } 164 165 // cppcheck-suppress * 166 TEST(UnaryTransformTest, CheckMeasureOutputIteratorForAvg) { 167 const int size = 3; 168 uint32_t indexVectorH[size * 2] = {0, 1, 2}; 169 uint32_t baseCountsH[size + 1] = {0, 3, 9, 12}; 170 int inputValuesH[size] = {-1, 1, 0}; 171 // T T F 172 uint8_t inputNullsH[1 + ((size - 1) / 8)] = {0x03}; 173 174 int64_t outputValuesH[size] = {0, 0, 0}; 175 176 uint32_t *indexVector = allocate(&indexVectorH[0], size * 2); 177 uint32_t *baseCounts = allocate(&baseCountsH[0], size + 1); 178 uint8_t *basePtr = 179 allocate_column(nullptr, &inputNullsH[0], &inputValuesH[0], 0, 1, 12); 180 int64_t *outputValues = allocate(&outputValuesH[0], size); 181 182 DefaultValue defaultValue = {false, {.Int32Val = 0}}; 183 VectorPartySlice inputVP = {basePtr, 0, 8, 0, Int32, defaultValue}; 184 185 MeasureOutputVector outputMeasure = { 186 reinterpret_cast<uint32_t *>(outputValues), Int64, 187 AGGR_SUM_SIGNED}; 188 189 InputVector input = {{.VP = inputVP}, VectorPartyInput}; 190 OutputVector output = {{.Measure = outputMeasure}, MeasureOutput}; 191 192 UnaryTransform(input, output, indexVector, size, baseCounts, 0, 193 Negate, 0, 0); 194 int64_t expectedValues[3] = {3, -6, 0}; 195 EXPECT_TRUE(equal(outputValues, outputValues + size, 196 &expectedValues[0])); 197 198 // Test NOOP functor 199 UnaryTransform(input, output, indexVector, size, baseCounts, 0, 200 Noop, 0, 0); 201 int64_t expectedValues2[3] = {-3, 6, 0}; 202 EXPECT_TRUE(equal(outputValues, outputValues + size, 203 &expectedValues2[0])); 204 205 // Test avg aggregation. 206 MeasureOutputVector outputMeasure2 = { 207 reinterpret_cast<uint32_t *>(outputValues), Float64, 208 AGGR_AVG_FLOAT}; 209 210 OutputVector output2 = {{.Measure = outputMeasure2}, MeasureOutput}; 211 212 UnaryTransform(input, output2, indexVector, size, baseCounts, 0, 213 Noop, 0, 0); 214 float_t expectedValues3[6] = {-1.0, 0, 1.0, 0, 0, 0}; 215 *reinterpret_cast<uint32_t*>(&expectedValues3[1]) = 3; 216 *reinterpret_cast<uint32_t*>(&expectedValues3[3]) = 6; 217 EXPECT_TRUE(equal_print(outputValues, outputValues + size, 218 reinterpret_cast<int64_t*>(&expectedValues3[0]))); 219 220 release(basePtr); 221 release(outputValues); 222 release(indexVector); 223 release(baseCounts); 224 } 225 226 // cppcheck-suppress * 227 TEST(UnaryTransformTest, CheckDimensionOutputIterator) { 228 const int size = 3; 229 uint32_t indexVectorH[size * 2] = {0, 1, 2}; 230 int16_t inputValuesH[size] = {-1, 1, 0}; 231 // T T F 232 uint8_t inputNullsH[1 + ((size - 1) / 8)] = {0x03}; 233 234 uint8_t outputValuesH[3 * 3]; 235 thrust::fill(std::begin(outputValuesH), std::end(outputValuesH), 0); 236 237 uint8_t *basePtr = 238 allocate_column(nullptr, &inputNullsH[0], &inputValuesH[0], 0, 1, 6); 239 uint32_t *indexVector = allocate(&indexVectorH[0], size * 2); 240 uint8_t *outputValues = allocate(&outputValuesH[0], 9); 241 242 DefaultValue defaultValue = {false, {.Int32Val = 0}}; 243 VectorPartySlice inputVP = {basePtr, 0, 8, 0, Int16, defaultValue}; 244 245 DimensionOutputVector outputDimension = { 246 outputValues, outputValues + 6, Int16}; 247 248 InputVector input = {{.VP = inputVP}, VectorPartyInput}; 249 OutputVector output = 250 {{.Dimension = outputDimension}, DimensionOutput}; 251 252 UnaryTransform(input, output, indexVector, size, nullptr, 0, 253 Negate, 0, 0); 254 255 uint8_t expectedValues[9] = {1, 0, 0xFF, 0xFF, 0, 0, 1, 1, 0}; 256 EXPECT_TRUE(equal(outputValues, outputValues + 9, &expectedValues[0])); 257 258 // Test NOOP functor 259 UnaryTransform(input, output, indexVector, size, nullptr, 0, Noop, 0, 0); 260 261 uint8_t expectedValues2[9] = {0xFF, 0xFF, 1, 0, 0, 0, 1, 1, 0}; 262 EXPECT_TRUE(equal(outputValues, outputValues + 9, &expectedValues2[0])); 263 264 release(basePtr); 265 release(outputValues); 266 release(indexVector); 267 } 268 269 // cppcheck-suppress * 270 TEST(UnaryFilterTest, CheckFilter) { 271 const int size = 3; 272 uint32_t indexVectorH[size] = {0, 1, 2}; 273 RecordID recordIDVectorH[3]; 274 for (int i = 0; i < size; i++) { 275 RecordID recordID = {(int32_t) 0, (uint32_t) i}; 276 recordIDVectorH[i] = recordID; 277 } 278 uint8_t boolVectorH[size] = {0, 0, 0}; 279 280 int inputValuesH[size] = {1, 0, 1}; 281 uint8_t inputNullsH[size] = {1, 0, 1}; 282 283 uint8_t *basePtr = 284 allocate_column(nullptr, reinterpret_cast<uint8_t *>(&inputValuesH[0]), 285 &inputNullsH[0], 0, 12, 3); 286 287 uint32_t *indexVector = allocate(&indexVectorH[0], size); 288 uint8_t *boolVector = allocate(&boolVectorH[0], size); 289 RecordID *recordIDVector = allocate(&recordIDVectorH[0], size); 290 291 ScratchSpaceVector inputVP = {basePtr, 16, Int32}; 292 293 InputVector input = {{.ScratchSpace = inputVP}, ScratchSpaceInput}; 294 RecordID *recordIDVectors[1] = {recordIDVector}; 295 CGoCallResHandle resHandle = UnaryFilter(input, 296 indexVector, 297 boolVector, 298 size, 299 recordIDVectors, 300 1, 301 nullptr, 302 0, 303 IsNotNull, 304 0, 305 0); 306 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 2); 307 EXPECT_EQ(resHandle.pStrErr, nullptr); 308 309 int length = reinterpret_cast<int64_t>(resHandle.res); 310 311 uint32_t expectedValues[2] = {0, 2}; 312 RecordID recordID0 = {(int32_t) 0, (int32_t) 0}; 313 RecordID recordID1 = {(int32_t) 0, (int32_t) 2}; 314 RecordID expectedRecordIDs[2] = {recordID0, recordID1}; 315 EXPECT_TRUE(equal(indexVector, indexVector + length, &expectedValues[0])); 316 EXPECT_TRUE(equal( 317 reinterpret_cast<uint8_t *>(recordIDVector), 318 reinterpret_cast<uint8_t *>(recordIDVector) + sizeof(RecordID) * length, 319 reinterpret_cast<uint8_t *>(&expectedRecordIDs[0]))); 320 release(basePtr); 321 release(boolVector); 322 release(indexVector); 323 release(recordIDVector); 324 } 325 326 // cppcheck-suppress * 327 TEST(UnaryFilterTest, AllEmpty) { 328 const int size = 3; 329 uint32_t indexVectorH[size] = {0, 1, 2}; 330 uint8_t boolVectorH[size] = {0, 0, 0}; 331 332 int inputValuesH[size] = {0, 0, 0}; 333 uint8_t inputNullsH[size] = {1, 1, 1}; 334 335 uint8_t *basePtr = 336 allocate_column(nullptr, reinterpret_cast<uint8_t *>(&inputValuesH[0]), 337 &inputNullsH[0], 0, 12, 3); 338 339 uint32_t *indexVector = allocate(&indexVectorH[0], size); 340 uint8_t *boolVector = allocate(&boolVectorH[0], size); 341 342 ScratchSpaceVector inputVP = {basePtr, 16, Int32}; 343 344 InputVector input = {{.ScratchSpace = inputVP}, ScratchSpaceInput}; 345 CGoCallResHandle resHandle = UnaryFilter(input, indexVector, boolVector, size, 346 nullptr, 0, nullptr, 347 0, Negate, 0, 0); 348 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 0); 349 EXPECT_EQ(resHandle.pStrErr, nullptr); 350 release(basePtr); 351 release(indexVector); 352 } 353 354 // cppcheck-suppress * 355 TEST(BinaryTransformTest, CheckInt) { 356 const int size = 3; 357 uint32_t indexVectorH[size * 2] = {0, 1, 2}; 358 int lhsValuesH[size] = {-1, 1, 0}; 359 // T T F 360 uint8_t lhsNullsH[1 + ((size - 1) / 8)] = {0x03}; 361 362 uint8_t *lhsBasePtr = 363 allocate_column(nullptr, &lhsNullsH[0], &lhsValuesH[0], 0, 1, 12); 364 365 int rhsValuesH[size] = {0, 1, -1}; 366 // F T T 367 uint8_t rhsNullsH[1 + ((size - 1) / 8)] = {0x06}; 368 369 uint8_t *rhsBasePtr = 370 allocate_column(nullptr, &rhsNullsH[0], &rhsValuesH[0], 0, 1, 12); 371 372 int outputValuesH[size] = {0, 0, 0}; 373 bool outputNullsH[size] = {false, false, false}; 374 uint8_t *outputBasePtr = 375 allocate_column(nullptr, reinterpret_cast<uint8_t *>(&outputValuesH[0]), 376 &outputNullsH[0], 0, 12, 3); 377 378 uint32_t *indexVector = allocate(&indexVectorH[0], size * 2); 379 380 DefaultValue defaultValue = {false, {.Int32Val = 0}}; 381 VectorPartySlice 382 lhsColumn = {lhsBasePtr, 0, 8, 0, Int32, defaultValue}; 383 VectorPartySlice 384 rhsColumn = {rhsBasePtr, 0, 8, 0, Int32, defaultValue}; 385 386 ScratchSpaceVector outputScratchSpace = {outputBasePtr, 16, Int32}; 387 388 InputVector lhs = {{.VP = lhsColumn}, VectorPartyInput}; 389 InputVector rhs = {{.VP = rhsColumn}, VectorPartyInput}; 390 OutputVector output = {{.ScratchSpace = outputScratchSpace}, 391 ScratchSpaceOutput}; 392 393 BinaryTransform(lhs, rhs, output, indexVector, size, nullptr, 0, 394 Plus, 0, 0); 395 396 int expectedValues[3] = {0, 2, 0}; 397 bool expectedNulls[3] = {false, true, false}; 398 399 int *outputValues = reinterpret_cast<int *>(outputBasePtr); 400 bool *outputNulls = reinterpret_cast<bool *>(outputBasePtr) + 16; 401 402 EXPECT_TRUE( 403 equal(outputValues, outputValues + size, 404 &expectedValues[0])); 405 406 EXPECT_TRUE( 407 equal(outputNulls, outputNulls + size, 408 &expectedNulls[0])); 409 410 release(lhsBasePtr); 411 release(rhsBasePtr); 412 release(outputBasePtr); 413 release(indexVector); 414 } 415 416 // cppcheck-suppress * 417 TEST(BinaryTransformTest, CheckGeoPoint) { 418 const int size = 3; 419 uint32_t indexVectorH[size * 2] = {0, 1, 2}; 420 GeoPointT lhsValuesH[size] = {{1, 1}, {1, 0}, {0, 0}}; 421 // T T F 422 uint8_t lhsNullsH[1 + ((size - 1) / 8)] = {0x03}; 423 424 uint8_t *lhsBasePtr = 425 allocate_column(nullptr, &lhsNullsH[0], &lhsValuesH[0], 0, 1, 24); 426 427 ConstantVector rhsConstant = {{.GeoPointVal = {1, 1}}, true, ConstGeoPoint}; 428 429 uint32_t outputValuesH[size] = {false, false, false}; 430 bool outputNullsH[size] = {false, false, false}; 431 uint8_t *outputBasePtr = 432 allocate_column(nullptr, reinterpret_cast<uint8_t *>(&outputValuesH[0]), 433 &outputNullsH[0], 0, 12, 3); 434 435 uint32_t *indexVector = allocate(&indexVectorH[0], size * 2); 436 437 DefaultValue defaultValue = {false, {.Int32Val = 0}}; 438 VectorPartySlice 439 lhsColumn = {lhsBasePtr, 0, 8, 0, GeoPoint, defaultValue}; 440 ScratchSpaceVector outputScratchSpace = {outputBasePtr, 16, Uint32}; 441 442 InputVector lhs = {{.VP = lhsColumn}, VectorPartyInput}; 443 InputVector rhs = {{.Constant = rhsConstant}, ConstantInput}; 444 OutputVector output = {{.ScratchSpace = outputScratchSpace}, 445 ScratchSpaceOutput}; 446 BinaryTransform(lhs, rhs, output, indexVector, size, nullptr, 0, 447 Equal, 0, 0); 448 449 uint32_t expectedValues[3] = {true, false, false}; 450 bool expectedNulls[3] = {true, true, false}; 451 452 uint32_t *outputValues = reinterpret_cast<uint32_t *>(outputBasePtr); 453 bool *outputNulls = reinterpret_cast<bool *>(outputBasePtr) + 16; 454 455 EXPECT_TRUE( 456 equal(outputValues, outputValues + size, 457 &expectedValues[0])); 458 459 EXPECT_TRUE( 460 equal(outputNulls, outputNulls + size, 461 &expectedNulls[0])); 462 463 int rhsValuesH[size] = {0, 1, -1}; 464 // F T T 465 uint8_t rhsNullsH[1 + ((size - 1) / 8)] = {0x06}; 466 467 uint8_t *rhsBasePtr = 468 allocate_column(nullptr, &rhsNullsH[0], &rhsValuesH[0], 0, 1, 12); 469 470 VectorPartySlice 471 rhsColumn = {rhsBasePtr, 0, 8, 0, Int32, defaultValue}; 472 473 InputVector rhsVector = {{.VP = rhsColumn}, VectorPartyInput}; 474 475 CGoCallResHandle resHandle = {0, nullptr}; 476 resHandle = BinaryTransform(lhs, rhsVector, output, indexVector, size, 477 nullptr, 0, Equal, 0, 0); 478 EXPECT_TRUE(resHandle.pStrErr != nullptr); 479 free(const_cast<char *>(resHandle.pStrErr)); 480 release(lhsBasePtr); 481 release(rhsBasePtr); 482 release(outputBasePtr); 483 release(indexVector); 484 } 485 486 // cppcheck-suppress * 487 TEST(BinaryTransformTest, CheckFloatAndUnpackedBoolIter) { 488 const int size = 3; 489 uint32_t indexVectorH[size * 2] = {0, 1, 2}; 490 int lhsValuesH[size] = {-1, 1, 0}; 491 uint8_t lhsNullsH[size] = {1, 1, 1}; 492 493 uint8_t *lhsBasePtr = 494 allocate_column(nullptr, 495 reinterpret_cast<uint8_t *>(&lhsValuesH[0]), 496 &lhsNullsH[0], 0, 12, 3); 497 498 float rhsValuesH[size] = {1.1, -1.1, 0.1}; 499 uint8_t rhsNullsH[size] = {1, 1, 1}; 500 501 uint8_t *rhsBasePtr = 502 allocate_column(nullptr, 503 reinterpret_cast<uint8_t *>(&rhsValuesH[0]), 504 &rhsNullsH[0], 0, 12, 3); 505 506 float outputValuesH[size] = {200, 0, 0}; 507 bool outputNullsH[size] = {false, false, false}; 508 uint8_t *outputBasePtr = 509 allocate_column(nullptr, reinterpret_cast<uint8_t *>(&outputValuesH[0]), 510 &outputNullsH[0], 0, 12, 3); 511 512 uint32_t *indexVector = allocate(&indexVectorH[0], size * 2); 513 514 ScratchSpaceVector lhsColumn = {lhsBasePtr, 16, Int32}; 515 ScratchSpaceVector rhsColumn = {rhsBasePtr, 16, Float32}; 516 ScratchSpaceVector outputScratchSpace = { 517 outputBasePtr, 16, Float32}; 518 519 InputVector lhs = {{.ScratchSpace = lhsColumn}, ScratchSpaceInput}; 520 InputVector rhs = {{.ScratchSpace = rhsColumn}, ScratchSpaceInput}; 521 OutputVector output = {{.ScratchSpace = outputScratchSpace}, 522 ScratchSpaceOutput}; 523 524 BinaryTransform(lhs, rhs, output, indexVector, size, nullptr, 0, Minus, 0, 0); 525 526 float expectedValues[3] = {-2.1, 2.1, -0.1}; 527 bool expectedNulls[3] = {true, true, true}; 528 529 float_t *outputValues = reinterpret_cast<float_t *>(outputBasePtr); 530 bool *outputNulls = reinterpret_cast<bool *>(outputBasePtr) + 16; 531 532 EXPECT_TRUE( 533 equal(outputValues, outputValues + size, 534 &expectedValues[0])); 535 536 EXPECT_TRUE( 537 equal(outputNulls, outputNulls + size, 538 &expectedNulls[0])); 539 540 // transform using multiply functor. 541 BinaryTransform(lhs, rhs, output, indexVector, size, nullptr, 0, 542 Multiply, 0, 0); 543 float expectedValues2[3] = {-1.1, -1.1, -0}; 544 bool expectedNulls2[3] = {true, true, true}; 545 546 EXPECT_TRUE( 547 equal(outputValues, outputValues + size, 548 &expectedValues2[0])); 549 550 EXPECT_TRUE( 551 equal(outputNulls, outputNulls + size, 552 &expectedNulls2[0])); 553 554 release(lhsBasePtr); 555 release(rhsBasePtr); 556 release(outputBasePtr); 557 release(indexVector); 558 } 559 560 // cppcheck-suppress * 561 TEST(BinaryTransformTest, CheckConstantIterator) { 562 const int size = 3; 563 uint32_t indexVectorH[size * 2] = {0, 1, 2}; 564 int columnValuesH[size] = {-1, 1, 0}; 565 uint8_t columnNullsH[size] = {1, 1, 1}; 566 567 uint8_t *columnBasePtr = 568 allocate_column(nullptr, 569 reinterpret_cast<uint8_t *>(&columnValuesH[0]), 570 &columnNullsH[0], 0, 12, 3); 571 572 float outputValuesH[size] = {0, 0, 0}; 573 uint8_t outputNullsH[size] = {false, false, false}; 574 575 uint8_t *outputBasePtr = 576 allocate_column(nullptr, reinterpret_cast<uint8_t *>(&outputValuesH[0]), 577 &outputNullsH[0], 0, 12, 3); 578 579 uint32_t *indexVector = allocate(&indexVectorH[0], size * 2); 580 581 ScratchSpaceVector lhsColumn = {columnBasePtr, 16, Int32}; 582 ConstantVector rhsConstant = {{.FloatVal = 0.1}, true, ConstFloat}; 583 ScratchSpaceVector outputScratchSpace = {outputBasePtr, 16, Float32}; 584 585 InputVector lhs = {{.ScratchSpace = lhsColumn}, ScratchSpaceInput}; 586 InputVector rhs = {{.Constant = rhsConstant}, ConstantInput}; 587 OutputVector output = {{.ScratchSpace = outputScratchSpace}, 588 ScratchSpaceOutput}; 589 590 BinaryTransform(lhs, rhs, output, indexVector, size, nullptr, 0, 591 Plus, 0, 0); 592 593 float expectedValues[3] = {-0.9, 1.1, 0.1}; 594 bool expectedNulls[3] = {true, true, true}; 595 596 float_t *outputValues = reinterpret_cast<float_t *>(outputBasePtr); 597 bool *outputNulls = reinterpret_cast<bool *>(outputBasePtr) + 16; 598 599 EXPECT_TRUE( 600 equal(outputValues, outputValues + size, 601 &expectedValues[0])); 602 603 EXPECT_TRUE( 604 equal(outputNulls, outputNulls + size, 605 &expectedNulls[0])); 606 607 release(columnBasePtr); 608 release(outputBasePtr); 609 release(indexVector); 610 } 611 612 // cppcheck-suppress * 613 TEST(BinaryFilterTest, CheckFilter) { 614 const int size = 3; 615 int lhsValuesH[size] = {0, 1, 2}; 616 uint8_t lhsNullsH[size] = {1, 1, 1}; 617 618 uint8_t *lhsBasePtr = 619 allocate_column(nullptr, 620 reinterpret_cast<uint8_t *>(&lhsValuesH[0]), 621 &lhsNullsH[0], 0, 12, 3); 622 623 float rhsValuesH[size] = {0.1, 0.9, 1.9}; 624 uint8_t rhsNullsH[size] = {1, 1, 1}; 625 626 uint8_t *rhsBasePtr = 627 allocate_column(nullptr, 628 reinterpret_cast<uint8_t *>(&rhsValuesH[0]), 629 &rhsNullsH[0], 0, 12, 3); 630 631 uint32_t indexVectorH[size * 2] = {0, 1, 2}; 632 uint8_t boolVectorH[size] = {0, 0, 0}; 633 634 uint32_t *indexVector = allocate(&indexVectorH[0], size); 635 uint8_t *boolVector = allocate(&boolVectorH[0], size); 636 637 ScratchSpaceVector lhsColumn = {lhsBasePtr, 16, Int32}; 638 ScratchSpaceVector rhsColumn = {rhsBasePtr, 16, Float32}; 639 640 InputVector lhs = {{.ScratchSpace = lhsColumn}, ScratchSpaceInput}; 641 InputVector rhs = {{.ScratchSpace = rhsColumn}, ScratchSpaceInput}; 642 643 CGoCallResHandle resHandle = BinaryFilter(lhs, rhs, indexVector, boolVector, 644 size, nullptr, 0, nullptr, 0, 645 GreaterThan, 0, 0); 646 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 2); 647 EXPECT_EQ(resHandle.pStrErr, nullptr); 648 649 int length = reinterpret_cast<int64_t>(resHandle.res); 650 651 uint32_t expectedValues[2] = {1, 2}; 652 EXPECT_TRUE( 653 equal(indexVector, indexVector + length, 654 &expectedValues[0])); 655 656 release(lhsBasePtr); 657 release(rhsBasePtr); 658 release(indexVector); 659 release(boolVector); 660 } 661 662 // cppcheck-suppress * 663 TEST(BinaryTransformTest, CheckMeasureOutputIterator) { 664 const int size = 3; 665 uint32_t indexVectorH[size * 2] = {0, 1, 2}; 666 uint32_t baseCountsH[size + 1] = {0, 3, 9, 10}; 667 668 int lhsValuesH[size] = {-1, 1, 0}; 669 uint8_t lhsNullsH[size] = {1, 1, 0}; 670 671 uint8_t *lhsBasePtr = 672 allocate_column(nullptr, 673 reinterpret_cast<uint8_t *>(&lhsValuesH[0]), 674 &lhsNullsH[0], 0, 12, 3); 675 676 float rhsValuesH[size] = {1.1, -1.1, 0.1}; 677 uint8_t rhsNullsH[size] = {1, 1, 1}; 678 679 uint8_t *rhsBasePtr = 680 allocate_column(nullptr, 681 reinterpret_cast<uint8_t *>(&rhsValuesH[0]), 682 &rhsNullsH[0], 0, 12, 3); 683 684 float outputValuesH[size] = {0, 0, 0}; 685 686 float *outputValues = allocate(&outputValuesH[0], size); 687 uint32_t *indexVector = allocate(&indexVectorH[0], size); 688 uint32_t *baseCounts = allocate(&baseCountsH[0], size); 689 690 ScratchSpaceVector lhsColumn = {lhsBasePtr, 16, Int32}; 691 692 ScratchSpaceVector rhsColumn = {rhsBasePtr, 16, Float32}; 693 694 MeasureOutputVector outputMeasure = { 695 reinterpret_cast<uint32_t *>(outputValues), Float32, 696 AGGR_SUM_FLOAT}; 697 698 InputVector lhs = {{.ScratchSpace = lhsColumn}, ScratchSpaceInput}; 699 InputVector rhs = {{.ScratchSpace = rhsColumn}, ScratchSpaceInput}; 700 OutputVector output = {{.Measure = outputMeasure}, MeasureOutput}; 701 702 BinaryTransform(lhs, rhs, output, indexVector, size, baseCounts, 703 0, Minus, 0, 0); 704 float expectedValues[3] = {-6.3, 12.6, 0.0}; 705 706 EXPECT_TRUE( 707 equal(outputValues, outputValues + 3, 708 &expectedValues[0])); 709 710 release(lhsBasePtr); 711 release(rhsBasePtr); 712 release(outputValues); 713 release(indexVector); 714 release(baseCounts); 715 } 716 717 // cppcheck-suppress * 718 TEST(InitIndexVectorTest, InitIndexVector) { 719 const int size = 3; 720 uint32_t indexVectorH[size * 2] = {0, 0, 0}; 721 uint32_t *indexVector = allocate(&indexVectorH[0], 3); 722 InitIndexVector(indexVector, 0, 3, 0, 0); 723 uint32_t expectedValues[3] = {0, 1, 2}; 724 EXPECT_TRUE( 725 equal(indexVector, indexVector + size, &expectedValues[0])); 726 release(indexVector); 727 } 728 729 // cppcheck-suppress * 730 TEST(HashLookupTest, CheckLookup) { 731 // hash index created in golang cuckoo_hash_index 732 uint8_t bucketsH[312] = { 733 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 734 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 735 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 17, 736 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 737 12, 0, 0, 0, 140, 236, 116, 56, 157, 195, 184, 133, 16, 0, 0, 738 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0, 6, 0, 739 0, 0, 17, 0, 0, 0, 11, 0, 0, 0, 12, 0, 0, 0, 0, 740 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 741 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 742 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 10, 0, 743 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 2, 744 0, 0, 0, 121, 236, 209, 218, 160, 185, 109, 187, 0, 0, 0, 0, 745 8, 0, 0, 0, 15, 0, 0, 0, 9, 0, 0, 0, 1, 0, 0, 746 0, 10, 0, 0, 0, 14, 0, 0, 0, 2, 0, 0, 0, 0, 0, 747 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 748 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 749 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 750 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 751 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 7, 752 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 753 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 754 755 uint8_t *buckets = allocate(bucketsH, 312); 756 CuckooHashIndex hashIndex = { 757 buckets, 758 {(uint32_t) 2596996162, (uint32_t) 4039455774, (uint32_t) 2854263694, 759 (uint32_t) 1879968118}, 760 4, 761 4, 762 2}; 763 const int size = 18; 764 765 uint32_t indexVectorH[size] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 766 9, 10, 11, 12, 13, 14, 15, 16, 17}; 767 uint32_t inputValuesH[size] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 768 9, 10, 11, 12, 13, 14, 15, 16, 17}; 769 uint8_t inputNullsH[3] = {0xFF, 0xFF, 0xFF}; 770 771 uint8_t *basePtr = 772 allocate_column(nullptr, 773 &inputNullsH[0], &inputValuesH[0], 0, 3, size * 4); 774 775 RecordID outputValuesH[18]; 776 777 uint32_t *indexVector = allocate(&indexVectorH[0], size); 778 779 RecordID *outputValues = allocate(&outputValuesH[0], size); 780 781 DefaultValue defaultValue = {false, {.Int32Val = 0}}; 782 VectorPartySlice inputVP = {basePtr, 0, 8, 0, Int32, defaultValue}; 783 784 InputVector input = {{.VP = inputVP}, VectorPartyInput}; 785 HashLookup(input, outputValues, indexVector, 786 size, nullptr, 0, hashIndex, 0, 0); 787 788 RecordID expectedOutputValues[18]; 789 for (int i = 0; i < size; i++) { 790 RecordID recordID = {(int32_t) 0, (uint32_t) i}; 791 expectedOutputValues[i] = recordID; 792 } 793 794 EXPECT_TRUE( 795 equal(reinterpret_cast<uint8_t *>(outputValues), 796 reinterpret_cast<uint8_t *>(outputValues) + sizeof(RecordID) * size, 797 reinterpret_cast<uint8_t *>(&expectedOutputValues[0]))); 798 release(buckets); 799 release(indexVector); 800 release(basePtr); 801 release(outputValues); 802 } 803 804 // cppcheck-suppress * 805 TEST(HashLookupTest, CheckUUID) { 806 // hash index created in golang cuckoo_hash_index 807 uint8_t bucketsH[600] = { 808 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 809 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 810 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 2, 0, 811 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 812 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 813 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 814 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 815 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 816 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 817 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 818 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 22, 0, 0, 0, 0, 0, 0, 0, 819 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 820 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 821 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 822 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 823 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 824 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 825 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 826 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 827 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 828 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 829 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 830 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 831 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 832 0, 0}; 833 834 uint8_t *buckets = allocate(bucketsH, 600); 835 CuckooHashIndex hashIndex = { 836 buckets, 837 {(uint32_t) 1904795661, (uint32_t) 1908039658, (uint32_t) 3167437076, 838 (uint32_t) 4232957548}, 839 16, 840 4, 841 2}; 842 const int size = 3; 843 844 uint32_t indexVectorH[size] = {0, 1, 2}; 845 UUIDT inputValuesH[size] = {{0, 0}, {1, 0}, {2, 0}}; 846 uint8_t inputNullsH[1] = {0xFF}; 847 848 uint8_t *basePtr = 849 allocate_column(nullptr, 850 &inputNullsH[0], &inputValuesH[0], 0, 1, size * 16); 851 852 RecordID outputValuesH[3]; 853 854 uint32_t *indexVector = allocate(&indexVectorH[0], size); 855 856 RecordID *outputValues = allocate(&outputValuesH[0], size); 857 858 DefaultValue defaultValue = {false, {}}; 859 VectorPartySlice inputVP = {basePtr, 0, 8, 0, UUID, defaultValue}; 860 861 InputVector input = {{.VP = inputVP}, VectorPartyInput}; 862 HashLookup(input, outputValues, indexVector, 863 size, nullptr, 0, hashIndex, 0, 0); 864 865 RecordID expectedOutputValues[3]; 866 for (int i = 0; i < size; i++) { 867 RecordID recordID = {(int32_t) 0, (uint32_t) i}; 868 expectedOutputValues[i] = recordID; 869 } 870 871 EXPECT_TRUE( 872 equal(reinterpret_cast<uint8_t *>(outputValues), 873 reinterpret_cast<uint8_t *>(outputValues) + sizeof(RecordID) * size, 874 reinterpret_cast<uint8_t *>(&expectedOutputValues[0]))); 875 release(buckets); 876 release(indexVector); 877 release(basePtr); 878 release(outputValues); 879 } 880 881 // cppcheck-suppress * 882 TEST(ForeignTableColumnTransformTest, CheckTransform) { 883 const int numBatches = 5; 884 const int kNumRecords = 5; 885 const int numRecordsInLastBatch = 5; 886 int16_t* const timezoneLookup = nullptr; 887 int16_t timezoneLookupSize = 0; 888 int32_t baseBatchID = -2147483648; 889 RecordID recordIDsH[kNumRecords]; 890 VectorPartySlice batches[kNumRecords]; 891 for (int i = 0; i < kNumRecords; i++) { 892 RecordID recordID = {(int32_t) i + baseBatchID, (uint32_t) i}; 893 recordIDsH[i] = recordID; 894 } 895 RecordID *recordIDs = allocate(&recordIDsH[0], kNumRecords); 896 int valuesH[5][5] = {{1, 0, 0, 0, 0}, 897 {0, 2, 0, 0, 0}, 898 {0, 0, 3, 0, 0}, 899 {0, 0, 0, 4, 0}, 900 {0, 0, 0, 0, 5}}; 901 902 uint8_t nullsH[1] = {0xFF}; 903 904 uint8_t *basePtrs[5]; 905 for (int i = 0; i < numBatches; i++) { 906 uint8_t 907 *basePtr = allocate_column(nullptr, nullsH, &valuesH[i][0], 0, 1, 20); 908 VectorPartySlice foreignVP = {basePtr, 0, 8, 0, Int32}; 909 batches[i] = foreignVP; 910 basePtrs[i] = basePtr; 911 } 912 913 DefaultValue defaultValue = {false, {.Int32Val = 0}}; 914 ForeignColumnVector foreignColumnVP = {recordIDs, 915 batches, 916 baseBatchID, 917 (int32_t) numBatches, 918 (int32_t) numRecordsInLastBatch, 919 timezoneLookup, 920 timezoneLookupSize, 921 Int32, 922 defaultValue}; 923 InputVector input = {{.ForeignVP = foreignColumnVP}, 924 ForeignColumnInput}; 925 int outputValuesH[kNumRecords]; 926 bool outputNullsH[kNumRecords]; 927 928 uint8_t *outputBasePtr = 929 allocate_column(nullptr, reinterpret_cast<uint8_t *>(&outputValuesH[0]), 930 &outputNullsH[0], 0, 20, 5); 931 932 ScratchSpaceVector outputScratchSpace = {outputBasePtr, 24, Int32}; 933 OutputVector output = {{.ScratchSpace = outputScratchSpace}, 934 ScratchSpaceOutput}; 935 936 int expectedValues[kNumRecords] = {-1, -2, -3, -4, -5}; 937 bool expectedNulls[kNumRecords] = {true, true, true, true, true}; 938 939 int *outputValues = reinterpret_cast<int *>(outputBasePtr); 940 bool *outputNulls = reinterpret_cast<bool *>(outputBasePtr) + 24; 941 942 UnaryTransform(input, output, nullptr, kNumRecords, nullptr, 0, 943 Negate, 0, 0); 944 945 ForeignTableIterator<int> *vpIters = prepareForeignTableIterators( 946 numBatches, 947 batches, 948 4, 949 false, 950 0, 0); 951 RecordIDJoinIterator<int> inputIter( 952 recordIDs, 953 numBatches, 954 baseBatchID, 955 vpIters, 956 numRecordsInLastBatch, 957 timezoneLookup, 958 timezoneLookupSize); 959 960 outputValues = reinterpret_cast<int *>(outputBasePtr); 961 outputNulls = reinterpret_cast<bool *>(outputBasePtr) + 24; 962 963 EXPECT_TRUE( 964 equal(outputValues, outputValues + kNumRecords, &expectedValues[0])); 965 EXPECT_TRUE(equal(outputNulls, outputNulls + kNumRecords, &expectedNulls[0])); 966 967 release(recordIDs); 968 969 for (int i = 0; i < numBatches; i++) { 970 release(basePtrs[i]); 971 } 972 release(outputBasePtr); 973 } 974 975 // cppcheck-suppress * 976 TEST(SortDimColumnVectorTest, CheckSort) { 977 // test with 1 4-byte dim, 1 2-byte dim and 1 1-byte dim 978 // with length = 3 979 // numBytes=(4+2+1+3)*3=30 980 uint8_t keysH[30] = {0}; 981 reinterpret_cast<uint32_t *>(keysH)[0] = 1; 982 reinterpret_cast<uint32_t *>(keysH)[1] = 2; 983 reinterpret_cast<uint32_t *>(keysH)[2] = 1; 984 reinterpret_cast<uint16_t *>(keysH + 12)[0] = 1; 985 reinterpret_cast<uint16_t *>(keysH + 12)[1] = 2; 986 reinterpret_cast<uint16_t *>(keysH + 12)[2] = 1; 987 (keysH + 18)[0] = 1; 988 (keysH + 18)[1] = 2; 989 (keysH + 18)[2] = 1; 990 991 uint32_t indexH[3] = {0, 1, 2}; 992 uint64_t hashValuesH[3] = {0}; 993 994 uint8_t *keys = allocate(&keysH[0], 30); 995 uint32_t *index = allocate(&indexH[0], 3); 996 uint64_t *hashValues = allocate(&hashValuesH[0], 3); 997 998 const int vectorCapacity = 3; 999 const int length = 3; 1000 DimensionColumnVector keyColVector = { 1001 keys, 1002 hashValues, 1003 index, 1004 vectorCapacity, 1005 {(uint8_t)0, (uint8_t)0, (uint8_t)1, (uint8_t)1, (uint8_t)1}}; 1006 Sort(keyColVector, length, 0, 0); 1007 1008 uint32_t expectedIndex1[3] = {1, 0, 2}; 1009 uint32_t expectedIndex2[3] = {0, 2, 1}; 1010 EXPECT_TRUE(equal(index, index + 3, expectedIndex1) || 1011 equal(index, index + 3, expectedIndex2)); 1012 } 1013 1014 // cppcheck-suppress * 1015 TEST(ReduceDimColumnVectorTest, CheckReduce) { 1016 // test with 3 dimensions (4-byte, 2-byte, 1-byte) 1017 // each dimension vector has 6 elements with values assigned as [1,2,3,2,3,1] 1018 uint8_t inputDimValuesH[60] = {1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 1019 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0, 3, 0, 1020 2, 0, 3, 0, 1, 0, 1, 2, 3, 2, 3, 1, 1, 1, 1, 1021 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; 1022 uint64_t inputHashValuesH[6] = {1, 1, 2, 2, 3, 3}; 1023 uint32_t inputIndexVectorH[6] = {1, 3, 2, 4, 0, 5}; 1024 uint32_t inputValuesH[6] = {5, 1, 3, 2, 4, 6}; 1025 1026 uint8_t outputDimValuesH[60] = {0}; 1027 uint64_t outputHashValuesH[6] = {0}; 1028 uint32_t outputIndexVectorH[6] = {0}; 1029 uint32_t outputValuesH[6] = {0}; 1030 1031 uint8_t *inputDimValues = allocate(inputDimValuesH, 60); 1032 uint64_t *inputHashValues = allocate(inputHashValuesH, 6); 1033 uint32_t *inputIndexVector = allocate(inputIndexVectorH, 6); 1034 uint32_t *inputValues = allocate(inputValuesH, 6); 1035 1036 uint8_t *outputDimValues = allocate(outputDimValuesH, 60); 1037 uint64_t *outputHashValues = allocate(outputHashValuesH, 6); 1038 uint32_t *outputIndexVector = allocate(outputIndexVectorH, 6); 1039 uint32_t *outputValues = allocate(outputValuesH, 6); 1040 1041 uint32_t expectedValues[3] = {3, 7, 11}; 1042 uint32_t expectedIndex[3] = {1, 2, 0}; 1043 // output dimension values should be [2,3,1] for each dim vector 1044 uint8_t expectedDimValues[60] = { 1045 2, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1046 0, 0, 0, 0, 2, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 3, 1, 0, 1047 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1048 }; 1049 int length = 6; 1050 int vectorCapacity = 6; 1051 DimensionColumnVector inputKeys = { 1052 inputDimValues, 1053 inputHashValues, 1054 inputIndexVector, 1055 vectorCapacity, 1056 {(uint8_t)0, (uint8_t)0, (uint8_t)1, (uint8_t)1, (uint8_t)1}}; 1057 1058 DimensionColumnVector outputKeys = { 1059 outputDimValues, 1060 outputHashValues, 1061 outputIndexVector, 1062 vectorCapacity, 1063 {(uint8_t)0, (uint8_t)0, (uint8_t)1, (uint8_t)1, (uint8_t)1}}; 1064 CGoCallResHandle 1065 resHandle = Reduce(inputKeys, 1066 reinterpret_cast<uint8_t *>(inputValues), 1067 outputKeys, 1068 reinterpret_cast<uint8_t *>(outputValues), 1069 4, 1070 length, 1071 AGGR_SUM_UNSIGNED, 1072 0, 1073 0); 1074 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 3); 1075 EXPECT_EQ(resHandle.pStrErr, nullptr); 1076 1077 EXPECT_TRUE(equal(outputValues, outputValues + 3, expectedValues)); 1078 EXPECT_TRUE(equal(outputIndexVector, outputIndexVector + 3, expectedIndex)); 1079 EXPECT_TRUE(equal(outputDimValues, outputDimValues + 60, expectedDimValues)); 1080 } 1081 1082 TEST(SortAndReduceTest, CheckReduceByAvg) { 1083 // 6 elements 1 2 3 2 3 1 1084 uint8_t inputDimValuesH[30] = {1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 1085 0, 3, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1}; 1086 uint64_t inputHashValuesH[6] = {1, 1, 2, 2, 3, 3}; 1087 uint32_t inputIndexVectorH[6] = {1, 3, 2, 4, 0, 5}; 1088 float_t inputValuesH[12] = {5.0, 0, 1.0, 0, 3.0, 0, 2.0, 0, 4.0, 0, 6.0, 0}; 1089 // set count to be 1. 1090 for (int i = 0; i < 6; i++) { 1091 *reinterpret_cast<uint32_t*>(&inputValuesH[i*2+1]) = uint32_t(1); 1092 } 1093 1094 uint8_t outputDimValuesH[30] = {0}; 1095 uint64_t outputHashValuesH[6] = {0}; 1096 uint32_t outputIndexVectorH[6] = {0}; 1097 uint64_t outputValuesH[6] = {0}; 1098 1099 uint8_t *inputDimValues = allocate(inputDimValuesH, 30); 1100 uint64_t *inputHashValues = allocate(inputHashValuesH, 6); 1101 uint32_t *inputIndexVector = allocate(inputIndexVectorH, 6); 1102 uint32_t *inputValues = 1103 allocate(reinterpret_cast<uint32_t*>(&inputValuesH[0]), 12); 1104 1105 uint8_t *outputDimValues = allocate(outputDimValuesH, 30); 1106 uint64_t *outputHashValues = allocate(outputHashValuesH, 6); 1107 uint32_t *outputIndexVector = allocate(outputIndexVectorH, 6); 1108 uint64_t *outputValues = allocate(outputValuesH, 6); 1109 1110 float_t expectedValuesF[6] = {1.5, 0, 3.5, 0, 5.5, 0}; 1111 uint64_t* expectedValues = reinterpret_cast<uint64_t*>(&expectedValuesF[0]); 1112 for (int i = 0; i < 3; i++) { 1113 *(reinterpret_cast<uint32_t *>(&expectedValues[i]) + 1) = 2; 1114 } 1115 1116 uint32_t expectedIndex[3] = {1, 2, 0}; 1117 // output dimension values should be [2,3,1] for each dim vector 1118 uint8_t expectedDimValues[30] = { 1119 2, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1120 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1121 }; 1122 1123 int length = 6; 1124 int vectorCapacity = 6; 1125 DimensionColumnVector inputKeys = { 1126 inputDimValues, 1127 inputHashValues, 1128 inputIndexVector, 1129 vectorCapacity, 1130 {(uint8_t)0, (uint8_t)0, (uint8_t)1, (uint8_t)0, (uint8_t)0}}; 1131 1132 DimensionColumnVector outputKeys = { 1133 outputDimValues, 1134 outputHashValues, 1135 outputIndexVector, 1136 vectorCapacity, 1137 {(uint8_t)0, (uint8_t)0, (uint8_t)1, (uint8_t)0, (uint8_t)0}}; 1138 CGoCallResHandle 1139 resHandle = Reduce(inputKeys, 1140 reinterpret_cast<uint8_t *>(inputValues), 1141 outputKeys, 1142 reinterpret_cast<uint8_t *>(outputValues), 1143 8, 1144 length, 1145 AGGR_AVG_FLOAT, 0, 0); 1146 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 3); 1147 EXPECT_EQ(resHandle.pStrErr, nullptr); 1148 1149 EXPECT_TRUE(equal(outputValues, outputValues + 3, expectedValues)); 1150 EXPECT_TRUE(equal(outputIndexVector, outputIndexVector + 3, expectedIndex)); 1151 EXPECT_TRUE(equal(outputDimValues, outputDimValues + 30, expectedDimValues)); 1152 } 1153 1154 // cppcheck-suppress * 1155 TEST(SortAndReduceTest, CheckHash) { 1156 int size = 8; 1157 1158 uint8_t dimValuesH[16] = {2, 1, 0, 3, 0, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1}; 1159 uint32_t measureValuesH[8] = {1, 1, 1, 1, 1, 1, 1, 1}; 1160 uint64_t hashValuesH[8] = {0}; 1161 uint32_t indexValuesH[8] = {0}; 1162 1163 uint8_t dimValuesOutH[16] = {0}; 1164 uint32_t measureValuesOutH[8] = {0}; 1165 uint64_t hashValuesOutH[8] = {0}; 1166 uint32_t indexValuesOutH[8] = {0}; 1167 1168 uint8_t *dimValues = allocate(dimValuesH, 16); 1169 uint32_t *measureValues = allocate(measureValuesH, 8); 1170 uint64_t *hashValues = allocate(hashValuesH, 8); 1171 uint32_t *indexValues = allocate(indexValuesH, 8); 1172 1173 uint8_t *dimValuesOut = allocate(dimValuesOutH, 16); 1174 uint32_t *measureValuesOut = allocate(measureValuesOutH, 8); 1175 uint64_t *hashValuesOut = allocate(hashValuesOutH, 8); 1176 uint32_t *indexValuesOut = allocate(indexValuesOutH, 8); 1177 1178 InitIndexVector(indexValues, 0, size, 0, 0); 1179 1180 const int length = 8; 1181 const int vectorCapacity = 8; 1182 DimensionColumnVector inputKeyColVector = { 1183 dimValues, 1184 hashValues, 1185 indexValues, 1186 vectorCapacity, 1187 {(uint8_t)0, (uint8_t)0, (uint8_t)0, (uint8_t)0, (uint8_t)1}}; 1188 1189 DimensionColumnVector outputKeyColVector = { 1190 dimValuesOut, 1191 hashValuesOut, 1192 indexValuesOut, 1193 vectorCapacity, 1194 {(uint8_t)0, (uint8_t)0, (uint8_t)0, (uint8_t)0, (uint8_t)1}}; 1195 1196 Sort(inputKeyColVector, length, 0, 0); 1197 CGoCallResHandle resHandle = 1198 Reduce(inputKeyColVector, reinterpret_cast<uint8_t *>(measureValues), 1199 outputKeyColVector, reinterpret_cast<uint8_t *>(measureValuesOut), 1200 4, length, AGGR_SUM_UNSIGNED, nullptr, 0); 1201 1202 uint8_t expectedDims[16] = {2, 0, 3, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0}; 1203 uint32_t expectedMeasures[8] = {2, 2, 2, 2, 0, 0, 0, 0}; 1204 uint32_t expectedIndexes[8] = {0, 2, 3, 1, 0, 0, 0, 0}; 1205 1206 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 4); 1207 EXPECT_EQ(resHandle.pStrErr, nullptr); 1208 1209 EXPECT_TRUE(equal(dimValuesOut, dimValuesOut + 16, &expectedDims[0])); 1210 EXPECT_TRUE( 1211 equal(measureValuesOut, measureValuesOut + 8, &expectedMeasures[0])); 1212 EXPECT_TRUE(equal(indexValuesOut, indexValuesOut + 8, &expectedIndexes[0])); 1213 release(dimValues); 1214 release(measureValues); 1215 release(hashValues); 1216 release(indexValues); 1217 release(dimValuesOut); 1218 release(measureValuesOut); 1219 release(hashValuesOut); 1220 release(indexValuesOut); 1221 } 1222 1223 // cppcheck-suppress * 1224 TEST(HyperLogLogTest, CheckSparseMode) { 1225 int prevResultSize = 0; 1226 int curBatchSize = 8; 1227 const int vectorCapacity = 8; 1228 1229 uint8_t prevDimH[16] = {1, 1, 2, 2, 3, 3, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1}; 1230 uint32_t prevValuesH[8] = {0}; 1231 uint64_t prevHashH[8] = {0}; 1232 uint32_t prevIndexH[8] = {0}; 1233 1234 uint8_t curDimH[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 1235 uint32_t curValuesH[8] = {0x010001, 0x020002, 0x010002, 0x020002, 1236 0x010003, 0x020003, 0x010004, 0x020004}; 1237 uint32_t curIndexH[8] = {0, 1, 2, 3, 4, 5, 6, 7}; 1238 uint64_t curHashH[8] = {0}; 1239 1240 uint8_t *prevDim = allocate(prevDimH, 16); 1241 uint32_t *prevValues = allocate(prevValuesH, 8); 1242 uint64_t *prevHash = allocate(prevHashH, 8); 1243 uint32_t *prevIndex = allocate(prevIndexH, 8); 1244 1245 uint8_t *curDim = allocate(curDimH, 16); 1246 uint32_t *curValues = allocate(curValuesH, 8); 1247 uint64_t *curHash = allocate(curHashH, 8); 1248 uint32_t *curIndex = allocate(curIndexH, 8); 1249 1250 DimensionColumnVector prevDimOut = { 1251 prevDim, 1252 prevHash, 1253 prevIndex, 1254 vectorCapacity, 1255 {(uint8_t)0, (uint8_t)0, (uint8_t)0, (uint8_t)0, (uint8_t)1}}; 1256 1257 DimensionColumnVector curDimOut = { 1258 curDim, 1259 curHash, 1260 curIndex, 1261 vectorCapacity, 1262 {(uint8_t)0, (uint8_t)0, (uint8_t)0, (uint8_t)0, (uint8_t)1}}; 1263 1264 uint8_t *hllVector; 1265 size_t hllVectorSize; 1266 uint16_t *hllDimRegIDCount; 1267 CGoCallResHandle 1268 resHandle = HyperLogLog(prevDimOut, curDimOut, prevValues, curValues, 1269 prevResultSize, curBatchSize, true, &hllVector, 1270 &hllVectorSize, &hllDimRegIDCount, 0, 0); 1271 1272 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 4); 1273 EXPECT_EQ(resHandle.pStrErr, nullptr); 1274 1275 int resSize = reinterpret_cast<int64_t>(resHandle.res); 1276 1277 EXPECT_EQ(resSize, 4); 1278 EXPECT_EQ(hllVectorSize, 20); 1279 uint8_t expectedDims[16] = {2, 4, 3, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0}; 1280 uint8_t expectedHLL[20] = {2, 0, 3, 0, 4, 0, 3, 0, 3, 0, 1281 3, 0, 1, 0, 2, 0, 2, 0, 3, 0}; 1282 uint16_t expectedDimRegIDCount[4] = {1, 1, 1, 2}; 1283 EXPECT_TRUE(equal(curDim, curDim + 16, &expectedDims[0])); 1284 EXPECT_TRUE(equal(hllVector, hllVector + hllVectorSize, &expectedHLL[0])); 1285 EXPECT_TRUE(equal(hllDimRegIDCount, hllDimRegIDCount + resSize, 1286 &expectedDimRegIDCount[0])); 1287 release(prevDim); 1288 release(curDim); 1289 release(prevValues); 1290 release(prevHash); 1291 release(prevIndex); 1292 release(curValues); 1293 release(curHash); 1294 release(curIndex); 1295 release(hllVector); 1296 release(hllDimRegIDCount); 1297 } 1298 1299 // cppcheck-suppress * 1300 TEST(HyperLogLogTest, CheckDenseMode) { 1301 int prevResultSize = 0; 1302 int curBatchSize = 5000; 1303 const int vectorCapacity = 5000; 1304 1305 uint8_t prevDimH[10000] = {0}; 1306 // {1,1,2,2,0,0, ... } 1307 prevDimH[0] = 1; 1308 prevDimH[1] = 1; 1309 prevDimH[2] = 2; 1310 prevDimH[3] = 2; 1311 for (int i = 5000; i < 10000; i++) { 1312 prevDimH[i] = 1; 1313 } 1314 uint32_t prevValuesH[5000] = {0}; 1315 uint64_t prevHashH[5000] = {0}; 1316 uint32_t prevIndexH[5000] = {0}; 1317 1318 uint8_t curDimH[10000] = {0}; 1319 uint32_t curValuesH[5000] = {0}; 1320 curValuesH[0] = 0x010001; 1321 curValuesH[1] = 0x020002; 1322 curValuesH[2] = 0x010002; 1323 curValuesH[3] = 0x020002; 1324 for (int i = 4; i < 5000; i++) { 1325 // 4996 registers 1326 curValuesH[i] = (0x010000 | (i - 4)); 1327 } 1328 uint32_t curIndexH[5000] = {0}; 1329 for (int i = 0; i < 5000; i++) { 1330 curIndexH[i] = i; 1331 } 1332 uint64_t curHashH[5000] = {0}; 1333 1334 uint8_t *prevDim = allocate(prevDimH, 10000); 1335 uint32_t *prevValues = allocate(prevValuesH, 5000); 1336 uint64_t *prevHash = allocate(prevHashH, 5000); 1337 uint32_t *prevIndex = allocate(prevIndexH, 5000); 1338 1339 uint8_t *curDim = allocate(curDimH, 10000); 1340 uint32_t *curValues = allocate(curValuesH, 5000); 1341 uint64_t *curHash = allocate(curHashH, 5000); 1342 uint32_t *curIndex = allocate(curIndexH, 5000); 1343 1344 DimensionColumnVector prevDimOut = { 1345 prevDim, 1346 prevHash, 1347 prevIndex, 1348 vectorCapacity, 1349 {(uint8_t)0, (uint8_t)0, (uint8_t)0, (uint8_t)0, (uint8_t)1}}; 1350 1351 DimensionColumnVector curDimOut = { 1352 curDim, 1353 curHash, 1354 curIndex, 1355 vectorCapacity, 1356 {(uint8_t)0, (uint8_t)0, (uint8_t)0, (uint8_t)0, (uint8_t)1}}; 1357 1358 uint8_t *hllVector; 1359 size_t hllVectorSize; 1360 uint16_t *hllDimRegIDCount; 1361 CGoCallResHandle 1362 resHandle = HyperLogLog(prevDimOut, curDimOut, prevValues, curValues, 1363 prevResultSize, curBatchSize, true, &hllVector, 1364 &hllVectorSize, &hllDimRegIDCount, 0, 0); 1365 1366 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 3); 1367 EXPECT_EQ(resHandle.pStrErr, nullptr); 1368 1369 int resSize = reinterpret_cast<int64_t>(resHandle.res); 1370 1371 EXPECT_EQ(resSize, 3); 1372 EXPECT_EQ(hllVectorSize, 16396); 1373 uint8_t expectedDims[10000] = {0}; 1374 expectedDims[0] = 2; 1375 expectedDims[1] = 0; 1376 expectedDims[2] = 1; 1377 expectedDims[5000] = 1; 1378 expectedDims[5001] = 1; 1379 expectedDims[5002] = 1; 1380 uint8_t expectedHLL[16396] = {0}; 1381 expectedHLL[0] = 2; 1382 expectedHLL[1] = 0; 1383 expectedHLL[2] = 3; 1384 expectedHLL[3] = 0; 1385 for (int i = 4; i < 5000; i++) { 1386 expectedHLL[i] = 2; 1387 } 1388 expectedHLL[16388] = 1; 1389 expectedHLL[16389] = 0; 1390 expectedHLL[16390] = 2; 1391 expectedHLL[16391] = 0; 1392 expectedHLL[16392] = 2; 1393 expectedHLL[16393] = 0; 1394 expectedHLL[16394] = 3; 1395 expectedHLL[16395] = 0; 1396 1397 uint16_t expectedDimRegIDCount[3] = {1, 4996, 2}; 1398 EXPECT_TRUE(equal(curDim, curDim + 10000, &expectedDims[0])); 1399 EXPECT_TRUE(equal(hllVector, hllVector + hllVectorSize, &expectedHLL[0])); 1400 EXPECT_TRUE(equal(hllDimRegIDCount, hllDimRegIDCount + resSize, 1401 &expectedDimRegIDCount[0])); 1402 release(prevDim); 1403 release(curDim); 1404 release(prevValues); 1405 release(prevHash); 1406 release(prevIndex); 1407 release(curValues); 1408 release(curHash); 1409 release(curIndex); 1410 release(hllVector); 1411 release(hllDimRegIDCount); 1412 } 1413 1414 // cppcheck-suppress * 1415 TEST(DateFunctorsTest, CheckGetStarts) { 1416 // First ensure the constant memory is properly initialized. 1417 BootstrapDevice(); 1418 1419 const int size = 3; 1420 uint32_t indexVectorH[size * 2] = {0, 1, 2}; 1421 uint32_t *indexVector = allocate(&indexVectorH[0], size * 2); 1422 1423 uint32_t inputValuesH[size] = {0, get_ts(2018, 6, 11), get_ts(1970, 1, 1)}; 1424 bool inputNullsH[size] = {false, true, true}; 1425 uint8_t *basePtr = 1426 allocate_column(nullptr, 1427 reinterpret_cast<uint8_t *>(&inputValuesH[0]), 1428 &inputNullsH[0], 0, 12, 3); 1429 1430 uint32_t outputValuesH[size] = {0, 0, 0}; 1431 bool outputNullsH[size] = {false, false, false}; 1432 uint8_t *outputBasePtr = 1433 allocate_column(nullptr, reinterpret_cast<uint8_t *>(&outputValuesH[0]), 1434 &outputNullsH[0], 0, 12, 3); 1435 1436 ScratchSpaceVector inputScratchSpace = {basePtr, 16, Int32}; 1437 ScratchSpaceVector outputScratchSpace = {outputBasePtr, 16, Int32}; 1438 1439 InputVector 1440 input = {{.ScratchSpace = inputScratchSpace}, ScratchSpaceInput}; 1441 OutputVector output = {{.ScratchSpace = outputScratchSpace}, 1442 ScratchSpaceOutput}; 1443 1444 UnaryTransform(input, output, indexVector, size, nullptr, 0, 1445 GetMonthStart, 0, 0); 1446 1447 uint32_t *outputValues = reinterpret_cast<uint32_t *>(outputBasePtr); 1448 bool *outputNulls = reinterpret_cast<bool *>(outputBasePtr) + 16; 1449 1450 uint32_t expectedValues[3] = {0, get_ts(2018, 6, 1), get_ts(1970, 1, 1)}; 1451 bool expectedNulls[3] = {false, true, true}; 1452 1453 EXPECT_TRUE( 1454 equal(outputValues, outputValues + size, 1455 &expectedValues[0])); 1456 1457 EXPECT_TRUE( 1458 equal(outputNulls, outputNulls + size, 1459 &expectedNulls[0])); 1460 1461 // Check get quarter start. 1462 UnaryTransform(input, output, indexVector, size, nullptr, 0, 1463 GetQuarterStart, 0, 0); 1464 1465 uint32_t expectedValues2[3] = {0, get_ts(2018, 4, 1), get_ts(1970, 1, 1)}; 1466 bool expectedNulls2[3] = {false, true, true}; 1467 1468 EXPECT_TRUE( 1469 equal(outputValues, outputValues + size, 1470 &expectedValues2[0])); 1471 1472 EXPECT_TRUE( 1473 equal(outputNulls, outputNulls + size, 1474 &expectedNulls2[0])); 1475 1476 // Check get year start. 1477 UnaryTransform(input, output, indexVector, size, nullptr, 0, 1478 GetYearStart, 0, 0); 1479 1480 uint32_t expectedValues3[3] = {0, get_ts(2018, 1, 1), get_ts(1970, 1, 1)}; 1481 bool expectedNulls3[3] = {false, true, true}; 1482 1483 EXPECT_TRUE( 1484 equal(outputValues, outputValues + size, 1485 &expectedValues3[0])); 1486 1487 EXPECT_TRUE( 1488 equal(outputNulls, outputNulls + size, 1489 &expectedNulls3[0])); 1490 1491 release(basePtr); 1492 release(outputBasePtr); 1493 release(indexVector); 1494 } 1495 1496 // cppcheck-suppress * 1497 TEST(GeoBatchIntersectTest, CheckInShape) { 1498 // 3 shapes 1499 // 1. Square with (1,1), (1,-1), (-1,-1), (-1, 1) 1500 // 2. Triangle with (3,3),(2,2),(4,2) 1501 // 3. Square with a hole (0,6),(3,6),(3,3),(0,3), hole (1,5),(2,5),(2,4),(1,4) 1502 float shapeLatsH[20] = {1, 1, -1, -1, 1, 3, 2, 4, 3, 0, 1503 3, 3, 0, 0, FLT_MAX, 1, 2, 2, 1, 1}; 1504 float shapeLongsH[20] = {1, -1, -1, 1, 1, 3, 2, 2, 3, 6, 1505 6, 3, 3, 6, FLT_MAX, 5, 5, 4, 4, 5}; 1506 uint8_t shapeIndexsH[20] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 1507 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; 1508 GeoShapeBatch geoShapes = 1509 get_geo_shape_batch(shapeLatsH, shapeLongsH, shapeIndexsH, 3, 20); 1510 1511 uint32_t indexVectorH[5] = {0, 1, 2, 3, 4}; 1512 uint32_t *indexVector = allocate(indexVectorH, 5); 1513 1514 // 5 points (0,0),(3,2.5),(1.5, 3.5),(1.5,4.5),null 1515 // in 1 in 2 in 3 out out 1516 GeoPointT pointsH[5] = {{0, 0}, {3, 2.5}, {1.5, 3.5}, {1.5, 4.5}, {0, 0}}; 1517 uint8_t nullsH[1] = {0x0F}; 1518 1519 uint32_t outputPredicateH[5] = {0}; 1520 uint32_t *outputPredicate = allocate(outputPredicateH, 5); 1521 1522 // in. 1523 bool inOrOut = true; 1524 1525 uint8_t *basePtr = 1526 allocate_column(nullptr, &nullsH[0], &pointsH[0], 0, 1, 40); 1527 1528 DefaultValue defaultValue = {false}; 1529 VectorPartySlice inputVP = {basePtr, 0, 8, 0, GeoPoint, defaultValue, 5}; 1530 InputVector points = {{.VP = inputVP}, VectorPartyInput}; 1531 1532 CGoCallResHandle resHandle = 1533 GeoBatchIntersects(geoShapes, points, indexVector, 5, 0, nullptr, 0, 1534 outputPredicate, inOrOut, 0, 0); 1535 1536 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 3); 1537 EXPECT_EQ(resHandle.pStrErr, nullptr); 1538 uint32_t expectedOutputPredicate[5] = {1, 2, 4, 0, 0}; 1539 EXPECT_TRUE( 1540 equal(outputPredicate, outputPredicate + 5, expectedOutputPredicate)); 1541 1542 release(outputPredicate); 1543 release(indexVector); 1544 release(basePtr); 1545 release(geoShapes); 1546 } 1547 1548 // cppcheck-suppress * 1549 TEST(GeoBatchIntersectTest, CheckRecordIDJoinIterator) { 1550 // 3 shapes 1551 // 1. Square with (1,1), (1,-1), (-1,-1), (-1, 1) 1552 // 2. Triangle with (3,3),(2,2),(4,2) 1553 // 3. Square with a hole (0,6),(3,6),(3,3),(0,3), hole (1,5),(2,5),(2,4),(1,4) 1554 float shapeLatsH[20] = {1, 1, -1, -1, 1, 3, 2, 4, 3, 0, 1555 3, 3, 0, 0, FLT_MAX, 1, 2, 2, 1, 1}; 1556 float shapeLongsH[20] = {1, -1, -1, 1, 1, 3, 2, 2, 3, 6, 1557 6, 3, 3, 6, FLT_MAX, 5, 5, 4, 4, 5}; 1558 uint8_t shapeIndexsH[20] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 1559 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; 1560 GeoShapeBatch geoShapes = 1561 get_geo_shape_batch(shapeLatsH, shapeLongsH, shapeIndexsH, 3, 20); 1562 1563 uint32_t indexVectorH[5] = {0, 1, 2, 3, 4}; 1564 uint32_t *indexVector = allocate(indexVectorH, 5); 1565 1566 // 5 points (0,0),(3,2.5),(1.5, 3.5),(1.5,4.5),null 1567 // in 1 in 2 in 3 out out 1568 const int numBatches = 5; 1569 const int kNumRecords = 5; 1570 const int numRecordsInLastBatch = 5; 1571 int32_t baseBatchID = -2147483648; 1572 RecordID recordIDsH[kNumRecords]; 1573 VectorPartySlice batches[kNumRecords]; 1574 for (int i = 0; i < kNumRecords; i++) { 1575 RecordID recordID = {(int32_t) i + baseBatchID, (uint32_t) i}; 1576 recordIDsH[i] = recordID; 1577 } 1578 RecordID *recordIDs = allocate(&recordIDsH[0], kNumRecords); 1579 GeoPointT valuesH[5][5]; 1580 GeoPointT pointsH[5] = {{0, 0}, {3, 2.5}, {1.5, 3.5}, {1.5, 4.5}, {0, 0}}; 1581 for (int i = 0; i < kNumRecords; i++) { 1582 valuesH[i][i] = pointsH[i]; 1583 } 1584 uint8_t nullsH[1] = {0x0F}; 1585 1586 uint8_t *basePtrs[5]; 1587 for (int i = 0; i < numBatches; i++) { 1588 uint8_t *basePtr = 1589 allocate_column(nullptr, nullsH, &valuesH[i][0], 0, 1, 40); 1590 VectorPartySlice foreignVP = {basePtr, 0, 8, 0, GeoPoint}; 1591 batches[i] = foreignVP; 1592 basePtrs[i] = basePtr; 1593 } 1594 1595 DefaultValue defaultValue = {false, {}}; 1596 ForeignColumnVector foreignColumnVP = {recordIDs, 1597 batches, 1598 baseBatchID, 1599 (int32_t) numBatches, 1600 (int32_t) numRecordsInLastBatch, 1601 nullptr, 1602 0, 1603 GeoPoint, 1604 defaultValue}; 1605 InputVector points = {{.ForeignVP = foreignColumnVP}, 1606 ForeignColumnInput}; 1607 1608 uint32_t outputPredicateH[5] = {0}; 1609 uint32_t *outputPredicate = allocate(outputPredicateH, 5); 1610 1611 CGoCallResHandle resHandle = 1612 GeoBatchIntersects(geoShapes, points, indexVector, 5, 0, nullptr, 0, 1613 outputPredicate, true, 0, 0); 1614 1615 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 3); 1616 EXPECT_EQ(resHandle.pStrErr, nullptr); 1617 uint32_t expectedOutputPredicate[5] = {1, 2, 4, 0, 0}; 1618 EXPECT_TRUE( 1619 equal(outputPredicate, outputPredicate + 5, expectedOutputPredicate)); 1620 1621 release(outputPredicate); 1622 release(indexVector); 1623 release(recordIDs); 1624 release(geoShapes); 1625 for (int i = 0; i < numBatches; i++) { 1626 release(basePtrs[i]); 1627 } 1628 } 1629 1630 // cppcheck-suppress * 1631 TEST(GeoBatchIntersectTest, CheckNotInShape) { 1632 // 3 shapes 1633 // 1. Square with (1,1), (1,-1), (-1,-1), (-1, 1) 1634 // 2. Triangle with (3,3),(2,2),(4,2) 1635 // 3. Square with a hole (0,6),(3,6),(3,3),(0,3), hole (1,5),(2,5),(2,4),(1,4) 1636 float shapeLatsH[20] = {1, 1, -1, -1, 1, 3, 2, 4, 3, 0, 1637 3, 3, 0, 0, FLT_MAX, 1, 2, 2, 1, 1}; 1638 float shapeLongsH[20] = {1, -1, -1, 1, 1, 3, 2, 2, 3, 6, 1639 6, 3, 3, 6, FLT_MAX, 5, 5, 4, 4, 5}; 1640 uint8_t shapeIndexsH[20] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 1641 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; 1642 GeoShapeBatch geoShapes = 1643 get_geo_shape_batch(shapeLatsH, shapeLongsH, shapeIndexsH, 3, 20); 1644 1645 uint32_t indexVectorH[5] = {0, 1, 2, 3, 4}; 1646 uint32_t *indexVector = allocate(indexVectorH, 5); 1647 1648 // 5 points (0,0),(3,2.5),(1.5, 3.5),(1.5,4.5),null 1649 // in 1 in 2 in 3 out out 1650 GeoPointT pointsH[5] = {{0, 0}, {3, 2.5}, {1.5, 3.5}, {1.5, 4.5}, {0, 0}}; 1651 uint8_t nullsH[1] = {0x0F}; 1652 1653 uint32_t outputPredicateH[5] = {0}; 1654 uint32_t *outputPredicate = allocate(outputPredicateH, 5); 1655 1656 // in. 1657 bool inOrOut = false; 1658 1659 uint8_t *basePtr = 1660 allocate_column(nullptr, &nullsH[0], &pointsH[0], 0, 1, 40); 1661 1662 DefaultValue defaultValue = {false}; 1663 VectorPartySlice inputVP = {basePtr, 0, 8, 0, GeoPoint, defaultValue, 5}; 1664 InputVector points = {{.VP = inputVP}, VectorPartyInput}; 1665 CGoCallResHandle resHandle = 1666 GeoBatchIntersects(geoShapes, points, indexVector, 5, 0, nullptr, 0, 1667 outputPredicate, inOrOut, 0, 0); 1668 1669 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 1); 1670 EXPECT_EQ(resHandle.pStrErr, nullptr); 1671 uint32_t expectedOutputPredicate[5] = {1, 2, 4, 0, 1}; 1672 EXPECT_TRUE( 1673 equal(outputPredicate, outputPredicate + 5, expectedOutputPredicate)); 1674 1675 release(outputPredicate); 1676 release(indexVector); 1677 release(basePtr); 1678 release(geoShapes); 1679 } 1680 1681 // cppcheck-suppress * 1682 TEST(GeoBatchIntersectionJoinTest, DimensionWriting) { 1683 float shapeLatsH[15] = { 1684 1, 1, -1, -1, 1, 2, 2, -2, 1685 -2, 2, 1.5 + 0.1, 1.5 + 0.1, 1.5 - 0.1, 1.5 - 0.1, 1.5 + 0.1}; 1686 float shapeLongsH[15] = { 1687 1, -1, -1, 1, 1, 2, -2, -2, 1688 2, 2, 3.5 + 0.1, 3.5 - 0.1, 3.5 + 0.1, 3.5 - 0.1, 3.5 + 0.1}; 1689 uint8_t shapeIndexsH[15] = {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2}; 1690 GeoShapeBatch geoShapes = 1691 get_geo_shape_batch(shapeLatsH, shapeLongsH, shapeIndexsH, 3, 15); 1692 uint32_t indexVectorH[5] = {0, 1, 2, 3, 4}; 1693 uint32_t *indexVector = allocate(indexVectorH, 5); 1694 1695 // 5 points (1.5,1.5) (0,0) (1.5,4.5) (1.5, 3.5) null 1696 // in2 in1,2 out in3 out 1697 GeoPointT pointsH[5] = {{1.5, 1.5}, {0, 0}, {1.5, 4.5}, {1.5, 3.5}, {0, 0}}; 1698 uint8_t nullsH[1] = {0x0F}; 1699 1700 uint32_t outputPredicateH[5] = {0}; 1701 uint32_t *outputPredicate = allocate(outputPredicateH, 5); 1702 1703 uint8_t *basePtr = 1704 allocate_column(nullptr, &nullsH[0], &pointsH[0], 0, 1, 40); 1705 1706 DefaultValue defaultValue = {false}; 1707 VectorPartySlice inputVP = {basePtr, 0, 8, 0, GeoPoint, defaultValue, 5}; 1708 1709 uint8_t outputValuesH[10]; 1710 thrust::fill(std::begin(outputValuesH), std::end(outputValuesH), 0); 1711 uint8_t *outputValues = allocate(&outputValuesH[0], 10); 1712 DimensionOutputVector outputDimension = {outputValues, outputValues + 5, 1713 Uint8}; 1714 1715 InputVector points = {{.VP = inputVP}, VectorPartyInput}; 1716 CGoCallResHandle resHandle = 1717 GeoBatchIntersects(geoShapes, points, indexVector, 5, 1718 0, nullptr, 0, outputPredicate, true, 0, 0); 1719 1720 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 3); 1721 EXPECT_EQ(resHandle.pStrErr, nullptr); 1722 1723 resHandle = WriteGeoShapeDim(1, outputDimension, 5, outputPredicate, 0, 0); 1724 1725 uint32_t expectedOutputPredicate[5] = {2, 3, 0, 4, 0}; 1726 GeoPredicateIterator geoIter(expectedOutputPredicate, 1); 1727 EXPECT_TRUE( 1728 equal(outputPredicate, outputPredicate + 5, expectedOutputPredicate)); 1729 uint8_t expectedDimValues[5] = {1, 0, 2, 0, 0}; 1730 uint8_t expectedDimNulls[5] = {1, 1, 1, 0, 0}; 1731 EXPECT_TRUE(equal(outputDimension.DimValues, 1732 outputDimension.DimValues + 5, expectedDimValues)); 1733 EXPECT_TRUE(equal(outputDimension.DimNulls, 1734 outputDimension.DimNulls + 5, expectedDimNulls)); 1735 1736 release(outputPredicate); 1737 release(indexVector); 1738 release(basePtr); 1739 release(geoShapes); 1740 } 1741 1742 TEST(ExpandTest, testOverFill) { 1743 // test with 3 dimensions (4-byte, 2-byte, 1-byte) 1744 // each dimension vector has 6 elements with values assigned as 1745 // [1,2,3,2,3,1] 1746 uint8_t inputDimValuesH[60] = { 1747 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1748 1, 0, 2, 0, 3, 0, 2, 0, 3, 0, 1, 0, 1749 1, 2, 3, 2, 3, 1, 1, 1750 1, 1, 1, 1, 1, 1, 1751 1, 1, 1, 1, 1, 1, 1752 1, 1, 1, 1, 1 1753 }; 1754 uint32_t inputIndexVectorH[6] = {1, 2, 4, 7, 9, 12}; 1755 uint32_t baseCountVectorH[16] = { 1756 0, 0, 1, 3, 4, 7, 8, 10, 13, 14, 16, 19, 22, 23, 26, 30 1757 }; 1758 // => counts{1, 2, 3, 3, 2, 1} 1759 // so normal result will be {1, 2, 2, 3, 3, 3, 2, 2, 2, 3, 3, 1} 1760 // and only cut first 10 elem 1761 1762 uint8_t outputDimValuesH[100] = {0}; 1763 uint8_t expectedDimValues[100] = { 1764 1, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1765 3, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1766 1, 0, 2, 0, 2, 0, 3, 0, 3, 0, 3, 0, 2, 0, 2, 0, 2, 0, 3, 0, 1767 1, 2, 2, 3, 3, 3, 2, 2, 2, 3, 1768 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1769 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1770 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1771 }; 1772 1773 uint8_t *inputDimValues = allocate(inputDimValuesH, 60); 1774 uint32_t *inputIndexVector = allocate(inputIndexVectorH, 6); 1775 uint32_t *baseCountVector = allocate(baseCountVectorH, 16); 1776 1777 uint8_t *outputDimValues = allocate(outputDimValuesH, 100); 1778 1779 int length = 6; 1780 int vectorCapacity = 6; 1781 DimensionColumnVector inputKeys = { 1782 inputDimValues, 1783 NULL, 1784 NULL, 1785 vectorCapacity, 1786 {(uint8_t)0, (uint8_t)0, (uint8_t)1, (uint8_t)1, (uint8_t)1}}; 1787 int outCapacity = 10; 1788 1789 DimensionColumnVector outputKeys = { 1790 outputDimValues, 1791 NULL, 1792 NULL, 1793 outCapacity, 1794 {(uint8_t)0, (uint8_t)0, (uint8_t)1, (uint8_t)1, (uint8_t)1}}; 1795 CGoCallResHandle 1796 resHandle = Expand(inputKeys, 1797 outputKeys, 1798 baseCountVector, 1799 inputIndexVector, 1800 length, 1801 0, 1802 0, 1803 0); 1804 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 10); 1805 EXPECT_EQ(resHandle.pStrErr, nullptr); 1806 EXPECT_TRUE(equal(outputDimValues, outputDimValues + 100, 1807 expectedDimValues)); 1808 } 1809 1810 TEST(ExpandTest, testAppend) { 1811 // test with 3 dimensions (4-byte, 2-byte, 1-byte) 1812 // each dimension vector has 6 elements with values assigned as 1813 // [1,2,3,2,3,1] 1814 uint8_t inputDimValuesH[60] = { 1815 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1816 1, 0, 2, 0, 3, 0, 2, 0, 3, 0, 1, 0, 1817 1, 2, 3, 2, 3, 1, 1, 1818 1, 1, 1, 1, 1, 1, 1819 1, 1, 1, 1, 1, 1, 1820 1, 1, 1, 1, 1 1821 }; 1822 uint32_t inputIndexVectorH[6] = {1, 2, 4, 7, 9, 12}; 1823 uint32_t baseCountVectorH[16] = { 1824 0, 0, 1, 3, 4, 7, 8, 10, 13, 14, 16, 19, 22, 23, 26, 30 1825 }; 1826 // => counts{1, 2, 3, 3, 2, 1} 1827 // so normal result will be {1, 2, 2, 3, 3, 3, 2, 2, 2, 3, 3, 1} 1828 // and only append the first 5 elem to the last 5 elem of output 1829 1830 uint8_t outputDimValuesH[100] = {0}; 1831 uint8_t expectedDimValues[100] = { 1832 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1833 1, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1834 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 2, 0, 3, 0, 3, 0, 1835 0, 0, 0, 0, 0, 1, 2, 2, 3, 3, 1836 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1837 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1838 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1839 }; 1840 1841 uint8_t *inputDimValues = allocate(inputDimValuesH, 60); 1842 uint32_t *inputIndexVector = allocate(inputIndexVectorH, 6); 1843 uint32_t *baseCountVector = allocate(baseCountVectorH, 16); 1844 1845 uint8_t *outputDimValues = allocate(outputDimValuesH, 100); 1846 1847 int length = 6; 1848 int vectorCapacity = 6; 1849 int outCapacity = 10; 1850 1851 DimensionColumnVector inputKeys = { 1852 inputDimValues, 1853 NULL, 1854 NULL, 1855 vectorCapacity, 1856 {(uint8_t)0, (uint8_t)0, (uint8_t)1, (uint8_t)1, (uint8_t)1}}; 1857 1858 DimensionColumnVector outputKeys = { 1859 outputDimValues, 1860 NULL, 1861 NULL, 1862 outCapacity, 1863 {(uint8_t)0, (uint8_t)0, (uint8_t)1, (uint8_t)1, (uint8_t)1}}; 1864 CGoCallResHandle 1865 resHandle = Expand(inputKeys, 1866 outputKeys, 1867 baseCountVector, 1868 inputIndexVector, 1869 length, 1870 5, 1871 0, 1872 0); 1873 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 10); 1874 EXPECT_EQ(resHandle.pStrErr, nullptr); 1875 EXPECT_TRUE(equal(outputDimValues, outputDimValues + 100, 1876 expectedDimValues)); 1877 } 1878 1879 TEST(ExpandTest, testFillPartial) { 1880 // test with 3 dimensions (4-byte, 2-byte, 1-byte) 1881 // each dimension vector has 6 elements with values assigned as 1882 // [1,2,3,2,3,1] 1883 uint8_t inputDimValuesH[60] = { 1884 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 1885 1, 0, 2, 0, 3, 0, 2, 0, 3, 0, 1, 0, 1886 1, 2, 3, 2, 3, 1, 1, 1887 1, 1, 1, 1, 1, 1, 1888 1, 1, 1, 1, 1, 1, 1889 1, 1, 1, 1, 1 1890 }; 1891 uint32_t inputIndexVectorH[6] = {1, 2, 4}; 1892 uint32_t baseCountVectorH[16] = { 1893 0, 0, 1, 3, 4, 7, 8, 10, 13, 14, 16, 19, 22, 23, 26, 30 1894 }; 1895 // => counts{1, 2, 3} 1896 // so normal result will be {1, 2, 2, 3, 3, 3} 1897 // and only cut first 10 elem 1898 1899 uint8_t outputDimValuesH[100] = {0}; 1900 uint8_t expectedDimValues[100] = { 1901 1, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 1902 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1903 1, 0, 2, 0, 2, 0, 3, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1904 1, 2, 2, 3, 3, 3, 0, 0, 0, 0, 1905 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1906 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1907 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 1908 }; 1909 1910 uint8_t *inputDimValues = allocate(inputDimValuesH, 60); 1911 uint32_t *inputIndexVector = allocate(inputIndexVectorH, 6); 1912 uint32_t *baseCountVector = allocate(baseCountVectorH, 16); 1913 1914 uint8_t *outputDimValues = allocate(outputDimValuesH, 100); 1915 1916 int length = 3; 1917 int vectorCapacity = 6; 1918 DimensionColumnVector inputKeys = { 1919 inputDimValues, 1920 NULL, 1921 NULL, 1922 vectorCapacity, 1923 {(uint8_t)0, (uint8_t)0, (uint8_t)1, (uint8_t)1, (uint8_t)1}}; 1924 int outCapacity = 10; 1925 1926 DimensionColumnVector outputKeys = { 1927 outputDimValues, 1928 NULL, 1929 NULL, 1930 outCapacity, 1931 {(uint8_t)0, (uint8_t)0, (uint8_t)1, (uint8_t)1, (uint8_t)1}}; 1932 CGoCallResHandle 1933 resHandle = Expand(inputKeys, 1934 outputKeys, 1935 baseCountVector, 1936 inputIndexVector, 1937 length, 1938 0, 1939 0, 1940 0); 1941 EXPECT_EQ(reinterpret_cast<int64_t>(resHandle.res), 6); 1942 EXPECT_EQ(resHandle.pStrErr, nullptr); 1943 EXPECT_TRUE(equal(outputDimValues, outputDimValues + 100, 1944 expectedDimValues)); 1945 } 1946 1947 } // namespace ares