Lukhnos: Optimized KeyValueBlobReader.

This commit is contained in:
ShikiSuen 2022-01-23 23:15:29 +08:00
parent 572002d950
commit b0de2b5683
2 changed files with 144 additions and 130 deletions

View File

@ -10,13 +10,13 @@
namespace vChewing { namespace vChewing {
KeyValueBlobReader::State KeyValueBlobReader::Next(KeyValue* out) { KeyValueBlobReader::State KeyValueBlobReader::Next(KeyValue* out)
{
static auto new_line = [](char c) { return c == '\n' || c == '\r'; }; static auto new_line = [](char c) { return c == '\n' || c == '\r'; };
static auto blank = [](char c) { return c == ' ' || c == '\t'; }; static auto blank = [](char c) { return c == ' ' || c == '\t'; };
static auto blank_or_newline = [](char c) { return blank(c) || new_line(c); }; static auto blank_or_newline
static auto content_char = [](char c) { = [](char c) { return blank(c) || new_line(c); };
return !blank(c) && !new_line(c); static auto content_char = [](char c) { return !blank(c) && !new_line(c); };
};
if (state_ == State::ERROR) { if (state_ == State::ERROR) {
return state_; return state_;
@ -80,8 +80,7 @@ KeyValueBlobReader::State KeyValueBlobReader::Next(KeyValue* out) {
SkipUntil(new_line); SkipUntil(new_line);
if (out != nullptr) { if (out != nullptr) {
*out = KeyValue{ *out = KeyValue { std::string_view { key_begin, key_length },
std::string_view{key_begin, key_length},
std::string_view { value_begin, value_length } }; std::string_view { value_begin, value_length } };
} }
state_ = State::HAS_PAIR; state_ = State::HAS_PAIR;
@ -89,11 +88,12 @@ KeyValueBlobReader::State KeyValueBlobReader::Next(KeyValue* out) {
error: error:
state_ = State::ERROR; state_ = State::ERROR;
return State::ERROR; return state_;
} }
KeyValueBlobReader::State KeyValueBlobReader::SkipUntilNot( KeyValueBlobReader::State KeyValueBlobReader::SkipUntilNot(
const std::function<bool(char)>& f) { const std::function<bool(char)>& f)
{
while (current_ != end_ && *current_) { while (current_ != end_ && *current_) {
if (!f(*current_)) { if (!f(*current_)) {
return State::CAN_CONTINUE; return State::CAN_CONTINUE;
@ -105,7 +105,8 @@ KeyValueBlobReader::State KeyValueBlobReader::SkipUntilNot(
} }
KeyValueBlobReader::State KeyValueBlobReader::SkipUntil( KeyValueBlobReader::State KeyValueBlobReader::SkipUntil(
const std::function<bool(char)>& f) { const std::function<bool(char)>& f)
{
while (current_ != end_ && *current_) { while (current_ != end_ && *current_) {
if (f(*current_)) { if (f(*current_)) {
return State::CAN_CONTINUE; return State::CAN_CONTINUE;
@ -116,8 +117,9 @@ KeyValueBlobReader::State KeyValueBlobReader::SkipUntil(
return State::END; return State::END;
} }
std::ostream& operator<<(std::ostream& os, std::ostream& operator<<(
const KeyValueBlobReader::KeyValue& kv) { std::ostream& os, const KeyValueBlobReader::KeyValue& kv)
{
os << "(key: " << kv.key << ", value: " << kv.value << ")"; os << "(key: " << kv.key << ", value: " << kv.value << ")";
return os; return os;
} }

View File

@ -44,11 +44,19 @@ class KeyValueBlobReader {
}; };
struct KeyValue { struct KeyValue {
constexpr KeyValue() : key(""), value("") {} constexpr KeyValue()
: key("")
, value("")
{
}
constexpr KeyValue(std::string_view k, std::string_view v) constexpr KeyValue(std::string_view k, std::string_view v)
: key(k), value(v) {} : key(k)
, value(v)
{
}
bool operator==(const KeyValue& another) const { bool operator==(const KeyValue& another) const
{
return key == another.key && value == another.value; return key == another.key && value == another.value;
} }
@ -57,10 +65,14 @@ class KeyValueBlobReader {
}; };
KeyValueBlobReader(const char* blob, size_t size) KeyValueBlobReader(const char* blob, size_t size)
: current_(blob), end_(blob + size) {} : current_(blob)
, end_(blob + size)
{
}
// Parse the next key-value pair and return the state of the reader. If `out` // Parse the next key-value pair and return the state of the reader. If
// is passed, out will be set to the produced key-value pair if there is one. // `out` is passed, out will be set to the produced key-value pair if there
// is one.
State Next(KeyValue* out = nullptr); State Next(KeyValue* out = nullptr);
private: private: