blob: 18047a388685ccb1da948493c2e1bb1eb06ff928 [file]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "catch.hpp"
#include "Session.h"
#include <memory>
#include <vector>
using namespace std;
TEST_CASE("SessionUtils filterNullColumns keeps only non-null FIELD columns", "[utils]") {
vector<pair<string, TSDataType::TSDataType>> schemas = {{"s1", TSDataType::INT32},
{"s2", TSDataType::INT64},
{"s3", TSDataType::FLOAT},
{"s4", TSDataType::DOUBLE},
{"s5", TSDataType::BOOLEAN}};
Tablet tablet("root.sg.d1", schemas, 1);
tablet.timestamps[0] = 1000L;
tablet.rowSize = 1;
tablet.addValue("s1", 0, 1);
tablet.addValue("s3", 0, 1.5f);
tablet.bitMaps[1].mark(0);
tablet.bitMaps[3].mark(0);
tablet.bitMaps[4].mark(0);
std::shared_ptr<const Tablet> filtered = SessionUtils::filterNullColumns(tablet);
REQUIRE(filtered != nullptr);
REQUIRE(filtered.get() != &tablet);
REQUIRE(filtered.use_count() == 1);
REQUIRE(filtered->schemas.size() == 2);
REQUIRE(filtered->schemas[0].first == "s1");
REQUIRE(filtered->schemas[1].first == "s3");
REQUIRE(((int*)filtered->values[0])[0] == 1);
REQUIRE(((float*)filtered->values[1])[0] == Approx(1.5f));
}
TEST_CASE("SessionUtils filterNullColumns returns original when nothing to drop", "[utils]") {
vector<pair<string, TSDataType::TSDataType>> schemas = {{"s1", TSDataType::INT32}};
Tablet tablet("root.sg.d1", schemas, 1);
tablet.timestamps[0] = 1L;
tablet.rowSize = 1;
tablet.addValue("s1", 0, 1);
std::shared_ptr<const Tablet> filtered = SessionUtils::filterNullColumns(tablet);
REQUIRE(filtered.get() == &tablet);
}
TEST_CASE("SessionUtils filterNullColumns returns nullptr when tree-model FIELD columns are all null",
"[utils]") {
vector<pair<string, TSDataType::TSDataType>> schemas = {{"s1", TSDataType::INT32},
{"s2", TSDataType::INT64}};
Tablet tablet("root.sg.d1", schemas, 1);
tablet.timestamps[0] = 2000L;
tablet.rowSize = 1;
tablet.bitMaps[0].mark(0);
tablet.bitMaps[1].mark(0);
std::shared_ptr<const Tablet> filtered = SessionUtils::filterNullColumns(tablet);
REQUIRE(filtered == nullptr);
}
TEST_CASE("SessionUtils filterNullColumns keeps TAG when table-model FIELD columns are all null",
"[utils]") {
vector<pair<string, TSDataType::TSDataType>> schemas = {
{"tag1", TSDataType::TEXT}, {"s1", TSDataType::INT32}, {"s2", TSDataType::INT64}};
vector<ColumnCategory> columnTypes = {ColumnCategory::TAG, ColumnCategory::FIELD,
ColumnCategory::FIELD};
Tablet tablet("table1", schemas, columnTypes, 1);
tablet.timestamps[0] = 3000L;
tablet.rowSize = 1;
tablet.addValue("tag1", 0, string("d1"));
tablet.bitMaps[1].mark(0);
tablet.bitMaps[2].mark(0);
std::shared_ptr<const Tablet> filtered = SessionUtils::filterNullColumns(tablet);
REQUIRE(filtered != nullptr);
REQUIRE(filtered.get() != &tablet);
REQUIRE(filtered->schemas.size() == 1);
REQUIRE(filtered->schemas[0].first == "tag1");
REQUIRE(filtered->columnTypes.size() == 1);
REQUIRE(filtered->columnTypes[0] == ColumnCategory::TAG);
}
TEST_CASE("SessionUtils filterNullColumns checks active rows when bitmap is maxRowNumber-sized",
"[utils]") {
vector<pair<string, TSDataType::TSDataType>> schemas = {{"s1", TSDataType::INT32},
{"s2", TSDataType::INT64}};
Tablet tablet("root.sg.d1", schemas, 10);
tablet.timestamps[0] = 1000L;
tablet.rowSize = 1;
tablet.addValue("s1", 0, 1);
tablet.bitMaps[1].mark(0);
std::shared_ptr<const Tablet> filtered = SessionUtils::filterNullColumns(tablet);
REQUIRE(filtered != nullptr);
REQUIRE(filtered->schemas.size() == 1);
REQUIRE(filtered->schemas[0].first == "s1");
}
TEST_CASE("BitMap isRangeAllMarked matches per-bit scan and rejects OOB", "[utils]") {
BitMap bitMap(20);
for (size_t i = 0; i < 20; i++) {
if (i % 4 != 2) {
bitMap.mark(i);
}
}
for (size_t start = 0; start <= 20; start++) {
for (size_t length = 0; length <= 20 - start; length++) {
bool allMarked = true;
for (size_t i = start; i < start + length; i++) {
allMarked = allMarked && bitMap.isMarked(i);
}
REQUIRE(bitMap.isRangeAllMarked(start, length) == allMarked);
}
}
REQUIRE(bitMap.isRangeAllMarked(0, 0));
REQUIRE_FALSE(bitMap.isRangeAllMarked(0, 21));
REQUIRE_FALSE(bitMap.isRangeAllMarked(21, 0));
BitMap empty;
REQUIRE(empty.isAllMarked());
BitMap full(8);
full.markAll();
REQUIRE(full.isAllMarked());
full.unmark(7);
REQUIRE_FALSE(full.isAllMarked());
REQUIRE(full.isRangeAllMarked(0, 7));
}