blob: da23bc5437cd4f0189b88f757b7ae507ca5f9cf7 [file] [log] [blame]
// 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 "olap/key_coder.h"
#include <gtest/gtest.h>
#include <string.h>
#include <limits>
#include "runtime/mem_pool.h"
#include "runtime/mem_tracker.h"
#include "util/debug_util.h"
namespace doris {
class KeyCoderTest : public testing::Test {
public:
KeyCoderTest() : _tracker(new MemTracker()), _pool(_tracker.get()) {}
virtual ~KeyCoderTest() {}
private:
std::shared_ptr<MemTracker> _tracker;
MemPool _pool;
};
template <FieldType type>
void test_integer_encode() {
using CppType = typename CppTypeTraits<type>::CppType;
auto key_coder = get_key_coder(type);
{
std::string buf;
CppType val = std::numeric_limits<CppType>::min();
key_coder->encode_ascending(&val, 1, &buf);
std::string result;
for (int i = 0; i < sizeof(CppType); ++i) {
result.append("00");
}
ASSERT_STREQ(result.c_str(), hexdump(buf.data(), buf.size()).c_str());
{
Slice slice(buf);
CppType check_val;
key_coder->decode_ascending(&slice, sizeof(CppType), (uint8_t*)&check_val, nullptr);
ASSERT_EQ(val, check_val);
}
}
{
std::string buf;
CppType val = std::numeric_limits<CppType>::max();
key_coder->encode_ascending(&val, sizeof(CppType), &buf);
std::string result;
for (int i = 0; i < sizeof(CppType); ++i) {
result.append("FF");
}
ASSERT_STREQ(result.c_str(), hexdump(buf.data(), buf.size()).c_str());
{
Slice slice(buf);
CppType check_val;
key_coder->decode_ascending(&slice, sizeof(CppType), (uint8_t*)&check_val, nullptr);
ASSERT_EQ(val, check_val);
}
}
for (auto i = 0; i < 100; ++i) {
CppType val1 = random();
CppType val2 = random();
std::string buf1;
std::string buf2;
key_coder->encode_ascending(&val1, sizeof(CppType), &buf1);
key_coder->encode_ascending(&val2, sizeof(CppType), &buf2);
if (val1 < val2) {
ASSERT_TRUE(memcmp(buf1.c_str(), buf2.c_str(), buf1.size()) < 0);
} else if (val1 > val2) {
ASSERT_TRUE(memcmp(buf1.c_str(), buf2.c_str(), buf1.size()) > 0);
} else {
ASSERT_TRUE(memcmp(buf1.c_str(), buf2.c_str(), buf1.size()) == 0);
}
}
}
TEST_F(KeyCoderTest, test_int) {
test_integer_encode<OLAP_FIELD_TYPE_TINYINT>();
test_integer_encode<OLAP_FIELD_TYPE_SMALLINT>();
test_integer_encode<OLAP_FIELD_TYPE_INT>();
test_integer_encode<OLAP_FIELD_TYPE_UNSIGNED_INT>();
test_integer_encode<OLAP_FIELD_TYPE_BIGINT>();
test_integer_encode<OLAP_FIELD_TYPE_UNSIGNED_BIGINT>();
test_integer_encode<OLAP_FIELD_TYPE_LARGEINT>();
test_integer_encode<OLAP_FIELD_TYPE_DATETIME>();
}
TEST_F(KeyCoderTest, test_date) {
using CppType = uint24_t;
auto key_coder = get_key_coder(OLAP_FIELD_TYPE_DATE);
{
std::string buf;
CppType val = 0;
key_coder->encode_ascending(&val, 1, &buf);
std::string result;
for (int i = 0; i < sizeof(uint24_t); ++i) {
result.append("00");
}
ASSERT_STREQ(result.c_str(), hexdump(buf.data(), buf.size()).c_str());
{
Slice slice(buf);
CppType check_val;
key_coder->decode_ascending(&slice, sizeof(CppType), (uint8_t*)&check_val, nullptr);
ASSERT_EQ(val, check_val);
}
}
{
std::string buf;
CppType val = 10000;
key_coder->encode_ascending(&val, sizeof(CppType), &buf);
std::string result("002710");
ASSERT_STREQ(result.c_str(), hexdump(buf.data(), buf.size()).c_str());
{
Slice slice(buf);
CppType check_val;
key_coder->decode_ascending(&slice, sizeof(CppType), (uint8_t*)&check_val, nullptr);
ASSERT_EQ(val, check_val);
}
}
for (auto i = 0; i < 100; ++i) {
CppType val1 = random();
CppType val2 = random();
std::string buf1;
std::string buf2;
key_coder->encode_ascending(&val1, sizeof(CppType), &buf1);
key_coder->encode_ascending(&val2, sizeof(CppType), &buf2);
if (val1 < val2) {
ASSERT_TRUE(memcmp(buf1.c_str(), buf2.c_str(), buf1.size()) < 0);
} else if (val1 > val2) {
ASSERT_TRUE(memcmp(buf1.c_str(), buf2.c_str(), buf1.size()) > 0);
} else {
ASSERT_TRUE(memcmp(buf1.c_str(), buf2.c_str(), buf1.size()) == 0);
}
}
}
TEST_F(KeyCoderTest, test_decimal) {
auto key_coder = get_key_coder(OLAP_FIELD_TYPE_DECIMAL);
decimal12_t val1(1, 100000000);
std::string buf1;
key_coder->encode_ascending(&val1, sizeof(decimal12_t), &buf1);
decimal12_t check_val;
Slice slice1(buf1);
key_coder->decode_ascending(&slice1, sizeof(decimal12_t), (uint8_t*)&check_val, nullptr);
ASSERT_EQ(check_val, val1);
{
decimal12_t val2(-1, -100000000);
std::string buf2;
key_coder->encode_ascending(&val2, sizeof(decimal12_t), &buf2);
ASSERT_TRUE(memcmp(buf1.c_str(), buf2.c_str(), buf1.size()) > 0);
}
{
decimal12_t val2(1, 100000001);
std::string buf2;
key_coder->encode_ascending(&val2, sizeof(decimal12_t), &buf2);
ASSERT_TRUE(memcmp(buf1.c_str(), buf2.c_str(), buf1.size()) < 0);
}
{
decimal12_t val2(0, 0);
std::string buf2;
key_coder->encode_ascending(&val2, sizeof(decimal12_t), &buf2);
ASSERT_TRUE(memcmp(buf1.c_str(), buf2.c_str(), buf1.size()) > 0);
std::string result("80");
for (int i = 0; i < sizeof(int64_t) - 1; ++i) {
result.append("00");
}
result.append("80");
for (int i = 0; i < sizeof(int32_t) - 1; ++i) {
result.append("00");
}
ASSERT_STREQ(result.c_str(), hexdump(buf2.data(), buf2.size()).c_str());
}
}
TEST_F(KeyCoderTest, test_char) {
auto key_coder = get_key_coder(OLAP_FIELD_TYPE_CHAR);
char buf[] = "1234567890";
Slice slice(buf, 10);
{
std::string key;
key_coder->encode_ascending(&slice, 10, &key);
Slice encoded_key(key);
Slice check_slice;
auto st = key_coder->decode_ascending(&encoded_key, 10, (uint8_t*)&check_slice, &_pool);
ASSERT_TRUE(st.ok());
ASSERT_EQ(10, check_slice.size);
ASSERT_EQ(strncmp("1234567890", check_slice.data, 10), 0);
}
{
std::string key;
key_coder->encode_ascending(&slice, 5, &key);
Slice encoded_key(key);
Slice check_slice;
auto st = key_coder->decode_ascending(&encoded_key, 5, (uint8_t*)&check_slice, &_pool);
ASSERT_TRUE(st.ok());
ASSERT_EQ(5, check_slice.size);
ASSERT_EQ(strncmp("12345", check_slice.data, 5), 0);
}
}
TEST_F(KeyCoderTest, test_varchar) {
auto key_coder = get_key_coder(OLAP_FIELD_TYPE_VARCHAR);
char buf[] = "1234567890";
Slice slice(buf, 10);
{
std::string key;
key_coder->encode_ascending(&slice, 15, &key);
Slice encoded_key(key);
Slice check_slice;
auto st = key_coder->decode_ascending(&encoded_key, 15, (uint8_t*)&check_slice, &_pool);
ASSERT_TRUE(st.ok());
ASSERT_EQ(10, check_slice.size);
ASSERT_EQ(strncmp("1234567890", check_slice.data, 10), 0);
}
{
std::string key;
key_coder->encode_ascending(&slice, 5, &key);
Slice encoded_key(key);
Slice check_slice;
auto st = key_coder->decode_ascending(&encoded_key, 5, (uint8_t*)&check_slice, &_pool);
ASSERT_TRUE(st.ok());
ASSERT_EQ(5, check_slice.size);
ASSERT_EQ(strncmp("12345", check_slice.data, 5), 0);
}
}
} // namespace doris
int main(int argc, char** argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}