2016-12-12 05:14:46 +00:00
|
|
|
|
#include <common/ClickHouseRevision.h>
|
|
|
|
|
|
2015-12-01 14:43:51 +00:00
|
|
|
|
#include <DB/DataStreams/BlocksListBlockInputStream.h>
|
|
|
|
|
#include <DB/DataStreams/MergingAggregatedMemoryEfficientBlockInputStream.h>
|
2011-09-19 03:34:23 +00:00
|
|
|
|
#include <DB/DataStreams/AggregatingBlockInputStream.h>
|
2016-12-12 05:14:46 +00:00
|
|
|
|
#include <DB/DataStreams/NativeBlockInputStream.h>
|
2011-09-19 03:34:23 +00:00
|
|
|
|
|
|
|
|
|
|
2016-10-24 02:02:37 +00:00
|
|
|
|
namespace ProfileEvents
|
|
|
|
|
{
|
|
|
|
|
extern const Event ExternalAggregationMerge;
|
|
|
|
|
}
|
|
|
|
|
|
2011-09-19 03:34:23 +00:00
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Block AggregatingBlockInputStream::readImpl()
|
|
|
|
|
{
|
2015-01-02 03:16:28 +00:00
|
|
|
|
if (!executed)
|
|
|
|
|
{
|
|
|
|
|
executed = true;
|
2016-05-28 14:14:18 +00:00
|
|
|
|
AggregatedDataVariantsPtr data_variants = std::make_shared<AggregatedDataVariants>();
|
2015-04-16 14:27:56 +00:00
|
|
|
|
|
|
|
|
|
Aggregator::CancellationHook hook = [&]() { return this->isCancelled(); };
|
|
|
|
|
aggregator.setCancellationHook(hook);
|
|
|
|
|
|
2015-12-09 02:55:35 +00:00
|
|
|
|
aggregator.execute(children.back(), *data_variants);
|
2015-12-01 14:43:51 +00:00
|
|
|
|
|
|
|
|
|
if (!aggregator.hasTemporaryFiles())
|
|
|
|
|
{
|
2015-12-09 02:55:35 +00:00
|
|
|
|
ManyAggregatedDataVariants many_data { data_variants };
|
|
|
|
|
impl = aggregator.mergeAndConvertToBlocks(many_data, final, 1);
|
2015-12-01 14:43:51 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/** Если есть временные файлы с частично-агрегированными данными на диске,
|
|
|
|
|
* то читаем и мерджим их, расходуя минимальное количество памяти.
|
|
|
|
|
*/
|
|
|
|
|
|
2015-12-03 21:23:21 +00:00
|
|
|
|
ProfileEvents::increment(ProfileEvents::ExternalAggregationMerge);
|
|
|
|
|
|
2015-12-06 15:29:16 +00:00
|
|
|
|
if (!isCancelled())
|
|
|
|
|
{
|
|
|
|
|
/// Сбросим имеющиеся в оперативке данные тоже на диск. Так проще.
|
2015-12-09 02:55:35 +00:00
|
|
|
|
size_t rows = data_variants->sizeWithoutOverflowRow();
|
2015-12-06 15:29:16 +00:00
|
|
|
|
if (rows)
|
2015-12-09 02:55:35 +00:00
|
|
|
|
aggregator.writeToTemporaryFile(*data_variants, rows);
|
2015-12-06 15:29:16 +00:00
|
|
|
|
}
|
2015-12-01 14:43:51 +00:00
|
|
|
|
|
|
|
|
|
const auto & files = aggregator.getTemporaryFiles();
|
|
|
|
|
BlockInputStreams input_streams;
|
2015-12-01 16:58:15 +00:00
|
|
|
|
for (const auto & file : files.files)
|
2015-12-01 14:43:51 +00:00
|
|
|
|
{
|
2016-05-28 12:22:22 +00:00
|
|
|
|
temporary_inputs.emplace_back(std::make_unique<TemporaryFileStream>(file->path()));
|
2015-12-01 14:43:51 +00:00
|
|
|
|
input_streams.emplace_back(temporary_inputs.back()->block_in);
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-01 16:58:15 +00:00
|
|
|
|
LOG_TRACE(log, "Will merge " << files.files.size() << " temporary files of size "
|
|
|
|
|
<< (files.sum_size_compressed / 1048576.0) << " MiB compressed, "
|
|
|
|
|
<< (files.sum_size_uncompressed / 1048576.0) << " MiB uncompressed.");
|
|
|
|
|
|
2016-05-28 12:22:22 +00:00
|
|
|
|
impl = std::make_unique<MergingAggregatedMemoryEfficientBlockInputStream>(input_streams, params, final, 1, 1);
|
2015-12-01 14:43:51 +00:00
|
|
|
|
}
|
2015-01-02 03:16:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Block res;
|
2015-12-01 14:43:51 +00:00
|
|
|
|
if (isCancelled() || !impl)
|
2015-01-02 03:16:28 +00:00
|
|
|
|
return res;
|
|
|
|
|
|
2015-12-01 14:43:51 +00:00
|
|
|
|
return impl->read();
|
2011-09-19 03:34:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2016-12-12 05:14:46 +00:00
|
|
|
|
AggregatingBlockInputStream::TemporaryFileStream::TemporaryFileStream(const std::string & path)
|
|
|
|
|
: file_in(path), compressed_in(file_in), block_in(std::make_shared<NativeBlockInputStream>(compressed_in, ClickHouseRevision::get())) {}
|
|
|
|
|
|
|
|
|
|
|
2011-09-19 03:34:23 +00:00
|
|
|
|
}
|