Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
6def419e
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,发现更多精彩内容 >>
提交
6def419e
编写于
9月 13, 2013
作者:
A
Alexey Milovidov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
dbms: development [#CONV-2944].
上级
d7eb7a1c
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
123 addition
and
86 deletion
+123
-86
dbms/include/DB/DataStreams/IBlockInputStream.h
dbms/include/DB/DataStreams/IBlockInputStream.h
+1
-0
dbms/include/DB/DataStreams/IProfilingBlockInputStream.h
dbms/include/DB/DataStreams/IProfilingBlockInputStream.h
+5
-0
dbms/include/DB/DataStreams/MergingSortedBlockInputStream.h
dbms/include/DB/DataStreams/MergingSortedBlockInputStream.h
+1
-2
dbms/include/DB/DataStreams/RemoteBlockInputStream.h
dbms/include/DB/DataStreams/RemoteBlockInputStream.h
+55
-53
dbms/include/DB/DataStreams/UnionBlockInputStream.h
dbms/include/DB/DataStreams/UnionBlockInputStream.h
+44
-30
dbms/src/Client/Client.cpp
dbms/src/Client/Client.cpp
+3
-0
dbms/src/DataStreams/IProfilingBlockInputStream.cpp
dbms/src/DataStreams/IProfilingBlockInputStream.cpp
+9
-0
dbms/src/DataStreams/MergingSortedBlockInputStream.cpp
dbms/src/DataStreams/MergingSortedBlockInputStream.cpp
+1
-1
dbms/src/Server/TCPHandler.cpp
dbms/src/Server/TCPHandler.cpp
+4
-0
未找到文件。
dbms/include/DB/DataStreams/IBlockInputStream.h
浏览文件 @
6def419e
...
...
@@ -42,6 +42,7 @@ public:
virtual
Block
read
()
=
0
;
/** Прочитать что-нибудь перед началом всех данных или после конца всех данных.
* В функции readSuffix можно реализовать финализацию, которая может привести к исключению.
*/
virtual
void
readPrefix
()
{}
virtual
void
readSuffix
()
{}
...
...
dbms/include/DB/DataStreams/IProfilingBlockInputStream.h
浏览文件 @
6def419e
...
...
@@ -74,6 +74,9 @@ public:
Block
read
();
/// Реализация по-умолчанию вызывает рекурсивно readSuffix() у всех детей, а затем readSuffixImpl() у себя.
void
readSuffix
();
/// Получить информацию о скорости выполнения.
const
BlockStreamProfileInfo
&
getInfo
()
const
;
...
...
@@ -185,6 +188,8 @@ protected:
/// Наследники должны реализовать эту функцию.
virtual
Block
readImpl
()
=
0
;
/// Здесь необходимо делать финализацию, которая может привести к исключению.
virtual
void
readSuffixImpl
()
{}
void
updateExtremes
(
Block
&
block
);
bool
checkLimits
();
...
...
dbms/include/DB/DataStreams/MergingSortedBlockInputStream.h
浏览文件 @
6def419e
...
...
@@ -24,8 +24,6 @@ public:
children
.
insert
(
children
.
end
(),
inputs_
.
begin
(),
inputs_
.
end
());
}
void
readSuffix
();
String
getName
()
const
{
return
"MergingSortedBlockInputStream"
;
}
String
getID
()
const
...
...
@@ -52,6 +50,7 @@ public:
protected:
Block
readImpl
();
void
readSuffixImpl
();
/// Инициализирует очередь и следующий блок результата.
void
init
(
Block
&
merged_block
,
ColumnPlainPtrs
&
merged_columns
);
...
...
dbms/include/DB/DataStreams/RemoteBlockInputStream.h
浏览文件 @
6def419e
...
...
@@ -82,62 +82,10 @@ public:
~
RemoteBlockInputStream
()
{
bool
uncaught_exception
=
std
::
uncaught_exception
();
/** В случае эксепшена, закрываем соединение, чтобы оно не осталось висеть в рассихронизированном состоянии.
*/
if
(
uncaught_exception
)
if
(
std
::
uncaught_exception
()
)
connection
.
disconnect
();
/** Если одно из:
* - ничего не начинали делать;
* - получили все пакеты до EndOfStream;
* - получили с сервера эксепшен;
* - объект уничтожается из-за эксепшена;
* - то больше читать ничего не нужно.
*/
if
(
!
sent_query
||
finished
||
got_exception_from_server
||
uncaught_exception
)
return
;
/** Если ещё прочитали не все данные, но они больше не нужны.
* Это может быть из-за того, что данных достаточно (например, при использовании LIMIT).
*/
/// Отправим просьбу прервать выполнение запроса, если ещё не отправляли.
if
(
!
was_cancelled
)
{
LOG_TRACE
(
log
,
"Cancelling query because enough data has been read"
);
was_cancelled
=
true
;
connection
.
sendCancel
();
}
/// Получим оставшиеся пакеты, чтобы не было рассинхронизации в соединении с сервером.
while
(
true
)
{
Connection
::
Packet
packet
=
connection
.
receivePacket
();
switch
(
packet
.
type
)
{
case
Protocol
::
Server
::
Data
:
case
Protocol
::
Server
::
Progress
:
case
Protocol
::
Server
::
ProfileInfo
:
case
Protocol
::
Server
::
Totals
:
case
Protocol
::
Server
::
Extremes
:
break
;
case
Protocol
::
Server
::
EndOfStream
:
return
;
case
Protocol
::
Server
::
Exception
:
got_exception_from_server
=
true
;
packet
.
exception
->
rethrow
();
break
;
default:
throw
Exception
(
"Unknown packet from server"
,
ErrorCodes
::
UNKNOWN_PACKET_FROM_SERVER
);
}
}
}
protected:
...
...
@@ -197,6 +145,60 @@ protected:
}
}
void
readSuffixImpl
()
{
/** Если одно из:
* - ничего не начинали делать;
* - получили все пакеты до EndOfStream;
* - получили с сервера эксепшен;
* - то больше читать ничего не нужно.
*/
if
(
!
sent_query
||
finished
||
got_exception_from_server
)
return
;
finished
=
true
;
/** Если ещё прочитали не все данные, но они больше не нужны.
* Это может быть из-за того, что данных достаточно (например, при использовании LIMIT).
*/
/// Отправим просьбу прервать выполнение запроса, если ещё не отправляли.
if
(
!
was_cancelled
)
{
LOG_TRACE
(
log
,
"Cancelling query because enough data has been read"
);
was_cancelled
=
true
;
connection
.
sendCancel
();
}
/// Получим оставшиеся пакеты, чтобы не было рассинхронизации в соединении с сервером.
while
(
true
)
{
Connection
::
Packet
packet
=
connection
.
receivePacket
();
switch
(
packet
.
type
)
{
case
Protocol
::
Server
::
Data
:
case
Protocol
::
Server
::
Progress
:
case
Protocol
::
Server
::
ProfileInfo
:
case
Protocol
::
Server
::
Totals
:
case
Protocol
::
Server
::
Extremes
:
break
;
case
Protocol
::
Server
::
EndOfStream
:
return
;
case
Protocol
::
Server
::
Exception
:
got_exception_from_server
=
true
;
packet
.
exception
->
rethrow
();
break
;
default:
throw
Exception
(
"Unknown packet from server"
,
ErrorCodes
::
UNKNOWN_PACKET_FROM_SERVER
);
}
}
}
private:
/// Используется, если нужно владеть соединением из пула
ConnectionPool
::
Entry
pool_entry
;
...
...
dbms/include/DB/DataStreams/UnionBlockInputStream.h
浏览文件 @
6def419e
...
...
@@ -37,7 +37,7 @@ class UnionBlockInputStream : public IProfilingBlockInputStream
public:
UnionBlockInputStream
(
BlockInputStreams
inputs_
,
unsigned
max_threads_
=
1
)
:
max_threads
(
std
::
min
(
inputs_
.
size
(),
static_cast
<
size_t
>
(
max_threads_
))),
output_queue
(
max_threads
),
exhausted_inputs
(
0
),
finish
(
false
),
all_read
(
false
),
output_queue
(
max_threads
),
exhausted_inputs
(
0
),
finish
(
false
),
all_read
(
false
),
finalized
(
false
),
log
(
&
Logger
::
get
(
"UnionBlockInputStream"
))
{
children
.
insert
(
children
.
end
(),
inputs_
.
begin
(),
inputs_
.
end
());
...
...
@@ -71,37 +71,10 @@ public:
return
res
.
str
();
}
~
UnionBlockInputStream
()
{
LOG_TRACE
(
log
,
"Waiting for threads to finish"
);
finish
=
true
;
cancel
();
ExceptionPtr
exception
;
/// Вынем всё, что есть в очереди готовых данных.
OutputData
res
;
while
(
output_queue
.
tryPop
(
res
))
if
(
res
.
exception
&&
!
exception
)
exception
=
res
.
exception
;
/** В этот момент, запоздавшие потоки ещё могут вставить в очередь какие-нибудь блоки, но очередь не переполнится.
* PS. Может быть, для переменной finish нужен барьер?
*/
for
(
ThreadsData
::
iterator
it
=
threads_data
.
begin
();
it
!=
threads_data
.
end
();
++
it
)
it
->
thread
->
join
();
/// Может быть, нам под конец положили эксепшен.
while
(
output_queue
.
tryPop
(
res
))
if
(
res
.
exception
&&
!
exception
)
exception
=
res
.
exception
;
if
(
exception
&&
!
std
::
uncaught_exception
())
exception
->
rethrow
();
LOG_TRACE
(
log
,
"Waited for threads to finish"
);
readSuffixImpl
();
}
/** Отличается от реализации по-умолчанию тем, что пытается остановить все источники,
...
...
@@ -179,6 +152,44 @@ protected:
return
res
.
block
;
}
void
readSuffixImpl
()
{
if
(
finalized
)
return
;
finalized
=
true
;
LOG_TRACE
(
log
,
"Waiting for threads to finish"
);
finish
=
true
;
cancel
();
ExceptionPtr
exception
;
/// Вынем всё, что есть в очереди готовых данных.
OutputData
res
;
while
(
output_queue
.
tryPop
(
res
))
if
(
res
.
exception
&&
!
exception
)
exception
=
res
.
exception
;
/** В этот момент, запоздавшие потоки ещё могут вставить в очередь какие-нибудь блоки, но очередь не переполнится.
* PS. Может быть, для переменной finish нужен барьер?
*/
for
(
ThreadsData
::
iterator
it
=
threads_data
.
begin
();
it
!=
threads_data
.
end
();
++
it
)
it
->
thread
->
join
();
/// Может быть, нам под конец положили эксепшен.
while
(
output_queue
.
tryPop
(
res
))
if
(
res
.
exception
&&
!
exception
)
exception
=
res
.
exception
;
if
(
exception
&&
!
std
::
uncaught_exception
())
exception
->
rethrow
();
LOG_TRACE
(
log
,
"Waited for threads to finish"
);
}
private:
/// Данные отдельного источника
struct
InputData
...
...
@@ -338,6 +349,9 @@ private:
volatile
bool
finish
;
bool
all_read
;
/// Была вызвана функция readSuffixImpl.
bool
finalized
;
Logger
*
log
;
};
...
...
dbms/src/Client/Client.cpp
浏览文件 @
6def419e
...
...
@@ -823,6 +823,9 @@ private:
void
onEndOfStream
()
{
if
(
block_std_in
)
block_std_in
->
readSuffix
();
if
(
block_std_out
)
block_std_out
->
writeSuffix
();
...
...
dbms/src/DataStreams/IProfilingBlockInputStream.cpp
浏览文件 @
6def419e
...
...
@@ -204,6 +204,15 @@ Block IProfilingBlockInputStream::read()
}
void
IProfilingBlockInputStream
::
readSuffix
()
{
for
(
BlockInputStreams
::
iterator
it
=
children
.
begin
();
it
!=
children
.
end
();
++
it
)
(
*
it
)
->
readSuffix
();
readSuffixImpl
();
}
void
IProfilingBlockInputStream
::
updateExtremes
(
Block
&
block
)
{
size_t
columns
=
block
.
columns
();
...
...
dbms/src/DataStreams/MergingSortedBlockInputStream.cpp
浏览文件 @
6def419e
...
...
@@ -171,7 +171,7 @@ void MergingSortedBlockInputStream::fetchNextBlock(const TSortCursor & current,
}
void
MergingSortedBlockInputStream
::
readSuffix
()
void
MergingSortedBlockInputStream
::
readSuffix
Impl
()
{
const
BlockStreamProfileInfo
&
profile_info
=
getInfo
();
double
seconds
=
profile_info
.
work_stopwatch
.
elapsedSeconds
();
...
...
dbms/src/Server/TCPHandler.cpp
浏览文件 @
6def419e
...
...
@@ -213,6 +213,8 @@ void TCPHandler::processOrdinaryQuery()
/// Отправим блок-заголовок, чтобы клиент мог подготовить формат вывода
if
(
state
.
io
.
in_sample
&&
client_revision
>=
DBMS_MIN_REVISION_WITH_HEADER_BLOCK
)
sendData
(
state
.
io
.
in_sample
);
state
.
io
.
in
->
readPrefix
();
AsynchronousBlockInputStream
async_in
(
state
.
io
.
in
);
...
...
@@ -254,6 +256,8 @@ void TCPHandler::processOrdinaryQuery()
break
;
}
state
.
io
.
in
->
readSuffix
();
watch
.
stop
();
logProfileInfo
(
watch
,
*
state
.
io
.
in
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录