mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
commit
e4c62935c3
@ -8,6 +8,7 @@
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <DB/Parsers/ExpressionElementParsers.h>
|
||||
#include <DB/Parsers/ASTLiteral.h>
|
||||
#include <DB/Common/PODArray.h>
|
||||
#include <bitset>
|
||||
#include <stack>
|
||||
|
||||
@ -44,7 +45,8 @@ struct AggregateFunctionSequenceMatchData final
|
||||
using Comparator = ComparePairFirst<std::less>;
|
||||
|
||||
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)
|
||||
{
|
||||
@ -60,7 +62,7 @@ struct AggregateFunctionSequenceMatchData final
|
||||
{
|
||||
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
|
||||
if (!sorted && !other.sorted)
|
||||
@ -111,7 +113,7 @@ struct AggregateFunctionSequenceMatchData final
|
||||
std::size_t size;
|
||||
readBinary(size, buf);
|
||||
|
||||
decltype(eventsList) eventsList;
|
||||
eventsList.clear();
|
||||
eventsList.reserve(size);
|
||||
|
||||
for (std::size_t i = 0; i < size; ++i)
|
||||
@ -124,8 +126,6 @@ struct AggregateFunctionSequenceMatchData final
|
||||
|
||||
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} {}
|
||||
};
|
||||
|
||||
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()
|
||||
{
|
||||
PatternActions actions{
|
||||
{ PatternActionType::KleeneStar }
|
||||
};
|
||||
actions.clear();
|
||||
actions.emplace_back(PatternActionType::KleeneStar);
|
||||
|
||||
ParserString special_open_p("(?");
|
||||
ParserString special_close_p(")");
|
||||
@ -354,8 +354,6 @@ private:
|
||||
else
|
||||
throw_exception("Could not parse pattern, unexpected starting symbol");
|
||||
}
|
||||
|
||||
this->actions = std::move(actions);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -164,6 +164,12 @@ public:
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
protected:
|
||||
static constexpr size_t getStackThreshold()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -209,6 +215,12 @@ public:
|
||||
memcpy(new_buf, buf, old_size);
|
||||
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;
|
||||
}
|
||||
|
||||
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:
|
||||
using value_type = T;
|
||||
|
||||
@ -130,55 +141,46 @@ public:
|
||||
|
||||
PODArray() {}
|
||||
|
||||
PODArray(size_t n)
|
||||
PODArray(size_t n)
|
||||
{
|
||||
alloc_for_num_elements(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);
|
||||
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);
|
||||
insert(from_begin, from_end);
|
||||
}
|
||||
|
||||
~PODArray()
|
||||
~PODArray()
|
||||
{
|
||||
dealloc();
|
||||
}
|
||||
|
||||
PODArray(PODArray && other)
|
||||
{
|
||||
c_start = other.c_start;
|
||||
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;
|
||||
this->swap(other);
|
||||
}
|
||||
|
||||
PODArray & operator=(PODArray && other)
|
||||
{
|
||||
std::swap(c_start, other.c_start);
|
||||
std::swap(c_end, other.c_end);
|
||||
std::swap(c_end_of_storage, other.c_end_of_storage);
|
||||
|
||||
this->swap(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T * data() { return t_start(); }
|
||||
const T * data() const { return t_start(); }
|
||||
|
||||
size_t size() 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 size() 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(); }
|
||||
|
||||
T & operator[] (size_t n) { return t_start()[n]; }
|
||||
const T & operator[] (size_t n) const { return t_start()[n]; }
|
||||
@ -310,9 +312,107 @@ public:
|
||||
|
||||
void swap(PODArray & rhs)
|
||||
{
|
||||
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);
|
||||
/// Swap two PODArray objects, arr1 and arr2, that satisfy the following conditions:
|
||||
/// - The elements of arr1 are stored on stack.
|
||||
/// - 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)
|
||||
@ -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-регистр по адресу последнего элемента. */
|
||||
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)
|
||||
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