dbms: improved performance: less copying when reading fixed-size columns [#CONV-2944].

This commit is contained in:
Alexey Milovidov 2013-09-07 03:28:20 +00:00
parent c69f353a17
commit e8d5603a49
3 changed files with 41 additions and 2 deletions

View File

@ -55,7 +55,7 @@ public:
{ {
typename ColumnType::Container_t & x = dynamic_cast<ColumnType &>(column).getData(); typename ColumnType::Container_t & x = dynamic_cast<ColumnType &>(column).getData();
x.resize(limit); x.resize(limit);
size_t size = istr.read(reinterpret_cast<char*>(&x[0]), sizeof(typename ColumnType::value_type) * limit); size_t size = istr.readBig(reinterpret_cast<char*>(&x[0]), sizeof(typename ColumnType::value_type) * limit);
x.resize(size / sizeof(typename ColumnType::value_type)); x.resize(size / sizeof(typename ColumnType::value_type));
} }

View File

@ -103,6 +103,45 @@ public:
return bytes_copied; return bytes_copied;
} }
/** Отличается от предыдущего метода тем, что делает меньше копирований:
* - если в текущем буфере есть данные, то копируем их;
* - если нужны ещё данные, то используем в качестве буфера для чтения to - то есть, читаем сразу куда сказали.
*/
size_t readBig(char * to, size_t n)
{
size_t bytes_copied = 0;
/// Копируем то, что есть в буфере (уже было считано раньше).
if (pos != working_buffer.end())
{
size_t bytes_to_copy = std::min(static_cast<size_t>(working_buffer.end() - pos), n);
std::memcpy(to, pos, bytes_to_copy);
pos += bytes_to_copy;
bytes_copied += bytes_to_copy;
}
/// Запоминаем старый буфер для чтения.
Buffer old_buffer = internal_buffer;
/// Если не хватило.
while (bytes_copied < n)
{
/// Выставляем в качестве буфера для чтения кусок памяти, куда нужно положить результат.
set(to + bytes_copied, n - bytes_copied);
/// Эта штука читает данные
if (!next())
break;
bytes_copied += working_buffer.size();
}
/// Выставляем обратно старый буфер.
set(old_buffer.begin(), old_buffer.size());
return bytes_copied;
}
/** Читает n байт, если есть меньше - кидает исключение. */ /** Читает n байт, если есть меньше - кидает исключение. */
void readStrict(char * to, size_t n) void readStrict(char * to, size_t n)
{ {

View File

@ -55,7 +55,7 @@ void DataTypeFixedString::deserializeBinary(IColumn & column, ReadBuffer & istr,
size_t max_bytes = limit * n; size_t max_bytes = limit * n;
data.resize(max_bytes); data.resize(max_bytes);
size_t read_bytes = istr.read(reinterpret_cast<char *>(&data[0]), max_bytes); size_t read_bytes = istr.readBig(reinterpret_cast<char *>(&data[0]), max_bytes);
if (read_bytes % n != 0) if (read_bytes % n != 0)
throw Exception("Cannot read all data of type FixedString", throw Exception("Cannot read all data of type FixedString",