ClickHouse/dbms/include/DB/Core/SortDescription.h

112 lines
3.2 KiB
C
Raw Normal View History

2011-09-04 01:42:14 +00:00
#pragma once
#include <vector>
2011-09-04 05:14:52 +00:00
#include <DB/Core/Types.h>
#include <DB/Core/Block.h>
2012-07-25 19:53:43 +00:00
#include <DB/Columns/IColumn.h>
2011-09-04 05:14:52 +00:00
2011-09-04 01:42:14 +00:00
namespace DB
{
/// Описание правила сортировки по одному столбцу.
struct SortColumnDescription
{
2011-09-04 05:14:52 +00:00
String column_name; /// Имя столбца.
size_t column_number; /// Номер столбца (используется, если не задано имя).
2011-09-04 01:42:14 +00:00
int direction; /// 1 - по возрастанию, -1 - по убыванию.
SortColumnDescription(size_t column_number_, int direction_)
: column_number(column_number_), direction(direction_) {}
2011-09-04 05:14:52 +00:00
SortColumnDescription(String column_name_, int direction_)
: column_name(column_name_), column_number(0), direction(direction_) {}
2011-09-04 01:42:14 +00:00
};
/// Описание правила сортировки по нескольким столбцам.
typedef std::vector<SortColumnDescription> SortDescription;
2012-07-25 19:53:43 +00:00
/** Курсор, позволяющий сравнивать соответствующие строки в разных блоках.
* Курсор двигается по одному блоку.
2012-07-25 19:53:43 +00:00
* Для использования в priority queue.
*/
struct SortCursorImpl
2012-07-25 19:53:43 +00:00
{
ConstColumnPlainPtrs all_columns;
ConstColumnPlainPtrs sort_columns;
SortDescription desc;
2012-07-25 19:53:43 +00:00
size_t sort_columns_size;
size_t pos;
size_t rows;
2012-08-14 20:33:37 +00:00
/** Порядок (что сравнивается), если сравниваемые столбцы равны.
* Даёт возможность предпочитать строки из нужного курсора.
*/
size_t order;
SortCursorImpl() {}
2012-07-25 19:53:43 +00:00
2012-08-14 20:33:37 +00:00
SortCursorImpl(const Block & block, const SortDescription & desc_, size_t order_ = 0)
: desc(desc_), sort_columns_size(desc.size()), order(order_)
2012-07-25 19:53:43 +00:00
{
reset(block);
}
/// Установить курсор в начало нового блока.
void reset(const Block & block)
{
all_columns.clear();
sort_columns.clear();
size_t num_columns = block.columns();
for (size_t j = 0; j < num_columns; ++j)
all_columns.push_back(&*block.getByPosition(j).column);
for (size_t j = 0, size = desc.size(); j < size; ++j)
{
size_t column_number = !desc[j].column_name.empty()
? block.getPositionByName(desc[j].column_name)
: desc[j].column_number;
sort_columns.push_back(&*block.getByPosition(column_number).column);
}
pos = 0;
rows = all_columns[0]->size();
2012-07-25 19:53:43 +00:00
}
bool isLast() const { return pos + 1 >= rows; }
void next() { ++pos; }
};
/// Для лёгкости копирования.
struct SortCursor
{
SortCursorImpl * impl;
SortCursor(SortCursorImpl * impl_) : impl(impl_) {}
SortCursorImpl * operator-> () { return impl; }
const SortCursorImpl * operator-> () const { return impl; }
/// Инвертировано, чтобы из priority queue элементы вынимались в нужном порядке.
2012-07-25 19:53:43 +00:00
bool operator< (const SortCursor & rhs) const
{
for (size_t i = 0; i < impl->sort_columns_size; ++i)
2012-07-25 19:53:43 +00:00
{
int res = impl->desc[i].direction * impl->sort_columns[i]->compareAt(impl->pos, rhs.impl->pos, *(rhs.impl->sort_columns[i]));
2012-07-25 19:53:43 +00:00
if (res > 0)
return true;
if (res < 0)
return false;
}
2012-08-14 20:33:37 +00:00
return impl->order > rhs.impl->order;
2012-07-25 19:53:43 +00:00
}
};
2011-09-04 01:42:14 +00:00
}