ClickHouse/dbms/include/DB/Columns/ColumnFixedArray.h
2011-08-28 00:31:30 +00:00

123 lines
2.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef DBMS_CORE_COLUMN_FIXED_ARRAY_H
#define DBMS_CORE_COLUMN_FIXED_ARRAY_H
#include <Poco/SharedPtr.h>
#include <DB/Core/Exception.h>
#include <DB/Core/ErrorCodes.h>
#include <DB/Columns/IColumn.h>
namespace DB
{
using Poco::SharedPtr;
/** Cтолбeц значений типа "массив фиксированного размера".
*/
class ColumnFixedArray : public IColumn
{
public:
/** Создать пустой столбец массивов фиксированного размера n, со типом значений, как в столбце nested_column */
ColumnFixedArray(ColumnPtr nested_column, size_t n_)
: data(nested_column), n(n_)
{
clear();
}
std::string getName() const { return "ColumnFixedArray(" + data->getName() + ")"; }
ColumnPtr cloneEmpty() const
{
return new ColumnFixedArray(data->cloneEmpty(), n);
}
size_t size() const
{
return data->size() / n;
}
Field operator[](size_t index) const
{
Array res;
for (size_t i = n * index; i < n * (index + 1); ++i)
res[i] = (*data)[n * index + i];
return res;
}
void cut(size_t start, size_t length)
{
data->cut(n * start, n * length);
}
void insert(const Field & x)
{
const Array & array = boost::get<Array &>(x);
if (n != array.size())
throw Exception("Size of array doesn't match size of FixedArray column",
ErrorCodes::SIZE_OF_ARRAY_DOESNT_MATCH_SIZE_OF_FIXEDARRAY_COLUMN);
for (size_t i = 0; i < n; ++i)
data->insert(array[i]);
}
void insertDefault()
{
for (size_t i = 0; i < n; ++i)
data->insertDefault();
}
void clear()
{
data->clear();
}
/** Более эффективные методы манипуляции */
IColumn & getData()
{
return *data;
}
void filter(const Filter & filt)
{
size_t size = this->size();
if (size != filt.size())
throw Exception("Size of filter doesn't match size of column.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
if (size == 0)
return;
/// Не слишком оптимально. Можно сделать специализацию для массивов известных типов.
Filter nested_filt(size * n);
for (size_t i = 0; i < size; ++i)
if (filt[i])
memset(&nested_filt[i * n], 1, n);
data->filter(nested_filt);
}
size_t byteSize()
{
return data->byteSize() + sizeof(n);
}
const IColumn & getData() const
{
return *data;
}
size_t getN() const
{
return n;
}
protected:
ColumnPtr data;
const size_t n;
};
}
#endif