dbms: development.

This commit is contained in:
Alexey Milovidov 2010-03-03 19:48:02 +00:00
parent 110cf04c2f
commit b39fe534ac
11 changed files with 242 additions and 167 deletions

View File

@ -1,61 +0,0 @@
#ifndef DBMS_COLUMN_TYPE_UINT64_H
#define DBMS_COLUMN_TYPE_UINT64_H
#include <DB/ColumnTypes/IColumnType.h>
namespace DB
{
/** Аналог BIGINT UNSIGNED, сериализуется в набор байт фиксированной длины */
class ColumnTypeUInt64 : public IColumnType
{
public:
std::string getName() const { return "UInt64"; }
void serializeBinary(const Field & field, std::ostream & ostr) const
{
Poco::BinaryWriter w(ostr);
w << boost::get<UInt64>(field);
}
void deserializeBinary(Field & field, std::istream & istr) const
{
Poco::BinaryReader r(istr);
UInt64 x;
r >> x;
field = x;
}
void serializeBinary(const Column & column, std::ostream & ostr) const
{
Poco::BinaryWriter w(ostr);
const UInt64Column & column = boost::get<UInt64Column>(column);
for (size_t i = 0, size = column.size(); i < size; ++i)
w << column[i];
}
void deserializeBinary(Column & column, std::istream & istr) const
{
Poco::BinaryReader r(istr);
UInt64Column & column = boost::get<UInt64Column>(column);
for (size_t i = 0, size = column.size(); i < size; ++i)
r >> column[i];
}
void serializeText(const Field & field, std::ostream & ostr) const
{
ostr << boost::get<UInt64>(field);
}
void deserializeText(Field & field, std::istream & istr) const
{
UInt64 x;
istr >> x;
field = x;
}
};
}
#endif

View File

