2010-03-12 20:44:25 +00:00
|
|
|
#include <iterator>
|
|
|
|
|
2010-03-04 19:20:28 +00:00
|
|
|
#include <DB/Core/Exception.h>
|
|
|
|
#include <DB/Core/ErrorCodes.h>
|
|
|
|
|
2010-03-01 16:59:51 +00:00
|
|
|
#include <DB/Core/Block.h>
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2010-03-12 20:44:25 +00:00
|
|
|
|
|
|
|
Block::Block(const Block & other)
|
|
|
|
{
|
|
|
|
*this = other;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Block & Block::operator= (const Block & other)
|
|
|
|
{
|
|
|
|
data = other.data;
|
|
|
|
rebuildIndexByPosition();
|
|
|
|
|
|
|
|
for (IndexByName_t::const_iterator it = other.index_by_name.begin(); it != other.index_by_name.end(); ++it)
|
|
|
|
{
|
|
|
|
Container_t::iterator value = data.begin();
|
|
|
|
std::advance(value, std::distance(const_cast<Block&>(other).data.begin(), it->second));
|
|
|
|
index_by_name[it->first] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-01 16:59:51 +00:00
|
|
|
void Block::rebuildIndexByPosition()
|
|
|
|
{
|
2010-03-04 19:20:28 +00:00
|
|
|
index_by_position.resize(data.size());
|
2010-03-01 16:59:51 +00:00
|
|
|
size_t pos = 0;
|
2010-03-04 19:20:28 +00:00
|
|
|
for (Container_t::iterator it = data.begin(); it != data.end(); ++it, ++pos)
|
2010-03-01 16:59:51 +00:00
|
|
|
index_by_position[pos] = it;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Block::insert(size_t position, const ColumnWithNameAndType & elem)
|
|
|
|
{
|
2010-03-05 15:29:17 +00:00
|
|
|
if (position >= index_by_position.size())
|
|
|
|
throw Exception("Position out of bound in Block::insert()", ErrorCodes::POSITION_OUT_OF_BOUND);
|
|
|
|
|
2010-03-04 19:20:28 +00:00
|
|
|
Container_t::iterator it = data.insert(index_by_position[position], elem);
|
2010-03-01 16:59:51 +00:00
|
|
|
rebuildIndexByPosition();
|
|
|
|
index_by_name[elem.name] = it;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-05 15:29:17 +00:00
|
|
|
void Block::insert(const ColumnWithNameAndType & elem)
|
|
|
|
{
|
|
|
|
Container_t::iterator it = data.insert(data.end(), elem);
|
|
|
|
rebuildIndexByPosition();
|
|
|
|
index_by_name[elem.name] = it;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-01 16:59:51 +00:00
|
|
|
void Block::erase(size_t position)
|
|
|
|
{
|
2010-03-05 15:29:17 +00:00
|
|
|
if (position >= index_by_position.size())
|
|
|
|
throw Exception("Position out of bound in Block::erase()", ErrorCodes::POSITION_OUT_OF_BOUND);
|
|
|
|
|
2010-03-01 16:59:51 +00:00
|
|
|
Container_t::iterator it = index_by_position[position];
|
|
|
|
index_by_name.erase(index_by_name.find(it->name));
|
2010-03-04 19:20:28 +00:00
|
|
|
data.erase(it);
|
2010-03-01 16:59:51 +00:00
|
|
|
rebuildIndexByPosition();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-04 19:20:28 +00:00
|
|
|
ColumnWithNameAndType & Block::getByPosition(size_t position)
|
2010-03-01 16:59:51 +00:00
|
|
|
{
|
|
|
|
return *index_by_position[position];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-04 19:20:28 +00:00
|
|
|
const ColumnWithNameAndType & Block::getByPosition(size_t position) const
|
2010-03-01 16:59:51 +00:00
|
|
|
{
|
|
|
|
return *index_by_position[position];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-04 19:20:28 +00:00
|
|
|
ColumnWithNameAndType & Block::getByName(const std::string & name)
|
2010-03-01 16:59:51 +00:00
|
|
|
{
|
|
|
|
return *index_by_name[name];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-04 19:20:28 +00:00
|
|
|
const ColumnWithNameAndType & Block::getByName(const std::string & name) const
|
2010-03-01 16:59:51 +00:00
|
|
|
{
|
2010-03-04 19:20:28 +00:00
|
|
|
IndexByName_t::const_iterator it = index_by_name.find(name);
|
|
|
|
if (index_by_name.end() == it)
|
|
|
|
throw Exception("Not found column " + name + " in block.", ErrorCodes::NOT_FOUND_COLUMN_IN_BLOCK);
|
|
|
|
|
|
|
|
return *it->second;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t Block::rows() const
|
|
|
|
{
|
|
|
|
size_t res = 0;
|
|
|
|
for (Container_t::const_iterator it = data.begin(); it != data.end(); ++it)
|
|
|
|
{
|
2010-03-12 18:25:35 +00:00
|
|
|
size_t size = it->column->size();
|
2010-03-04 19:20:28 +00:00
|
|
|
|
|
|
|
if (size == 0)
|
|
|
|
throw Exception("Empty column in block.", ErrorCodes::EMPTY_COLUMN_IN_BLOCK);
|
|
|
|
|
|
|
|
if (size != 1 && res != 0 && size != res)
|
|
|
|
throw Exception("Sizes of columns doesn't match.", ErrorCodes::SIZES_OF_COLUMNS_DOESNT_MATCH);
|
|
|
|
|
|
|
|
res = size;
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
2010-03-01 16:59:51 +00:00
|
|
|
}
|
|
|
|
|
2010-03-04 19:20:28 +00:00
|
|
|
|
|
|
|
size_t Block::columns() const
|
|
|
|
{
|
|
|
|
return data.size();
|
2010-03-01 16:59:51 +00:00
|
|
|
}
|
|
|
|
|
2010-03-04 19:20:28 +00:00
|
|
|
}
|