mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
Added tests
This commit is contained in:
parent
c74011851a
commit
07c8293043
@ -10,12 +10,6 @@ target_link_libraries (sip_hash_perf PRIVATE clickhouse_common_io)
|
||||
add_executable (auto_array auto_array.cpp)
|
||||
target_link_libraries (auto_array PRIVATE clickhouse_common_io)
|
||||
|
||||
add_executable (hash_table hash_table.cpp)
|
||||
target_link_libraries (hash_table PRIVATE clickhouse_common_io)
|
||||
|
||||
add_executable (hash_table_erase hash_table_erase.cpp)
|
||||
target_link_libraries (hash_table_erase PRIVATE clickhouse_common_io)
|
||||
|
||||
add_executable (small_table small_table.cpp)
|
||||
target_link_libraries (small_table PRIVATE clickhouse_common_io)
|
||||
|
||||
|
210
src/Common/tests/gtest_hash_table.cpp
Normal file
210
src/Common/tests/gtest_hash_table.cpp
Normal file
@ -0,0 +1,210 @@
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
#include <Interpreters/AggregationCommon.h>
|
||||
|
||||
#include <Common/HashTable/HashMap.h>
|
||||
#include <Common/HashTable/HashSet.h>
|
||||
|
||||
#include <IO/ReadBufferFromString.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
/// To test dump functionality without using other hashes that can change
|
||||
template <typename T>
|
||||
struct DummyHash
|
||||
{
|
||||
size_t operator()(T key) const { return T(key); }
|
||||
};
|
||||
|
||||
template<typename HashTable>
|
||||
std::set<typename HashTable::value_type> convertToSet(const HashTable& table)
|
||||
{
|
||||
std::set<typename HashTable::value_type> result;
|
||||
|
||||
for (auto v: table)
|
||||
result.emplace(v.getValue());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
TEST(HashTable, Insert)
|
||||
{
|
||||
using Cont = HashSet<int, DefaultHash<int>, HashTableGrower<1>>;
|
||||
|
||||
Cont cont;
|
||||
|
||||
cont.insert(1);
|
||||
cont.insert(2);
|
||||
|
||||
ASSERT_EQ(cont.size(), 2);
|
||||
}
|
||||
|
||||
TEST(HashTable, Emplace)
|
||||
{
|
||||
using Cont = HashSet<int, DefaultHash<int>, HashTableGrower<1>>;
|
||||
|
||||
Cont cont;
|
||||
|
||||
Cont::LookupResult it;
|
||||
bool inserted = false;
|
||||
cont.emplace(1, it, inserted);
|
||||
ASSERT_EQ(it->getKey(), 1);
|
||||
ASSERT_EQ(inserted, true);
|
||||
|
||||
cont.emplace(2, it, inserted);
|
||||
ASSERT_EQ(it->getKey(), 2);
|
||||
ASSERT_EQ(inserted, true);
|
||||
|
||||
cont.emplace(1, it, inserted);
|
||||
ASSERT_EQ(it->getKey(), 1);
|
||||
ASSERT_EQ(inserted, false);
|
||||
}
|
||||
|
||||
TEST(HashTable, Lookup)
|
||||
{
|
||||
using Cont = HashSet<int, DefaultHash<int>, HashTableGrower<1>>;
|
||||
|
||||
Cont cont;
|
||||
|
||||
cont.insert(1);
|
||||
cont.insert(2);
|
||||
|
||||
Cont::LookupResult it = cont.find(1);
|
||||
ASSERT_TRUE(it != nullptr);
|
||||
|
||||
it = cont.find(2);
|
||||
ASSERT_TRUE(it != nullptr);
|
||||
|
||||
it = cont.find(3);
|
||||
ASSERT_TRUE(it == nullptr);
|
||||
}
|
||||
|
||||
TEST(HashTable, Iteration)
|
||||
{
|
||||
using Cont = HashSet<int, DefaultHash<int>, HashTableGrower<1>>;
|
||||
|
||||
Cont cont;
|
||||
|
||||
cont.insert(1);
|
||||
cont.insert(2);
|
||||
cont.insert(3);
|
||||
|
||||
std::set<int> expected = {1, 2, 3};
|
||||
std::set<int> actual = convertToSet(cont);
|
||||
|
||||
ASSERT_EQ(actual, expected);
|
||||
}
|
||||
|
||||
TEST(HashTable, Erase)
|
||||
{
|
||||
using Cont = HashSet<int, DefaultHash<int>, HashTableGrower<1>>;
|
||||
Cont cont;
|
||||
|
||||
for (size_t i = 0; i < 5000; ++i)
|
||||
{
|
||||
cont.insert(i);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 2500; ++i)
|
||||
{
|
||||
cont.erase(i);
|
||||
}
|
||||
|
||||
for (size_t i = 5000; i < 10000; ++i)
|
||||
{
|
||||
cont.insert(i);
|
||||
}
|
||||
|
||||
for (size_t i = 5000; i < 10000; ++i)
|
||||
{
|
||||
cont.erase(i);
|
||||
}
|
||||
|
||||
for (size_t i = 2500; i < 5000; ++i)
|
||||
{
|
||||
cont.erase(i);
|
||||
}
|
||||
|
||||
ASSERT_EQ(cont.size(), 0);
|
||||
}
|
||||
|
||||
TEST(HashTable, SerializationDeserialization)
|
||||
{
|
||||
{
|
||||
/// Use dummy hash to make it reproducible if default hash implementation will be changed
|
||||
using Cont = HashSet<int, DummyHash<int>, HashTableGrower<1>>;
|
||||
|
||||
Cont cont;
|
||||
|
||||
cont.insert(1);
|
||||
cont.insert(2);
|
||||
cont.insert(3);
|
||||
|
||||
DB::WriteBufferFromOwnString wb;
|
||||
cont.writeText(wb);
|
||||
|
||||
std::string expected = "3,1,2,3";
|
||||
|
||||
ASSERT_EQ(wb.str(), expected);
|
||||
|
||||
DB::ReadBufferFromString rb(expected);
|
||||
|
||||
Cont deserialized;
|
||||
deserialized.readText(rb);
|
||||
ASSERT_EQ(convertToSet(cont), convertToSet(deserialized));
|
||||
}
|
||||
{
|
||||
using Cont = HashSet<int, DefaultHash<int>, HashTableGrower<1>>;
|
||||
|
||||
Cont cont;
|
||||
|
||||
cont.insert(1);
|
||||
cont.insert(2);
|
||||
cont.insert(3);
|
||||
|
||||
DB::WriteBufferFromOwnString wb;
|
||||
cont.write(wb);
|
||||
|
||||
DB::ReadBufferFromString rb(wb.str());
|
||||
|
||||
Cont deserialized;
|
||||
deserialized.read(rb);
|
||||
ASSERT_EQ(convertToSet(cont), convertToSet(deserialized));
|
||||
}
|
||||
{
|
||||
using Cont = HashSet<int, DummyHash<int>, HashTableGrower<1>>;
|
||||
Cont cont;
|
||||
|
||||
DB::WriteBufferFromOwnString wb;
|
||||
cont.writeText(wb);
|
||||
|
||||
std::string expected = "0";
|
||||
ASSERT_EQ(wb.str(), expected);
|
||||
|
||||
DB::ReadBufferFromString rb(expected);
|
||||
|
||||
Cont deserialized;
|
||||
deserialized.readText(rb);
|
||||
ASSERT_EQ(convertToSet(cont), convertToSet(deserialized));
|
||||
}
|
||||
{
|
||||
using Cont = HashSet<DB::UInt128, DB::UInt128TrivialHash>;
|
||||
Cont cont;
|
||||
|
||||
DB::WriteBufferFromOwnString wb;
|
||||
cont.write(wb);
|
||||
|
||||
std::string expected;
|
||||
expected += static_cast<char>(0);
|
||||
|
||||
ASSERT_EQ(wb.str(), expected);
|
||||
|
||||
DB::ReadBufferFromString rb(expected);
|
||||
|
||||
Cont deserialized;
|
||||
deserialized.read(rb);
|
||||
ASSERT_EQ(convertToSet(cont), convertToSet(deserialized));
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
#include <Interpreters/AggregationCommon.h>
|
||||
|
||||
#include <Common/HashTable/HashMap.h>
|
||||
#include <Common/HashTable/HashSet.h>
|
||||
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
{
|
||||
using Cont = HashSet<int, DefaultHash<int>, HashTableGrower<1>>;
|
||||
Cont cont;
|
||||
|
||||
cont.insert(1);
|
||||
cont.insert(2);
|
||||
|
||||
Cont::LookupResult it;
|
||||
bool inserted;
|
||||
int key = 3;
|
||||
cont.emplace(key, it, inserted);
|
||||
std::cerr << inserted << ", " << key << std::endl;
|
||||
|
||||
cont.emplace(key, it, inserted);
|
||||
std::cerr << inserted << ", " << key << std::endl;
|
||||
|
||||
std::cerr << "Before erase" << std::endl;
|
||||
for (auto x : cont)
|
||||
std::cerr << x.getValue() << std::endl;
|
||||
|
||||
DB::WriteBufferFromOwnString wb;
|
||||
cont.writeText(wb);
|
||||
|
||||
std::cerr << "Dump before erase: " << wb.str() << std::endl;
|
||||
|
||||
cont.erase(2);
|
||||
cont.erase(3);
|
||||
|
||||
std::cerr << "After erase" << std::endl;
|
||||
for (auto x : cont)
|
||||
std::cerr << x.getValue() << std::endl;
|
||||
|
||||
wb.restart();
|
||||
cont.writeText(wb);
|
||||
|
||||
std::cerr << "Dump after erase: " << wb.str() << std::endl;
|
||||
}
|
||||
|
||||
{
|
||||
using Cont = HashSet<
|
||||
DB::UInt128,
|
||||
DB::UInt128TrivialHash>;
|
||||
Cont cont;
|
||||
|
||||
DB::WriteBufferFromOwnString wb;
|
||||
cont.write(wb);
|
||||
|
||||
std::cerr << "dump: " << wb.str() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
#include <Common/HashTable/HashMap.h>
|
||||
#include <Common/HashTable/HashSet.h>
|
||||
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
{
|
||||
using Cont = HashSet<int, DefaultHash<int>, HashTableGrower<1>>;
|
||||
Cont cont;
|
||||
|
||||
for (size_t i = 0; i < 5000; ++i)
|
||||
{
|
||||
cont.insert(i);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < 2500; ++i)
|
||||
{
|
||||
cont.erase(i);
|
||||
}
|
||||
|
||||
for (size_t i = 5000; i < 10000; ++i)
|
||||
{
|
||||
cont.insert(i);
|
||||
}
|
||||
|
||||
for (size_t i = 5000; i < 10000; ++i)
|
||||
{
|
||||
cont.erase(i);
|
||||
}
|
||||
|
||||
for (size_t i = 2500; i < 5000; ++i)
|
||||
{
|
||||
cont.erase(i);
|
||||
}
|
||||
|
||||
std::cerr << "size: " << cont.size() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -9,7 +9,7 @@ FROM
|
||||
number % 7 AS k,
|
||||
arrayMap(x -> arrayMap(x -> if(x = 0, NULL, toString(x)), range(x)), range(intDiv(number, 1))) AS v
|
||||
FROM system.numbers
|
||||
LIMIT 512
|
||||
LIMIT 10
|
||||
)
|
||||
GROUP BY k
|
||||
ORDER BY k ASC
|
||||
|
Loading…
Reference in New Issue
Block a user