Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
e4c62935
C
ClickHouse
项目概览
2dot5
/
ClickHouse
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
ClickHouse
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
e4c62935
编写于
7月 10, 2016
作者:
A
alexey-milovidov
提交者:
GitHub
7月 10, 2016
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #49 from yandex/METR-18844
Metr 18844
上级
ff558b9a
a2e3c88d
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
605 addition
and
32 deletion
+605
-32
dbms/include/DB/AggregateFunctions/AggregateFunctionSequenceMatch.h
...de/DB/AggregateFunctions/AggregateFunctionSequenceMatch.h
+9
-11
dbms/include/DB/Common/Allocator.h
dbms/include/DB/Common/Allocator.h
+12
-0
dbms/include/DB/Common/PODArray.h
dbms/include/DB/Common/PODArray.h
+126
-21
dbms/src/Common/tests/CMakeLists.txt
dbms/src/Common/tests/CMakeLists.txt
+3
-0
dbms/src/Common/tests/pod_array.cpp
dbms/src/Common/tests/pod_array.cpp
+455
-0
未找到文件。
dbms/include/DB/AggregateFunctions/AggregateFunctionSequenceMatch.h
浏览文件 @
e4c62935
...
...
@@ -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:
...
...
dbms/include/DB/Common/Allocator.h
浏览文件 @
e4c62935
...
...
@@ -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
;
}
};
...
...
dbms/include/DB/Common/PODArray.h
浏览文件 @
e4c62935
...
...
@@ -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
>
>
...
...
dbms/src/Common/tests/CMakeLists.txt
浏览文件 @
e4c62935
...
...
@@ -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
)
\ No newline at end of file
dbms/src/Common/tests/pod_array.cpp
0 → 100644
浏览文件 @
e4c62935
#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
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录