2011-09-19 01:42:16 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
2011-09-26 15:45:31 +00:00
|
|
|
|
#include <city.h>
|
|
|
|
|
|
2011-09-26 07:25:22 +00:00
|
|
|
|
#include <map>
|
|
|
|
|
#include <tr1/unordered_map>
|
|
|
|
|
|
2011-09-19 01:42:16 +00:00
|
|
|
|
#include <DB/Core/ColumnNumbers.h>
|
2011-09-24 20:32:41 +00:00
|
|
|
|
#include <DB/Core/Names.h>
|
2011-09-19 01:42:16 +00:00
|
|
|
|
#include <DB/DataStreams/IBlockInputStream.h>
|
|
|
|
|
#include <DB/AggregateFunctions/IAggregateFunction.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct AggregateDescription
|
|
|
|
|
{
|
|
|
|
|
AggregateFunctionPtr function;
|
|
|
|
|
ColumnNumbers arguments;
|
2011-09-24 20:32:41 +00:00
|
|
|
|
Names argument_names; /// Используются, если arguments не заданы.
|
2011-09-25 03:37:09 +00:00
|
|
|
|
String column_name; /// Какое имя использовать для столбца со значениями агрегатной функции
|
2011-09-19 01:42:16 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef std::vector<AggregateDescription> AggregateDescriptions;
|
|
|
|
|
|
2011-09-26 07:25:22 +00:00
|
|
|
|
|
|
|
|
|
/// Для агрегации по md5.
|
|
|
|
|
struct UInt128
|
|
|
|
|
{
|
|
|
|
|
UInt64 first;
|
|
|
|
|
UInt64 second;
|
|
|
|
|
|
|
|
|
|
bool operator== (const UInt128 rhs) const { return first == rhs.first && second == rhs.second; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct UInt128Hash
|
|
|
|
|
{
|
2011-09-26 13:16:11 +00:00
|
|
|
|
size_t operator()(UInt128 x) const { return x.first ^ x.second; }
|
2011-09-26 07:25:22 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2011-09-26 15:45:31 +00:00
|
|
|
|
/// Немного быстрее стандартного
|
|
|
|
|
struct StringHash
|
|
|
|
|
{
|
|
|
|
|
size_t operator()(const String & x) const { return CityHash64(x.data(), x.size()); }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2011-09-26 07:25:22 +00:00
|
|
|
|
/// Разные структуры данных, которые могут использоваться для агрегации
|
2011-09-19 01:42:16 +00:00
|
|
|
|
typedef std::map<Row, AggregateFunctions> AggregatedData;
|
2011-09-26 07:25:22 +00:00
|
|
|
|
typedef AggregateFunctions AggregatedDataWithoutKey;
|
|
|
|
|
typedef std::tr1::unordered_map<UInt64, AggregateFunctions> AggregatedDataWithUInt64Key;
|
2011-09-26 15:45:31 +00:00
|
|
|
|
typedef std::tr1::unordered_map<String, AggregateFunctions, StringHash> AggregatedDataWithStringKey;
|
2011-09-26 07:25:22 +00:00
|
|
|
|
typedef std::tr1::unordered_map<UInt128, std::pair<Row, AggregateFunctions>, UInt128Hash> AggregatedDataHashed;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct AggregatedDataVariants
|
|
|
|
|
{
|
2011-09-26 15:45:31 +00:00
|
|
|
|
/// Наиболее общий вариант. Самый медленный. На данный момент, не используется.
|
2011-09-26 07:25:22 +00:00
|
|
|
|
AggregatedData generic;
|
2011-09-26 15:45:31 +00:00
|
|
|
|
|
|
|
|
|
/// Специализация для случая, когда ключи отсутствуют.
|
2011-09-26 07:25:22 +00:00
|
|
|
|
AggregatedDataWithoutKey without_key;
|
2011-09-26 15:45:31 +00:00
|
|
|
|
|
|
|
|
|
/// Специализация для случая, когда есть один числовой ключ (не с плавающей запятой).
|
2011-09-26 07:25:22 +00:00
|
|
|
|
AggregatedDataWithUInt64Key key64;
|
2011-09-26 15:45:31 +00:00
|
|
|
|
|
|
|
|
|
/// Специализация для случая, когда есть один строковый ключ.
|
2011-09-26 15:22:25 +00:00
|
|
|
|
AggregatedDataWithStringKey key_string;
|
2011-09-26 15:45:31 +00:00
|
|
|
|
|
|
|
|
|
/** Агрегирует по 128 битному хэшу от ключа.
|
|
|
|
|
* Если все ключи фиксированной длины, влезающие целиком в 128 бит, то укладывает их без изменений в 128 бит.
|
|
|
|
|
* Иначе - вычисляет md5 от набора из всех ключей.
|
|
|
|
|
*/
|
2011-09-26 07:25:22 +00:00
|
|
|
|
AggregatedDataHashed hashed;
|
|
|
|
|
};
|
|
|
|
|
|
2011-09-19 01:42:16 +00:00
|
|
|
|
|
|
|
|
|
/** Агрегирует поток блоков.
|
|
|
|
|
*/
|
2011-09-19 03:34:23 +00:00
|
|
|
|
class Aggregator
|
2011-09-19 01:42:16 +00:00
|
|
|
|
{
|
|
|
|
|
public:
|
2011-09-19 03:34:23 +00:00
|
|
|
|
Aggregator(const ColumnNumbers & keys_, AggregateDescriptions & aggregates_) : keys(keys_), aggregates(aggregates_) {};
|
2011-09-24 20:32:41 +00:00
|
|
|
|
Aggregator(const Names & key_names_, AggregateDescriptions & aggregates_) : key_names(key_names_), aggregates(aggregates_) {};
|
2011-09-19 01:42:16 +00:00
|
|
|
|
|
2011-09-26 07:25:22 +00:00
|
|
|
|
void execute(BlockInputStreamPtr stream, AggregatedDataVariants & result);
|
2011-09-19 01:42:16 +00:00
|
|
|
|
|
2011-09-19 03:34:23 +00:00
|
|
|
|
/// Получить пример блока, описывающего результат. Следует вызывать только после execute.
|
|
|
|
|
Block getSampleBlock() { return sample; }
|
|
|
|
|
|
2011-09-19 01:42:16 +00:00
|
|
|
|
private:
|
|
|
|
|
ColumnNumbers keys;
|
2011-09-24 20:32:41 +00:00
|
|
|
|
Names key_names;
|
2011-09-19 01:42:16 +00:00
|
|
|
|
AggregateDescriptions aggregates;
|
2011-09-19 03:34:23 +00:00
|
|
|
|
|
|
|
|
|
Block sample;
|
2011-09-19 01:42:16 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|