From 7a360b0cd6c936b7e76ff05743822f0bc6399555 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 1 Jun 2010 14:12:28 +0000 Subject: [PATCH] dbms: development. --- dbms/include/DB/Common/VarInt.h | 25 +++-- dbms/include/DB/Core/ReadBuffer.h | 95 +---------------- dbms/include/DB/Core/WriteBuffer.h | 59 +---------- .../DB/DataTypes/IDataTypeNumberVariable.h | 8 +- dbms/src/Core/ReadBuffer.cpp | 100 ++++++++++++++++++ dbms/src/Core/WriteBuffer.cpp | 60 +++++++++++ 6 files changed, 188 insertions(+), 159 deletions(-) create mode 100644 dbms/src/Core/ReadBuffer.cpp create mode 100644 dbms/src/Core/WriteBuffer.cpp diff --git a/dbms/include/DB/Common/VarInt.h b/dbms/include/DB/Common/VarInt.h index de05014c3c8..3b50672c485 100644 --- a/dbms/include/DB/Common/VarInt.h +++ b/dbms/include/DB/Common/VarInt.h @@ -2,6 +2,8 @@ #define DB_VARINT_H #include +#include +#include namespace DB @@ -10,10 +12,12 @@ namespace DB /** Записать UInt64 в формате переменной длины (base128) */ void writeVarUInt(UInt64 x, std::ostream & ostr); +void writeVarUInt(UInt64 x, WriteBuffer & ostr); /** Прочитать UInt64, записанный в формате переменной длины (base128) */ void readVarUInt(UInt64 & x, std::istream & istr); +void readVarUInt(UInt64 & x, ReadBuffer & istr); /** Получить длину UInt64 в формате VarUInt */ @@ -21,28 +25,31 @@ size_t getLengthOfVarUInt(UInt64 x); /** Записать Int64 в формате переменной длины (base128) */ -inline void writeVarInt(Int64 x, std::ostream & ostr) +template +inline void writeVarInt(Int64 x, OUT & ostr) { writeVarUInt(static_cast((x << 1) ^ (x >> 63)), ostr); } /** Прочитать Int64, записанный в формате переменной длины (base128) */ -inline void readVarInt(Int64 & x, std::istream & istr) +template +inline void readVarInt(Int64 & x, IN & istr) { readVarUInt(*reinterpret_cast(&x), istr); x = (static_cast(x) >> 1) ^ -(x & 1); } -template inline void writeVarT(T x, std::ostream & ostr); -template <> inline void writeVarT(UInt64 x, std::ostream & ostr) { writeVarUInt(x, ostr); } -template <> inline void writeVarT(Int64 x, std::ostream & ostr) { writeVarInt(x, ostr); } - -template inline void readVarT(T & x, std::istream & istr); -template <> inline void readVarT(UInt64 & x, std::istream & istr) { readVarUInt(x, istr); } -template <> inline void readVarT(Int64 & x, std::istream & istr) { readVarInt(x, istr); } +inline void writeVarT(UInt64 x, std::ostream & ostr) { writeVarUInt(x, ostr); } +inline void writeVarT(Int64 x, std::ostream & ostr) { writeVarInt(x, ostr); } +inline void writeVarT(UInt64 x, WriteBuffer & ostr) { writeVarUInt(x, ostr); } +inline void writeVarT(Int64 x, WriteBuffer & ostr) { writeVarInt(x, ostr); } +inline void readVarT(UInt64 & x, std::istream & istr) { readVarUInt(x, istr); } +inline void readVarT(Int64 & x, std::istream & istr) { readVarInt(x, istr); } +inline void readVarT(UInt64 & x, ReadBuffer & istr) { readVarUInt(x, istr); } +inline void readVarT(Int64 & x, ReadBuffer & istr) { readVarInt(x, istr); } } diff --git a/dbms/include/DB/Core/ReadBuffer.h b/dbms/include/DB/Core/ReadBuffer.h index 6030dbc8099..6f779982c61 100644 --- a/dbms/include/DB/Core/ReadBuffer.h +++ b/dbms/include/DB/Core/ReadBuffer.h @@ -113,16 +113,7 @@ static inline char parseEscapeSequence(char c) } } -static void assertString(const char * s, ReadBuffer & buf) -{ - for (; *s; ++s) - { - if (buf.eof() || *buf.position() != *s) - throw Exception(String("Cannot parse input: expected ") + s, ErrorCodes::CANNOT_PARSE_INPUT_ASSERTION_FAILED); - ++buf.position(); - } -} - +void assertString(const char * s, ReadBuffer & buf); /// грубо template @@ -270,89 +261,11 @@ void readFloatText(T & x, ReadBuffer & buf) } /// грубо; всё до '\n' или '\t' -void readString(String & s, ReadBuffer & buf) -{ - s = ""; - while (!buf.eof()) - { - size_t bytes = 0; - for (; buf.position() + bytes != buf.buffer().end(); ++bytes) - if (buf.position()[bytes] == '\t' || buf.position()[bytes] == '\n') - break; +void readString(String & s, ReadBuffer & buf); - s.append(buf.position(), bytes); - buf.position() += bytes; +void readEscapedString(String & s, ReadBuffer & buf); - if (buf.position() != buf.buffer().end()) - return; - } -} - -void readEscapedString(String & s, ReadBuffer & buf) -{ - s = ""; - while (!buf.eof()) - { - size_t bytes = 0; - for (; buf.position() + bytes != buf.buffer().end(); ++bytes) - if (buf.position()[bytes] == '\\' || buf.position()[bytes] == '\t' || buf.position()[bytes] == '\n') - break; - - s.append(buf.position(), bytes); - buf.position() += bytes; - - if (*buf.position() == '\t' || *buf.position() == '\n') - return; - - if (*buf.position() == '\\') - { - ++buf.position(); - if (buf.eof()) - throw Exception("Cannot parse escape sequence", ErrorCodes::CANNOT_PARSE_ESCAPE_SEQUENCE); - s += parseEscapeSequence(*buf.position()); - ++buf.position(); - } - } -} - -void readQuotedString(String & s, ReadBuffer & buf) -{ - s = ""; - - if (buf.eof() || *buf.position() != '\'') - throw Exception("Cannot parse quoted string: expected opening single quote", - ErrorCodes::CANNOT_PARSE_QUOTED_STRING); - ++buf.position(); - - while (!buf.eof()) - { - size_t bytes = 0; - for (; buf.position() + bytes != buf.buffer().end(); ++bytes) - if (buf.position()[bytes] == '\\' || buf.position()[bytes] == '\'') - break; - - s.append(buf.position(), bytes); - buf.position() += bytes; - - if (*buf.position() == '\'') - { - ++buf.position(); - return; - } - - if (*buf.position() == '\\') - { - ++buf.position(); - if (buf.eof()) - throw Exception("Cannot parse escape sequence", ErrorCodes::CANNOT_PARSE_ESCAPE_SEQUENCE); - s += parseEscapeSequence(*buf.position()); - ++buf.position(); - } - } - - throw Exception("Cannot parse quoted string: expected closing single quote", - ErrorCodes::CANNOT_PARSE_QUOTED_STRING); -} +void readQuotedString(String & s, ReadBuffer & buf); } diff --git a/dbms/include/DB/Core/WriteBuffer.h b/dbms/include/DB/Core/WriteBuffer.h index 79d56936317..597d0046885 100644 --- a/dbms/include/DB/Core/WriteBuffer.h +++ b/dbms/include/DB/Core/WriteBuffer.h @@ -91,7 +91,7 @@ protected: /// Функции-помошники для форматированной записи -void writeChar(char x, WriteBuffer & buf) +inline void writeChar(char x, WriteBuffer & buf) { buf.nextIfAtEnd(); *buf.position() = x; @@ -100,16 +100,7 @@ void writeChar(char x, WriteBuffer & buf) template struct IntFormat { static const char * format; }; -template <> const char * IntFormat::format = "%hhi"; -template <> const char * IntFormat::format = "%hi"; -template <> const char * IntFormat::format = "%li"; -template <> const char * IntFormat::format = "%lli"; -template <> const char * IntFormat::format = "%hhi"; -template <> const char * IntFormat::format = "%hi"; -template <> const char * IntFormat::format = "%li"; -template <> const char * IntFormat::format = "%lli"; -/// грубо template void writeIntText(T x, WriteBuffer & buf) { @@ -135,57 +126,15 @@ void writeFloatText(T x, WriteBuffer & buf, unsigned precision = DEFAULT_FLOAT_P buf.write(tmp, res - 1); } -void writeString(const String & s, WriteBuffer & buf) +inline void writeString(const String & s, WriteBuffer & buf) { buf.write(s.data(), s.size()); } /// предполагается, что строка в оперативке хранится непрерывно, и \0-terminated. -void writeEscapedString(const String & s, WriteBuffer & buf) -{ - for (String::const_iterator it = s.begin(); it != s.end(); ++it) - { - switch (*it) - { - case '\b': - writeChar('\\', buf); - writeChar('b', buf); - break; - case '\f': - writeChar('\\', buf); - writeChar('f', buf); - break; - case '\n': - writeChar('\\', buf); - writeChar('n', buf); - break; - case '\r': - writeChar('\\', buf); - writeChar('r', buf); - break; - case '\t': - writeChar('\\', buf); - writeChar('t', buf); - break; - case '\0': - writeChar('\\', buf); - writeChar('0', buf); - break; - case '\'': - writeChar('\\', buf); - writeChar('\'', buf); - break; - case '\\': - writeChar('\\', buf); - writeChar('\\', buf); - break; - default: - writeChar(*it, buf); - } - } -} +void writeEscapedString(const String & s, WriteBuffer & buf); -void writeQuotedString(const String & s, WriteBuffer & buf) +inline void writeQuotedString(const String & s, WriteBuffer & buf) { writeChar('\'', buf); writeEscapedString(s, buf); diff --git a/dbms/include/DB/DataTypes/IDataTypeNumberVariable.h b/dbms/include/DB/DataTypes/IDataTypeNumberVariable.h index 142ac2ff676..249c1da16dc 100644 --- a/dbms/include/DB/DataTypes/IDataTypeNumberVariable.h +++ b/dbms/include/DB/DataTypes/IDataTypeNumberVariable.h @@ -25,12 +25,12 @@ class IDataTypeNumberVariable : public IDataTypeNumber public: void serializeBinary(const Field & field, std::ostream & ostr) const { - writeVarT(boost::get(field), ostr); + writeVarT(static_cast(boost::get(field)), ostr); } void deserializeBinary(Field & field, std::istream & istr) const { - readVarT(boost::get(field), istr); + readVarT(static_cast(boost::get(field)), istr); } void serializeBinary(const IColumn & column, std::ostream & ostr) const @@ -38,7 +38,7 @@ public: const typename ColumnType::Container_t & x = dynamic_cast(column).getData(); size_t size = x.size(); for (size_t i = 0; i < size; ++i) - writeVarT(x[i], ostr); + writeVarT(x[i], ostr); } void deserializeBinary(IColumn & column, std::istream & istr, size_t limit) const @@ -47,7 +47,7 @@ public: x.resize(limit); for (size_t i = 0; i < limit; ++i) { - readVarT(x[i], istr); + readVarT(x[i], istr); if (istr.eof()) { diff --git a/dbms/src/Core/ReadBuffer.cpp b/dbms/src/Core/ReadBuffer.cpp new file mode 100644 index 00000000000..84c956c11fc --- /dev/null +++ b/dbms/src/Core/ReadBuffer.cpp @@ -0,0 +1,100 @@ +#include + +namespace DB +{ + +void assertString(const char * s, ReadBuffer & buf) +{ + for (; *s; ++s) + { + if (buf.eof() || *buf.position() != *s) + throw Exception(String("Cannot parse input: expected ") + s, ErrorCodes::CANNOT_PARSE_INPUT_ASSERTION_FAILED); + ++buf.position(); + } +} + +void readString(String & s, ReadBuffer & buf) +{ + s = ""; + while (!buf.eof()) + { + size_t bytes = 0; + for (; buf.position() + bytes != buf.buffer().end(); ++bytes) + if (buf.position()[bytes] == '\t' || buf.position()[bytes] == '\n') + break; + + s.append(buf.position(), bytes); + buf.position() += bytes; + + if (buf.position() != buf.buffer().end()) + return; + } +} + +void readEscapedString(String & s, ReadBuffer & buf) +{ + s = ""; + while (!buf.eof()) + { + size_t bytes = 0; + for (; buf.position() + bytes != buf.buffer().end(); ++bytes) + if (buf.position()[bytes] == '\\' || buf.position()[bytes] == '\t' || buf.position()[bytes] == '\n') + break; + + s.append(buf.position(), bytes); + buf.position() += bytes; + + if (*buf.position() == '\t' || *buf.position() == '\n') + return; + + if (*buf.position() == '\\') + { + ++buf.position(); + if (buf.eof()) + throw Exception("Cannot parse escape sequence", ErrorCodes::CANNOT_PARSE_ESCAPE_SEQUENCE); + s += parseEscapeSequence(*buf.position()); + ++buf.position(); + } + } +} + +void readQuotedString(String & s, ReadBuffer & buf) +{ + s = ""; + + if (buf.eof() || *buf.position() != '\'') + throw Exception("Cannot parse quoted string: expected opening single quote", + ErrorCodes::CANNOT_PARSE_QUOTED_STRING); + ++buf.position(); + + while (!buf.eof()) + { + size_t bytes = 0; + for (; buf.position() + bytes != buf.buffer().end(); ++bytes) + if (buf.position()[bytes] == '\\' || buf.position()[bytes] == '\'') + break; + + s.append(buf.position(), bytes); + buf.position() += bytes; + + if (*buf.position() == '\'') + { + ++buf.position(); + return; + } + + if (*buf.position() == '\\') + { + ++buf.position(); + if (buf.eof()) + throw Exception("Cannot parse escape sequence", ErrorCodes::CANNOT_PARSE_ESCAPE_SEQUENCE); + s += parseEscapeSequence(*buf.position()); + ++buf.position(); + } + } + + throw Exception("Cannot parse quoted string: expected closing single quote", + ErrorCodes::CANNOT_PARSE_QUOTED_STRING); +} + +} diff --git a/dbms/src/Core/WriteBuffer.cpp b/dbms/src/Core/WriteBuffer.cpp new file mode 100644 index 00000000000..d51a0860c92 --- /dev/null +++ b/dbms/src/Core/WriteBuffer.cpp @@ -0,0 +1,60 @@ +#include + +namespace DB +{ + +template <> const char * IntFormat::format = "%hhi"; +template <> const char * IntFormat::format = "%hi"; +template <> const char * IntFormat::format = "%li"; +template <> const char * IntFormat::format = "%lli"; +template <> const char * IntFormat::format = "%hhi"; +template <> const char * IntFormat::format = "%hi"; +template <> const char * IntFormat::format = "%li"; +template <> const char * IntFormat::format = "%lli"; + + +void writeEscapedString(const String & s, WriteBuffer & buf) +{ + for (String::const_iterator it = s.begin(); it != s.end(); ++it) + { + switch (*it) + { + case '\b': + writeChar('\\', buf); + writeChar('b', buf); + break; + case '\f': + writeChar('\\', buf); + writeChar('f', buf); + break; + case '\n': + writeChar('\\', buf); + writeChar('n', buf); + break; + case '\r': + writeChar('\\', buf); + writeChar('r', buf); + break; + case '\t': + writeChar('\\', buf); + writeChar('t', buf); + break; + case '\0': + writeChar('\\', buf); + writeChar('0', buf); + break; + case '\'': + writeChar('\\', buf); + writeChar('\'', buf); + break; + case '\\': + writeChar('\\', buf); + writeChar('\\', buf); + break; + default: + writeChar(*it, buf); + } + } +} + +}