Commit 227f5881 authored by zhujiashun's avatar zhujiashun

redis_server_protocol: add append_decimal to IOBufappender

parent 7ba68500
......@@ -40,8 +40,6 @@ const char* RedisReplyTypeToString(RedisReplyType type) {
}
bool RedisReply::SerializeTo(butil::IOBufAppender* appender) {
char prefix_buf[24]; // should be enough for '<type><integer>\r\n"
size_t len = 0;
switch (_type) {
case REDIS_REPLY_ERROR:
// fall through
......@@ -55,40 +53,32 @@ bool RedisReply::SerializeTo(butil::IOBufAppender* appender) {
appender->append("\r\n");
break;
case REDIS_REPLY_INTEGER:
prefix_buf[0] = ':';
len = butil::AppendDecimal(&prefix_buf[1], _data.integer);
prefix_buf[len + 1] = '\r';
prefix_buf[len + 2] = '\n';
appender->append(prefix_buf, len + 3 /* 1 for ':', 2 for "\r\n" */);
appender->push_back(':');
appender->append_decimal(_data.integer);
appender->append("\r\n");
break;
case REDIS_REPLY_STRING:
prefix_buf[0] = '$';
len = butil::AppendDecimal(&prefix_buf[1], _length);
prefix_buf[len + 1] = '\r';
prefix_buf[len + 2] = '\n';
appender->append(prefix_buf, len + 3 /* 1 for ':', 2 for "\r\n" */);
if (_length == npos) {
break;
}
if (_length < (int)sizeof(_data.short_str)) {
appender->append(_data.short_str, _length);
} else {
appender->append(_data.long_str, _length);
}
appender->push_back('$');
appender->append_decimal(_length);
appender->append("\r\n");
if (_length != npos) {
if (_length < (int)sizeof(_data.short_str)) {
appender->append(_data.short_str, _length);
} else {
appender->append(_data.long_str, _length);
}
appender->append("\r\n");
}
break;
case REDIS_REPLY_ARRAY:
prefix_buf[0] = '*';
len = butil::AppendDecimal(&prefix_buf[1], _length);
prefix_buf[len + 1] = '\r';
prefix_buf[len + 2] = '\n';
appender->append(prefix_buf, len + 3 /* 1 for ':', 2 for "\r\n" */);
if (_length == npos) {
break;
}
for (int i = 0; i < _length; ++i) {
if (!_data.array.replies[i].SerializeTo(appender)) {
return false;
appender->push_back('*');
appender->append_decimal(_length);
appender->append("\r\n");
if (_length != npos) {
for (int i = 0; i < _length; ++i) {
if (!_data.array.replies[i].SerializeTo(appender)) {
return false;
}
}
}
break;
......
......@@ -669,6 +669,11 @@ public:
// Returns 0 on success, -1 otherwise.
int append(const void* data, size_t n);
int append(const butil::StringPiece& str);
// Format integer |d| to back side of the internal buffer, which is much faster
// than snprintf(..., "%lu", d).
// Returns 0 on success, -1 otherwise.
int append_decimal(long d);
// Push the character to back side of the internal buffer.
// Costs ~3ns while IOBuf.push_back costs ~13ns on Intel(R) Xeon(R) CPU
......
......@@ -285,6 +285,25 @@ inline int IOBufAppender::append(const StringPiece& str) {
return append(str.data(), str.size());
}
inline int IOBufAppender::append_decimal(long d) {
char buf[24]; // enough for decimal 64-bit integers
size_t n = sizeof(buf);
bool negative = false;
if (d < 0) {
negative = true;
d = -d;
}
do {
const long q = d / 10;
buf[--n] = d - q * 10 + '0';
d = q;
} while (d);
if (negative) {
buf[--n] = '-';
}
return append(buf + n, sizeof(buf) - n);
}
inline int IOBufAppender::push_back(char c) {
if (_data == _data_end) {
if (add_block() != 0) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment