mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-26 09:32:01 +00:00
commit
e4c62935c3
@ -8,6 +8,7 @@
|
|||||||
#include <boost/range/iterator_range_core.hpp>
|
#include <boost/range/iterator_range_core.hpp>
|
||||||
#include <DB/Parsers/ExpressionElementParsers.h>
|
#include <DB/Parsers/ExpressionElementParsers.h>
|
||||||
#include <DB/Parsers/ASTLiteral.h>
|
#include <DB/Parsers/ASTLiteral.h>
|
||||||
|
#include <DB/Common/PODArray.h>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
@ -44,7 +45,8 @@ struct AggregateFunctionSequenceMatchData final
|
|||||||
using Comparator = ComparePairFirst<std::less>;
|
using Comparator = ComparePairFirst<std::less>;
|
||||||
|
|
||||||
bool sorted = true;
|
bool sorted = true;
|
||||||
std::vector<TimestampEvents> eventsList;
|
static constexpr size_t bytes_in_arena = 64;
|
||||||
|
PODArray<TimestampEvents, bytes_in_arena, AllocatorWithStackMemory<Allocator<false>, bytes_in_arena>> eventsList;
|
||||||
|
|
||||||
void add(const Timestamp timestamp, const Events & events)
|
void add(const Timestamp timestamp, const Events & events)
|
||||||
{
|
{
|
||||||
@ -60,7 +62,7 @@ struct AggregateFunctionSequenceMatchData final
|
|||||||
{
|
{
|
||||||
const auto size = eventsList.size();
|
const auto size = eventsList.size();
|
||||||
|
|
||||||
eventsList.insert(std::end(eventsList), std::begin(other.eventsList), std::end(other.eventsList));
|
eventsList.insert(std::begin(other.eventsList), std::end(other.eventsList));
|
||||||
|
|
||||||
/// either sort whole container or do so partially merging ranges afterwards
|
/// either sort whole container or do so partially merging ranges afterwards
|
||||||
if (!sorted && !other.sorted)
|
if (!sorted && !other.sorted)
|
||||||
@ -111,7 +113,7 @@ struct AggregateFunctionSequenceMatchData final
|
|||||||
std::size_t size;
|
std::size_t size;
|
||||||
readBinary(size, buf);
|
readBinary(size, buf);
|
||||||
|
|
||||||
decltype(eventsList) eventsList;
|
eventsList.clear();
|
||||||
eventsList.reserve(size);
|
eventsList.reserve(size);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < size; ++i)
|
for (std::size_t i = 0; i < size; ++i)
|
||||||
@ -124,8 +126,6 @@ struct AggregateFunctionSequenceMatchData final
|
|||||||
|
|
||||||
eventsList.emplace_back(timestamp, Events{events});
|
eventsList.emplace_back(timestamp, Events{events});
|
||||||
}
|
}
|
||||||
|
|
||||||
this->eventsList = std::move(eventsList);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -262,14 +262,14 @@ private:
|
|||||||
PatternAction(const PatternActionType type, const std::uint32_t extra = 0) : type{type}, extra{extra} {}
|
PatternAction(const PatternActionType type, const std::uint32_t extra = 0) : type{type}, extra{extra} {}
|
||||||
};
|
};
|
||||||
|
|
||||||
using PatternActions = std::vector<PatternAction>;
|
static constexpr size_t bytes_on_stack = 64;
|
||||||
|
using PatternActions = PODArray<PatternAction, bytes_on_stack, AllocatorWithStackMemory<Allocator<false>, bytes_on_stack>>;
|
||||||
|
|
||||||
|
|
||||||
void parsePattern()
|
void parsePattern()
|
||||||
{
|
{
|
||||||
PatternActions actions{
|
actions.clear();
|
||||||
{ PatternActionType::KleeneStar }
|
actions.emplace_back(PatternActionType::KleeneStar);
|
||||||
};
|
|
||||||
|
|
||||||
ParserString special_open_p("(?");
|
ParserString special_open_p("(?");
|
||||||
ParserString special_close_p(")");
|
ParserString special_close_p(")");
|
||||||
@ -354,8 +354,6 @@ private:
|
|||||||
else
|
else
|
||||||
throw_exception("Could not parse pattern, unexpected starting symbol");
|
throw_exception("Could not parse pattern, unexpected starting symbol");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->actions = std::move(actions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -164,6 +164,12 @@ public:
|
|||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static constexpr size_t getStackThreshold()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -209,6 +215,12 @@ public:
|
|||||||
memcpy(new_buf, buf, old_size);
|
memcpy(new_buf, buf, old_size);
|
||||||
return new_buf;
|
return new_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static constexpr size_t getStackThreshold()
|
||||||
|
{
|
||||||
|
return N;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,6 +109,17 @@ private:
|
|||||||
c_end_of_storage = c_start + bytes - pad_right;
|
c_end_of_storage = c_start + bytes - pad_right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isInitialized() const
|
||||||
|
{
|
||||||
|
return (c_start != nullptr) && (c_end != nullptr) && (c_end_of_storage != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isAllocatedFromStack() const
|
||||||
|
{
|
||||||
|
constexpr size_t stack_threshold = TAllocator::getStackThreshold();
|
||||||
|
return (stack_threshold > 0) && (allocated_size() <= stack_threshold);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
|
|
||||||
@ -130,55 +141,46 @@ public:
|
|||||||
|
|
||||||
PODArray() {}
|
PODArray() {}
|
||||||
|
|
||||||
PODArray(size_t n)
|
PODArray(size_t n)
|
||||||
{
|
{
|
||||||
alloc_for_num_elements(n);
|
alloc_for_num_elements(n);
|
||||||
c_end += byte_size(n);
|
c_end += byte_size(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
PODArray(size_t n, const T & x)
|
PODArray(size_t n, const T & x)
|
||||||
{
|
{
|
||||||
alloc_for_num_elements(n);
|
alloc_for_num_elements(n);
|
||||||
assign(n, x);
|
assign(n, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
PODArray(const_iterator from_begin, const_iterator from_end)
|
PODArray(const_iterator from_begin, const_iterator from_end)
|
||||||
{
|
{
|
||||||
alloc_for_num_elements(from_end - from_begin);
|
alloc_for_num_elements(from_end - from_begin);
|
||||||
insert(from_begin, from_end);
|
insert(from_begin, from_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
~PODArray()
|
~PODArray()
|
||||||
{
|
{
|
||||||
dealloc();
|
dealloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
PODArray(PODArray && other)
|
PODArray(PODArray && other)
|
||||||
{
|
{
|
||||||
c_start = other.c_start;
|
this->swap(other);
|
||||||
c_end = other.c_end;
|
|
||||||
c_end_of_storage = other.c_end_of_storage;
|
|
||||||
|
|
||||||
other.c_start = nullptr;
|
|
||||||
other.c_end = nullptr;
|
|
||||||
other.c_end_of_storage = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PODArray & operator=(PODArray && other)
|
PODArray & operator=(PODArray && other)
|
||||||
{
|
{
|
||||||
std::swap(c_start, other.c_start);
|
this->swap(other);
|
||||||
std::swap(c_end, other.c_end);
|
|
||||||
std::swap(c_end_of_storage, other.c_end_of_storage);
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
T * data() { return t_start(); }
|
T * data() { return t_start(); }
|
||||||
const T * data() const { return t_start(); }
|
const T * data() const { return t_start(); }
|
||||||
|
|
||||||
size_t size() const { return t_end() - t_start(); }
|
size_t size() const { return t_end() - t_start(); }
|
||||||
bool empty() const { return t_end() == t_start(); }
|
bool empty() const { return t_end() == t_start(); }
|
||||||
size_t capacity() const { return t_end_of_storage() - t_start(); }
|
size_t capacity() const { return t_end_of_storage() - t_start(); }
|
||||||
|
|
||||||
T & operator[] (size_t n) { return t_start()[n]; }
|
T & operator[] (size_t n) { return t_start()[n]; }
|
||||||
const T & operator[] (size_t n) const { return t_start()[n]; }
|
const T & operator[] (size_t n) const { return t_start()[n]; }
|
||||||
@ -310,9 +312,107 @@ public:
|
|||||||
|
|
||||||
void swap(PODArray & rhs)
|
void swap(PODArray & rhs)
|
||||||
{
|
{
|
||||||
std::swap(c_start, rhs.c_start);
|
/// Swap two PODArray objects, arr1 and arr2, that satisfy the following conditions:
|
||||||
std::swap(c_end, rhs.c_end);
|
/// - The elements of arr1 are stored on stack.
|
||||||
std::swap(c_end_of_storage, rhs.c_end_of_storage);
|
/// - The elements of arr2 are stored on heap.
|
||||||
|
auto swap_stack_heap = [](PODArray & arr1, PODArray & arr2)
|
||||||
|
{
|
||||||
|
size_t stack_size = arr1.size();
|
||||||
|
size_t stack_allocated = arr1.allocated_size();
|
||||||
|
|
||||||
|
size_t heap_size = arr2.size();
|
||||||
|
size_t heap_allocated = arr2.allocated_size();
|
||||||
|
|
||||||
|
/// Keep track of the stack content we have to copy.
|
||||||
|
char * stack_c_start = arr1.c_start;
|
||||||
|
|
||||||
|
/// arr1 takes ownership of the heap memory of arr2.
|
||||||
|
arr1.c_start = arr2.c_start;
|
||||||
|
arr1.c_end_of_storage = arr1.c_start + heap_allocated - arr1.pad_right;
|
||||||
|
arr1.c_end = arr1.c_start + byte_size(heap_size);
|
||||||
|
|
||||||
|
/// Allocate stack space for arr2.
|
||||||
|
arr2.alloc(stack_allocated);
|
||||||
|
/// Copy the stack content.
|
||||||
|
memcpy(arr2.c_start, stack_c_start, byte_size(stack_size));
|
||||||
|
arr2.c_end = arr2.c_start + byte_size(stack_size);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto do_move = [](PODArray & src, PODArray & dest)
|
||||||
|
{
|
||||||
|
if (src.isAllocatedFromStack())
|
||||||
|
{
|
||||||
|
dest.dealloc();
|
||||||
|
dest.alloc(src.allocated_size());
|
||||||
|
memcpy(dest.c_start, src.c_start, byte_size(src.size()));
|
||||||
|
dest.c_end = dest.c_start + (src.c_end - src.c_start);
|
||||||
|
|
||||||
|
src.c_start = nullptr;
|
||||||
|
src.c_end = nullptr;
|
||||||
|
src.c_end_of_storage = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::swap(dest.c_start, src.c_start);
|
||||||
|
std::swap(dest.c_end, src.c_end);
|
||||||
|
std::swap(dest.c_end_of_storage, src.c_end_of_storage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!isInitialized() && !rhs.isInitialized())
|
||||||
|
return;
|
||||||
|
else if (!isInitialized() && rhs.isInitialized())
|
||||||
|
{
|
||||||
|
do_move(rhs, *this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (isInitialized() && !rhs.isInitialized())
|
||||||
|
{
|
||||||
|
do_move(*this, rhs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAllocatedFromStack() && rhs.isAllocatedFromStack())
|
||||||
|
{
|
||||||
|
size_t min_size = std::min(size(), rhs.size());
|
||||||
|
size_t max_size = std::max(size(), rhs.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < min_size; ++i)
|
||||||
|
std::swap(this->operator[](i), rhs[i]);
|
||||||
|
|
||||||
|
if (size() == max_size)
|
||||||
|
{
|
||||||
|
for (size_t i = min_size; i < max_size; ++i)
|
||||||
|
rhs[i] = this->operator[](i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (size_t i = min_size; i < max_size; ++i)
|
||||||
|
this->operator[](i) = rhs[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t lhs_size = size();
|
||||||
|
size_t lhs_allocated = allocated_size();
|
||||||
|
|
||||||
|
size_t rhs_size = rhs.size();
|
||||||
|
size_t rhs_allocated = rhs.allocated_size();
|
||||||
|
|
||||||
|
c_end_of_storage = c_start + rhs_allocated - pad_right;
|
||||||
|
rhs.c_end_of_storage = rhs.c_start + lhs_allocated - pad_right;
|
||||||
|
|
||||||
|
c_end = c_start + byte_size(rhs_size);
|
||||||
|
rhs.c_end = rhs.c_start + byte_size(lhs_size);
|
||||||
|
}
|
||||||
|
else if (isAllocatedFromStack() && !rhs.isAllocatedFromStack())
|
||||||
|
swap_stack_heap(*this, rhs);
|
||||||
|
else if (!isAllocatedFromStack() && rhs.isAllocatedFromStack())
|
||||||
|
swap_stack_heap(rhs, *this);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::swap(c_start, rhs.c_start);
|
||||||
|
std::swap(c_end, rhs.c_end);
|
||||||
|
std::swap(c_end_of_storage, rhs.c_end_of_storage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void assign(size_t n, const T & x)
|
void assign(size_t n, const T & x)
|
||||||
@ -365,6 +465,11 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, size_t INITIAL_SIZE, typename TAllocator, size_t pad_right_>
|
||||||
|
void swap(PODArray<T, INITIAL_SIZE, TAllocator, pad_right_> & lhs, PODArray<T, INITIAL_SIZE, TAllocator, pad_right_> & rhs)
|
||||||
|
{
|
||||||
|
lhs.swap(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
/** Для столбцов. Padding-а хватает, чтобы читать и писать xmm-регистр по адресу последнего элемента. */
|
/** Для столбцов. Padding-а хватает, чтобы читать и писать xmm-регистр по адресу последнего элемента. */
|
||||||
template <typename T, size_t INITIAL_SIZE = 4096, typename TAllocator = Allocator<false>>
|
template <typename T, size_t INITIAL_SIZE = 4096, typename TAllocator = Allocator<false>>
|
||||||
|
@ -42,3 +42,6 @@ target_link_libraries (shell_command_test dbms)
|
|||||||
|
|
||||||
add_executable (arena_with_free_lists arena_with_free_lists.cpp)
|
add_executable (arena_with_free_lists arena_with_free_lists.cpp)
|
||||||
target_link_libraries (arena_with_free_lists dbms)
|
target_link_libraries (arena_with_free_lists dbms)
|
||||||
|
|
||||||
|
add_executable (pod_array pod_array.cpp)
|
||||||
|
target_link_libraries (pod_array dbms)
|
455
dbms/src/Common/tests/pod_array.cpp
Normal file
455
dbms/src/Common/tests/pod_array.cpp
Normal file
@ -0,0 +1,455 @@
|
|||||||
|
#include <DB/Common/PODArray.h>
|
||||||
|
#include <DB/Core/Types.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define ASSERT_CHECK(cond, res) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (!(cond)) \
|
||||||
|
{ \
|
||||||
|
std::cerr << __FILE__ << ":" << __LINE__ << ":" \
|
||||||
|
<< "Assertion " << #cond << " failed.\n"; \
|
||||||
|
if ((res)) { (res) = false; } \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
void test1()
|
||||||
|
{
|
||||||
|
using namespace DB;
|
||||||
|
|
||||||
|
static constexpr size_t initial_size = 8;
|
||||||
|
static constexpr size_t stack_threshold = 32;
|
||||||
|
using Array = PODArray<UInt64, initial_size, AllocatorWithStackMemory<Allocator<false>, stack_threshold>>;
|
||||||
|
|
||||||
|
bool res = true;
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
Array arr2;
|
||||||
|
arr2 = std::move(arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
|
||||||
|
arr.push_back(1);
|
||||||
|
arr.push_back(2);
|
||||||
|
arr.push_back(3);
|
||||||
|
|
||||||
|
Array arr2;
|
||||||
|
|
||||||
|
arr2 = std::move(arr);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 3), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr2[2] == 3), res);
|
||||||
|
|
||||||
|
arr = std::move(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 3), res);
|
||||||
|
ASSERT_CHECK((arr[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr[2] == 3), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
|
||||||
|
arr.push_back(1);
|
||||||
|
arr.push_back(2);
|
||||||
|
arr.push_back(3);
|
||||||
|
arr.push_back(4);
|
||||||
|
arr.push_back(5);
|
||||||
|
|
||||||
|
Array arr2;
|
||||||
|
|
||||||
|
arr2 = std::move(arr);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 5), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr2[2] == 3), res);
|
||||||
|
ASSERT_CHECK((arr2[3] == 4), res);
|
||||||
|
ASSERT_CHECK((arr2[4] == 5), res);
|
||||||
|
|
||||||
|
arr = std::move(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 5), res);
|
||||||
|
ASSERT_CHECK((arr[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr[2] == 3), res);
|
||||||
|
ASSERT_CHECK((arr[3] == 4), res);
|
||||||
|
ASSERT_CHECK((arr[4] == 5), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
|
||||||
|
arr.push_back(1);
|
||||||
|
arr.push_back(2);
|
||||||
|
arr.push_back(3);
|
||||||
|
|
||||||
|
Array arr2;
|
||||||
|
|
||||||
|
arr2.push_back(4);
|
||||||
|
arr2.push_back(5);
|
||||||
|
arr2.push_back(6);
|
||||||
|
arr2.push_back(7);
|
||||||
|
|
||||||
|
arr2 = std::move(arr);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 3), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr2[2] == 3), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
|
||||||
|
arr.push_back(1);
|
||||||
|
arr.push_back(2);
|
||||||
|
arr.push_back(3);
|
||||||
|
|
||||||
|
Array arr2;
|
||||||
|
|
||||||
|
arr2.push_back(4);
|
||||||
|
arr2.push_back(5);
|
||||||
|
arr2.push_back(6);
|
||||||
|
arr2.push_back(7);
|
||||||
|
arr2.push_back(8);
|
||||||
|
|
||||||
|
arr = std::move(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 5), res);
|
||||||
|
ASSERT_CHECK((arr[0] == 4), res);
|
||||||
|
ASSERT_CHECK((arr[1] == 5), res);
|
||||||
|
ASSERT_CHECK((arr[2] == 6), res);
|
||||||
|
ASSERT_CHECK((arr[3] == 7), res);
|
||||||
|
ASSERT_CHECK((arr[4] == 8), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
std::cerr << "Some errors were found in test 1\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void test2()
|
||||||
|
{
|
||||||
|
using namespace DB;
|
||||||
|
|
||||||
|
static constexpr size_t initial_size = 8;
|
||||||
|
static constexpr size_t stack_threshold = 32;
|
||||||
|
using Array = PODArray<UInt64, initial_size, AllocatorWithStackMemory<Allocator<false>, stack_threshold>>;
|
||||||
|
|
||||||
|
bool res = true;
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
Array arr2;
|
||||||
|
arr.swap(arr2);
|
||||||
|
arr2.swap(arr);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
|
||||||
|
Array arr2;
|
||||||
|
|
||||||
|
arr2.push_back(1);
|
||||||
|
arr2.push_back(2);
|
||||||
|
arr2.push_back(3);
|
||||||
|
|
||||||
|
arr.swap(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 3), res);
|
||||||
|
ASSERT_CHECK((arr[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr[2] == 3), res);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 0), res);
|
||||||
|
|
||||||
|
arr.swap(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 0), res);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 3), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr2[2] == 3), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
|
||||||
|
Array arr2;
|
||||||
|
|
||||||
|
arr2.push_back(1);
|
||||||
|
arr2.push_back(2);
|
||||||
|
arr2.push_back(3);
|
||||||
|
arr2.push_back(4);
|
||||||
|
arr2.push_back(5);
|
||||||
|
|
||||||
|
arr.swap(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 5), res);
|
||||||
|
ASSERT_CHECK((arr[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr[2] == 3), res);
|
||||||
|
ASSERT_CHECK((arr[3] == 4), res);
|
||||||
|
ASSERT_CHECK((arr[4] == 5), res);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 0), res);
|
||||||
|
|
||||||
|
arr.swap(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 0), res);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 5), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr2[2] == 3), res);
|
||||||
|
ASSERT_CHECK((arr2[3] == 4), res);
|
||||||
|
ASSERT_CHECK((arr2[4] == 5), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
|
||||||
|
arr.push_back(1);
|
||||||
|
arr.push_back(2);
|
||||||
|
arr.push_back(3);
|
||||||
|
|
||||||
|
Array arr2;
|
||||||
|
|
||||||
|
arr2.push_back(4);
|
||||||
|
arr2.push_back(5);
|
||||||
|
arr2.push_back(6);
|
||||||
|
|
||||||
|
arr.swap(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 3), res);
|
||||||
|
ASSERT_CHECK((arr[0] == 4), res);
|
||||||
|
ASSERT_CHECK((arr[1] == 5), res);
|
||||||
|
ASSERT_CHECK((arr[2] == 6), res);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 3), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr2[2] == 3), res);
|
||||||
|
|
||||||
|
arr.swap(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 3), res);
|
||||||
|
ASSERT_CHECK((arr[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr[2] == 3), res);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 3), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 4), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 5), res);
|
||||||
|
ASSERT_CHECK((arr2[2] == 6), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
|
||||||
|
arr.push_back(1);
|
||||||
|
arr.push_back(2);
|
||||||
|
|
||||||
|
Array arr2;
|
||||||
|
|
||||||
|
arr2.push_back(3);
|
||||||
|
arr2.push_back(4);
|
||||||
|
arr2.push_back(5);
|
||||||
|
|
||||||
|
arr.swap(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 3), res);
|
||||||
|
ASSERT_CHECK((arr[0] == 3), res);
|
||||||
|
ASSERT_CHECK((arr[1] == 4), res);
|
||||||
|
ASSERT_CHECK((arr[2] == 5), res);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 2), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 2), res);
|
||||||
|
|
||||||
|
arr.swap(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 2), res);
|
||||||
|
ASSERT_CHECK((arr[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr[1] == 2), res);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 3), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 3), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 4), res);
|
||||||
|
ASSERT_CHECK((arr2[2] == 5), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
|
||||||
|
arr.push_back(1);
|
||||||
|
arr.push_back(2);
|
||||||
|
arr.push_back(3);
|
||||||
|
|
||||||
|
Array arr2;
|
||||||
|
|
||||||
|
arr2.push_back(4);
|
||||||
|
arr2.push_back(5);
|
||||||
|
arr2.push_back(6);
|
||||||
|
arr2.push_back(7);
|
||||||
|
arr2.push_back(8);
|
||||||
|
|
||||||
|
arr.swap(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 5), res);
|
||||||
|
ASSERT_CHECK((arr[0] == 4), res);
|
||||||
|
ASSERT_CHECK((arr[1] == 5), res);
|
||||||
|
ASSERT_CHECK((arr[2] == 6), res);
|
||||||
|
ASSERT_CHECK((arr[3] == 7), res);
|
||||||
|
ASSERT_CHECK((arr[4] == 8), res);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 3), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr2[2] == 3), res);
|
||||||
|
|
||||||
|
arr.swap(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 3), res);
|
||||||
|
ASSERT_CHECK((arr[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr[2] == 3), res);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 5), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 4), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 5), res);
|
||||||
|
ASSERT_CHECK((arr2[2] == 6), res);
|
||||||
|
ASSERT_CHECK((arr2[3] == 7), res);
|
||||||
|
ASSERT_CHECK((arr2[4] == 8), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
|
||||||
|
arr.push_back(1);
|
||||||
|
arr.push_back(2);
|
||||||
|
arr.push_back(3);
|
||||||
|
arr.push_back(4);
|
||||||
|
arr.push_back(5);
|
||||||
|
|
||||||
|
Array arr2;
|
||||||
|
|
||||||
|
arr2.push_back(6);
|
||||||
|
arr2.push_back(7);
|
||||||
|
arr2.push_back(8);
|
||||||
|
arr2.push_back(9);
|
||||||
|
arr2.push_back(10);
|
||||||
|
|
||||||
|
arr.swap(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 5), res);
|
||||||
|
ASSERT_CHECK((arr[0] == 6), res);
|
||||||
|
ASSERT_CHECK((arr[1] == 7), res);
|
||||||
|
ASSERT_CHECK((arr[2] == 8), res);
|
||||||
|
ASSERT_CHECK((arr[3] == 9), res);
|
||||||
|
ASSERT_CHECK((arr[4] == 10), res);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 5), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr2[2] == 3), res);
|
||||||
|
ASSERT_CHECK((arr2[3] == 4), res);
|
||||||
|
ASSERT_CHECK((arr2[4] == 5), res);
|
||||||
|
|
||||||
|
arr.swap(arr2);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 5), res);
|
||||||
|
ASSERT_CHECK((arr[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr[2] == 3), res);
|
||||||
|
ASSERT_CHECK((arr[3] == 4), res);
|
||||||
|
ASSERT_CHECK((arr[4] == 5), res);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 5), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 6), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 7), res);
|
||||||
|
ASSERT_CHECK((arr2[2] == 8), res);
|
||||||
|
ASSERT_CHECK((arr2[3] == 9), res);
|
||||||
|
ASSERT_CHECK((arr2[4] == 10), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
std::cerr << "Some errors were found in test 2\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void test3()
|
||||||
|
{
|
||||||
|
using namespace DB;
|
||||||
|
|
||||||
|
static constexpr size_t initial_size = 8;
|
||||||
|
static constexpr size_t stack_threshold = 32;
|
||||||
|
using Array = PODArray<UInt64, initial_size, AllocatorWithStackMemory<Allocator<false>, stack_threshold>>;
|
||||||
|
|
||||||
|
bool res = true;
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
Array arr2{std::move(arr)};
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
|
||||||
|
arr.push_back(1);
|
||||||
|
arr.push_back(2);
|
||||||
|
arr.push_back(3);
|
||||||
|
|
||||||
|
Array arr2{std::move(arr)};
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 0), res);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 3), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr2[2] == 3), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Array arr;
|
||||||
|
|
||||||
|
arr.push_back(1);
|
||||||
|
arr.push_back(2);
|
||||||
|
arr.push_back(3);
|
||||||
|
arr.push_back(4);
|
||||||
|
arr.push_back(5);
|
||||||
|
|
||||||
|
Array arr2{std::move(arr)};
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr.size() == 0), res);
|
||||||
|
|
||||||
|
ASSERT_CHECK((arr2.size() == 5), res);
|
||||||
|
ASSERT_CHECK((arr2[0] == 1), res);
|
||||||
|
ASSERT_CHECK((arr2[1] == 2), res);
|
||||||
|
ASSERT_CHECK((arr2[2] == 3), res);
|
||||||
|
ASSERT_CHECK((arr2[3] == 4), res);
|
||||||
|
ASSERT_CHECK((arr2[4] == 5), res);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
std::cerr << "Some errors were found in test 3\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
std::cout << "test 1\n";
|
||||||
|
test1();
|
||||||
|
std::cout << "test 2\n";
|
||||||
|
test2();
|
||||||
|
std::cout << "test 3\n";
|
||||||
|
test3();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user