ClickHouse/dbms/include/DB/Interpreters/Aggregator.h

104 lines
3.4 KiB
C
Raw Normal View History

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
};
}