@ -0,0 +1,35 @@
#ifndef DBMS_COLUMN_TYPES_NUMBER_FIXED_H
#define DBMS_COLUMN_TYPES_NUMBER_FIXED_H
#include <DB/Core/Column.h>
#include <DB/ColumnTypes/IColumnTypeNumberFixed.h>
namespace DB
{
/** Типы столбцов для чисел фиксированной ширины. */
#define DEFINE_COLUMN_TYPE_NUMBER_FIXED(TYPE) \
class ColumnType ## TYPE : public IColumnTypeNumberFixed<TYPE, TYPE ## Column> \
{ \
public: \
std::string getName() const { return #TYPE; } \
};
DEFINE_COLUMN_TYPE_NUMBER_FIXED(UInt8);
DEFINE_COLUMN_TYPE_NUMBER_FIXED(UInt16);
DEFINE_COLUMN_TYPE_NUMBER_FIXED(UInt32);
DEFINE_COLUMN_TYPE_NUMBER_FIXED(UInt64);
DEFINE_COLUMN_TYPE_NUMBER_FIXED(Int8);
DEFINE_COLUMN_TYPE_NUMBER_FIXED(Int16);
DEFINE_COLUMN_TYPE_NUMBER_FIXED(Int32);
DEFINE_COLUMN_TYPE_NUMBER_FIXED(Int64);
DEFINE_COLUMN_TYPE_NUMBER_FIXED(Float32);
DEFINE_COLUMN_TYPE_NUMBER_FIXED(Float64);
}
#endif

View File

@ -1,5 +1,5 @@
#ifndef DBMS_COLUMN_TYPES_ICOLUMNTYPE_H
#ifndef DBMS_COLUMN_TYPES_ICOLUMNTYPE_H
#define DBMS_COLUMN_TYPES_ICOLUMNTYPE_H
#include <ostream>
@ -10,19 +10,6 @@
namespace DB
{
/** Стиль квотирования значения.
*/
namespace QuoteStyle
{
enum Enum
{
None = 0, /// Без квотирования и эскейпинга. Hапример, для чисел.
String, /// В '', с эскейпингом с помощью \.
Array, /// В [], список значений через запятую, каждое из которых квотируется по своему.
Tuple, /// В (), список значений через запятую, каждое из которых квотируется по своему.
};
}
/** Метаданные типа для хранения (столбца).
* Содержит методы для сериализации/десериализации.
@ -33,6 +20,9 @@ public:
/// Основное имя типа (например, BIGINT UNSIGNED).
virtual std::string getName() const = 0;
/** Предполагается, что проверка статуса stream-ов производится вызывающей стороной.
*/
/** Бинарная сериализация - для сохранения на диск / в сеть и т. п.
* Обратите внимание, что присутствует по два вида методов
* - для работы с единичными значениями и целыми столбцами.
@ -40,7 +30,8 @@ public:
virtual void serializeBinary(const Field & field, std::ostream & ostr) const = 0;
virtual void deserializeBinary(Field & field, std::istream & istr) const = 0;
virtual void serializeBinary(const Column & column, std::ostream & ostr) const = 0;
virtual void deserializeBinary(Column & column, std::istream & istr) const = 0;
/** Считать не более limit значений. */
virtual void deserializeBinary(Column & column, std::istream & istr, size_t limit) const = 0;
/** Текстовая сериализация - для вывода на экран / сохранения в текстовый файл и т. п.
* Без эскейпинга и квотирования.
@ -48,23 +39,18 @@ public:
virtual void serializeText(const Field & field, std::ostream & ostr) const = 0;
virtual void deserializeText(Field & field, std::istream & istr) const = 0;
/** Получить стиль квотирования значений этого типа.
*/
virtual QuoteStyle::Enum getQuoteStyle() const = 0;
/** Текстовая сериализация с эскейпингом, но без квотирования.
* Есть реализация по умолчанию, которая подходит почти для всех случаев.
*/
virtual void serializeTextEscaped(const Field & field, std::ostream & ostr) const;
virtual void deserializeTextEscaped(Field & field, std::istream & istr) const;
virtual void serializeTextEscaped(const Field & field, std::ostream & ostr) const = 0;
virtual void deserializeTextEscaped(Field & field, std::istream & istr) const = 0;
/** Текстовая сериализация в виде литерала, который может быть вставлен в запрос.
* Если compatible = true, то значение типа "массив" и "кортеж" ещё дополнительно записывается в кавычки,
* чтобы текстовый дамп можно было загрузить в другую СУБД с этими значениями в виде строки.
* Есть реализация по умолчанию, которая подходит почти для всех случаев.
*/
virtual void serializeTextQuoted(const Field & field, std::ostream & ostr, bool compatible = false) const;
virtual void deserializeTextQuoted(Field & field, std::istream & istr, bool compatible = false) const;
virtual void serializeTextQuoted(const Field & field, std::ostream & ostr, bool compatible = false) const = 0;
virtual void deserializeTextQuoted(Field & field, std::istream & istr, bool compatible = false) const = 0;
virtual ~IColumnType() {}

View File

@ -0,0 +1,53 @@
#ifndef DBMS_COLUMN_TYPES_ICOLUMNTYPE_NUMBER_H
#define DBMS_COLUMN_TYPES_ICOLUMNTYPE_NUMBER_H
#include <DB/ColumnTypes/IColumnType.h>
namespace DB
{
/** Реализует часть интерфейса IColumnType, общую для всяких чисел
* - ввод и вывод в текстовом виде.
*/
template <typename FieldType>
class IColumnTypeNumber : public IColumnType
{
public:
void serializeText(const Field & field, std::ostream & ostr) const
{
ostr << boost::get<FieldType>(field);
}
void deserializeText(Field & field, std::istream & istr) const
{
FieldType x;
istr >> x;
field = x;
}
void serializeTextEscaped(const Field & field, std::ostream & ostr) const
{
serializeText(field, ostr);
}
void deserializeTextEscaped(Field & field, std::istream & istr) const
{
deserializeText(field, istr);
}
void serializeTextQuoted(const Field & field, std::ostream & ostr, bool compatible = false) const
{
serializeText(field, ostr);
}
void deserializeTextQuoted(Field & field, std::istream & istr, bool compatible = false) const
{
deserializeText(field, istr);
}
};
}
#endif

View File

@ -0,0 +1,59 @@
#ifndef DBMS_COLUMN_TYPES_ICOLUMNTYPE_NUMBER_FIXED_H
#define DBMS_COLUMN_TYPES_ICOLUMNTYPE_NUMBER_FIXED_H
#include <Poco/BinaryWriter.h>
#include <Poco/BinaryReader.h>
#include <DB/ColumnTypes/IColumnTypeNumber.h>
namespace DB
{
/** Реализует часть интерфейса IColumnType, общую для всяких чисел фиксированной ширины
* - ввод и вывод в текстовом и бинарном виде.
* Остаётся лишь чисто виртуальный метод getName().
*
* Параметры: FieldType - тип единичного значения, ColumnType - тип столбца со значениями.
* (см. Field.h, Column.h)
*/
template <typename FieldType, typename ColumnType>
class IColumnTypeNumberFixed : public IColumnTypeNumber<FieldType>
{
public:
/** Формат платформозависимый (зависит от представления данных в памяти).
*/
void serializeBinary(const Field & field, std::ostream & ostr) const
{
/// ColumnType::value_type - более узкий тип. Например, UInt8, когда тип Field - UInt64
typename ColumnType::value_type x = boost::get<FieldType>(field);
ostr.write(reinterpret_cast<const char *>(&x), sizeof(x));
}
void deserializeBinary(Field & field, std::istream & istr) const
{
typename ColumnType::value_type x;
istr.read(reinterpret_cast<char *>(&x), sizeof(x));
field = x;
}
void serializeBinary(const Column & column, std::ostream & ostr) const
{
const ColumnType & x = boost::get<ColumnType>(column);
ostr.write(reinterpret_cast<const char *>(&x[0]), sizeof(typename ColumnType::value_type) * x.size());
}
void deserializeBinary(Column & column, std::istream & istr, size_t limit) const
{
ColumnType & x = boost::get<ColumnType>(column);
x.resize(limit);
istr.read(reinterpret_cast<char*>(&x[0]), sizeof(typename ColumnType::value_type) * limit);
x.resize(istr.gcount());
}
};
}
#endif

View File

@ -14,28 +14,21 @@ namespace DB
class UnescapingStreamBuf : public Poco::UnbufferedStreamBuf
{
public:
UnescapingStreamBuf(std::istream & istr);
UnescapingStreamBuf(std::istream & istr, char delimiter_);
protected:
int readFromDevice();
private:
std::istream * p_istr;
enum State
{
Normal = 0,
EscapeSequence
};
State state;
char delimiter;
};
class UnescapingIOS : public virtual std::ios
{
public:
UnescapingIOS(std::istream & istr);
UnescapingIOS(std::istream & istr, char delimiter_);
UnescapingStreamBuf * rdbuf();
protected:
@ -46,7 +39,7 @@ protected:
class UnescapingInputStream : public UnescapingIOS, public std::istream
{
public:
UnescapingInputStream(std::istream & istr);
UnescapingInputStream(std::istream & istr, char delimiter_);
};

View File

@ -9,7 +9,11 @@ namespace ErrorCodes
{
enum ErrorCodes
{
UNSUPPORTED_METHOD,
UNSUPPORTED_PARAMETER,
UNEXPECTED_END_OF_FILE,
CANNOT_READ_DATA_FROM_ISTREAM,
CANNOT_PARSE_TEXT,
};
}

View File

@ -1,30 +0,0 @@
#include <boost/variant/apply_visitor.hpp>
#include <DB/Common/EscapeManipulators.h>
#include <DB/Common/QuoteManipulators.h>
#include <DB/ColumnTypes/IColumnType.h>
namespace DB
{
virtual void serializeTextEscaped(const Field & field, std::ostream & ostr) const
{
FieldVisitorIsNull visitor;
if (boost::apply_visitor(visitor, field))
ostr << "\\N";
else
ostr <<
}
virtual void deserializeTextEscaped(Field & field, std::istream & istr) const;
virtual void serializeTextQuoted(const Field & field, std::ostream & ostr, bool compatible = false) const;
virtual void deserializeTextQuoted(Field & field, std::istream & istr, bool compatible = false) const;
};
}
#endif

View File

@ -0,0 +1,31 @@
#include <iostream>
#include <fstream>
#include <Poco/Stopwatch.h>
#include <DB/ColumnTypes/ColumnTypesNumberFixed.h>
int main(int argc, char ** argv)
{
DB::Column column = DB::UInt64Column();
DB::UInt64Column & vec = boost::get<DB::UInt64Column>(column);
DB::ColumnTypeUInt64 column_type;
Poco::Stopwatch stopwatch;
size_t n = 10000000;
vec.resize(n);
for (size_t i = 0; i < n; ++i)
vec[i] = i;
std::ofstream ostr("/dev/null");
stopwatch.restart();
column_type.serializeBinary(column, ostr);
stopwatch.stop();
std::cout << "Elapsed: " << static_cast<double>(stopwatch.elapsed()) / 1000000 << std::endl;
return 0;
}

View File

@ -5,8 +5,8 @@ namespace DB
{
UnescapingStreamBuf::UnescapingStreamBuf(std::istream & istr)
: p_istr(&istr), state(Normal)
UnescapingStreamBuf::UnescapingStreamBuf(std::istream & istr, char delimiter_)
: p_istr(&istr), delimiter(delimiter_)
{
}
@ -18,45 +18,49 @@ int UnescapingStreamBuf::readFromDevice()
return res;
char c = res;
switch (c)
if (c == '\\')
{
case '\\':
res = p_istr->get();
if (!p_istr->good())
return res;
c = res;
switch (c)
{
case '\\':
return '\\';
break;
case 'b':
return '\b';
break;
case 'f':
return '\f';
break;
case 'n':
return '\n';
break;
case 'r':
return '\r';
break;
case 't':
return '\t';
break;
default:
return c;
}
break;
default:
return c;
res = p_istr->get();
if (!p_istr->good())
return res;
c = res;
switch (c)
{
case '\\':
return '\\';
break;
case 'b':
return '\b';
break;
case 'f':
return '\f';
break;
case 'n':
return '\n';
break;
case 'r':
return '\r';
break;
case 't':
return '\t';
break;
default:
return c;
}
}
else if (c == delimiter)
{
return std::char_traits<char>::eof();
}
else
{
return c;
}
}
UnescapingIOS::UnescapingIOS(std::istream & istr)
: buf(istr)
UnescapingIOS::UnescapingIOS(std::istream & istr, char delimiter_)
: buf(istr, delimiter_)
{
}
@ -67,8 +71,8 @@ UnescapingStreamBuf * UnescapingIOS::rdbuf()
}
UnescapingInputStream::UnescapingInputStream(std::istream & istr)
: UnescapingIOS(istr),
UnescapingInputStream::UnescapingInputStream(std::istream & istr, char delimiter_)
: UnescapingIOS(istr, delimiter_),
std::istream(&buf)
{
}

View File

@ -11,12 +11,13 @@ int main(int argc, char ** argv)
std::stringstream stream;
DB::EscapingOutputStream o(stream);
DB::UnescapingInputStream i(stream);
DB::UnescapingInputStream i(stream, '"');
std::cout << s1 << std::endl;
o << s1;
stream << "\"xxx";
std::cout << stream.str() << std::endl;
i >> s2;
std::getline(i, s2);
std::cout << s2 << std::endl;
return 0;