nghttpx: Optimize logging further

This commit is contained in:
Tatsuhiro Tsujikawa 2016-01-17 15:04:09 +09:00
parent 4f07db8bcb
commit 7b2d4b6ae6
6 changed files with 59 additions and 23 deletions

View File

@ -542,7 +542,8 @@ std::vector<LogFragment> parse_log_format(const char *optarg) {
}
if (literal_start < var_start) {
res.emplace_back(SHRPX_LOGF_LITERAL, strcopy(literal_start, var_start));
res.emplace_back(SHRPX_LOGF_LITERAL,
ImmutableString(literal_start, var_start));
}
literal_start = p;
@ -552,17 +553,18 @@ std::vector<LogFragment> parse_log_format(const char *optarg) {
continue;
}
res.emplace_back(type, strcopy(value, var_name + var_namelen));
auto &v = res.back().value;
for (size_t i = 0; v[i]; ++i) {
if (v[i] == '_') {
v[i] = '-';
auto name = std::string(value, var_name + var_namelen);
for (auto &c : name) {
if (c == '_') {
c = '-';
}
}
res.emplace_back(type, ImmutableString(name));
}
if (literal_start != eop) {
res.emplace_back(SHRPX_LOGF_LITERAL, strcopy(literal_start, eop));
res.emplace_back(SHRPX_LOGF_LITERAL, ImmutableString(literal_start, eop));
}
return res;

View File

@ -224,8 +224,8 @@ void Downstream::force_resume_read() {
}
namespace {
const Headers::value_type *get_header_linear(const Headers &headers,
const std::string &name) {
const Headers::value_type *search_header_linear(const Headers &headers,
const StringRef &name) {
const Headers::value_type *res = nullptr;
for (auto &kv : headers) {
if (kv.name == name) {
@ -395,8 +395,8 @@ Headers::value_type *FieldStore::header(int16_t token) {
return http2::get_header(hdidx_, token, headers_);
}
const Headers::value_type *FieldStore::header(const std::string &name) const {
return get_header_linear(headers_, name);
const Headers::value_type *FieldStore::header(const StringRef &name) const {
return search_header_linear(headers_, name);
}
void FieldStore::add_header(std::string name, std::string value) {

View File

@ -76,7 +76,7 @@ public:
Headers::value_type *header(int16_t token);
// Returns pointer to the header field with the name |name|. If no
// such header is found, returns nullptr.
const Headers::value_type *header(const std::string &name) const;
const Headers::value_type *header(const StringRef &name) const;
void add_header(std::string name, std::string value);
void add_header(std::string name, std::string value, int16_t token);

View File

@ -243,7 +243,7 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
for (auto &lf : lfv) {
switch (lf.type) {
case SHRPX_LOGF_LITERAL:
std::tie(p, avail) = copy(lf.value.get(), avail, p);
std::tie(p, avail) = copy(lf.value, avail, p);
break;
case SHRPX_LOGF_REMOTE_ADDR:
std::tie(p, avail) = copy(lgsp.remote_addr, avail, p);
@ -273,7 +273,7 @@ void upstream_accesslog(const std::vector<LogFragment> &lfv,
break;
case SHRPX_LOGF_HTTP:
if (req) {
auto hd = req->fs.header(lf.value.get());
auto hd = req->fs.header(lf.value);
if (hd) {
std::tie(p, avail) = copy((*hd).value, avail, p);
break;

View File

@ -134,10 +134,10 @@ enum LogFragmentType {
};
struct LogFragment {
LogFragment(LogFragmentType type, std::unique_ptr<char[]> value = nullptr)
LogFragment(LogFragmentType type, ImmutableString value = ImmutableString())
: type(type), value(std::move(value)) {}
LogFragmentType type;
std::unique_ptr<char[]> value;
ImmutableString value;
};
struct LogSpec {

View File

@ -218,6 +218,16 @@ inline std::unique_ptr<char[]> strcopy(const std::unique_ptr<char[]> &val,
// appear before the final terminal NULL.
class ImmutableString {
public:
using traits_type = std::char_traits<char>;
using value_type = traits_type::char_type;
using allocator_type = std::allocator<char>;
using size_type = std::allocator_traits<allocator_type>::size_type;
using difference_type =
std::allocator_traits<allocator_type>::difference_type;
using const_reference = const value_type &;
using const_pointer = const value_type *;
using const_iterator = const_pointer;
ImmutableString() : len(0) {}
ImmutableString(const char *s, size_t slen)
: len(slen), base(strcopy(s, len)) {}
@ -244,10 +254,10 @@ public:
}
const char *c_str() const { return base.get(); }
size_t size() const { return len; }
size_type size() const { return len; }
private:
size_t len;
size_type len;
std::unique_ptr<char[]> base;
};
@ -258,10 +268,19 @@ private:
// function can be used to export the content as std::string.
class StringRef {
public:
using traits_type = std::char_traits<char>;
using value_type = traits_type::char_type;
using allocator_type = std::allocator<char>;
using size_type = std::allocator_traits<allocator_type>::size_type;
using difference_type =
std::allocator_traits<allocator_type>::difference_type;
using const_reference = const value_type &;
using const_pointer = const value_type *;
using const_iterator = const_pointer;
StringRef() : base(""), len(0) {}
template <typename T>
StringRef(const T &s)
: base(s.c_str()), len(s.size()) {}
StringRef(const std::string &s) : base(s.c_str()), len(s.size()) {}
StringRef(const ImmutableString &s) : base(s.c_str()), len(s.size()) {}
StringRef(const char *s) : base(s), len(strlen(s)) {}
StringRef(const char *s, size_t n) : base(s), len(n) {}
@ -269,16 +288,31 @@ public:
return StringRef(s, N - 1);
}
const_iterator begin() const { return base; };
const_iterator cbegin() const { return base; };
const_iterator end() const { return base + len; };
const_iterator cend() const { return base + len; };
const char *c_str() const { return base; }
size_t size() const { return len; }
size_type size() const { return len; }
std::string str() const { return std::string(base, len); }
private:
const char *base;
size_t len;
size_type len;
};
inline bool operator==(const StringRef &lhs, const std::string &rhs) {
return lhs.size() == rhs.size() &&
std::equal(std::begin(lhs), std::end(lhs), std::begin(rhs));
}
inline bool operator==(const std::string &lhs, const StringRef &rhs) {
return rhs == lhs;
}
inline int run_app(std::function<int(int, char **)> app, int argc,
char **argv) {
try {