mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-22 01:30:51 +00:00
dbms: improved performance: less copying when reading fixed-size columns [#CONV-2944].
This commit is contained in:
parent
c69f353a17
commit
e8d5603a49
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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",
|
||||||
|
Loading…
Reference in New Issue
Block a user