Skip to content

Commit

Permalink
- json: optimize class keys read/write performance
Browse files Browse the repository at this point in the history
  • Loading branch information
oknenavin committed Jun 23, 2024
1 parent c22f519 commit 7c6d4ca
Show file tree
Hide file tree
Showing 23 changed files with 512 additions and 282 deletions.
2 changes: 1 addition & 1 deletion src/cxon/cxon.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace cxon { // interface
struct format_selector : T {};

template <typename X, template <typename> class S>
using is_same_format = has_traits<S<X>, X>;
using is_same_format = has_traits<X, S>;

template <typename X, template <typename> class S, typename R = bool>
using enable_for_t = enable_if_t<is_same_format<X, S>::value, R>;
Expand Down
112 changes: 35 additions & 77 deletions src/cxon/lang/cbor/class.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -226,88 +226,46 @@ namespace cxon { namespace cbor { namespace cls {
#define CXON_CBOR_CLS_FIELD_ASIS_DFLT(F, ...) CXON_CBOR_CLS_FIELD_DFLT(CXON_T_, #F, F, __VA_ARGS__)
#define CXON_CBOR_CLS_FIELD_SKIP(N) cxon::cbor::cls::make_field<CXON_T_>(N, {})

#if defined(__cpp_constexpr) && __cpp_constexpr >= 201603L
# define CXON_CBOR_CLS_READ(Type, ...)\
namespace cxon {\
template <typename X, typename II, typename Cx>\
inline auto read_value(Type& t, II& i, II e, Cx& cx) -> enable_for_t<X, CBOR> {\
using CXON_T_ = Type;\
static constexpr auto f = cbor::cls::make_fields(__VA_ARGS__);\
return cbor::tag::read<X>(i, e, cx) &&\
cbor::cls::read_fields<X>(t, f, i, e, cx)\
;\
}\
}
# define CXON_CBOR_CLS_WRITE(Type, ...)\
namespace cxon {\
template <typename X, typename O, typename Cx>\
inline auto write_value(O& o, const Type& t, Cx& cx) -> enable_for_t<X, CBOR> {\
using CXON_T_ = Type;\
static constexpr auto f = cbor::cls::make_fields(__VA_ARGS__);\
return cbor::cls::write_fields<X>(o, t, f, cx);\
}\
}
#else
# define CXON_CBOR_CLS_READ(Type, ...)\
namespace cxon {\
template <typename X, typename II, typename Cx>\
inline auto read_value(Type& t, II& i, II e, Cx& cx) -> enable_for_t<X, CBOR> {\
using CXON_T_ = Type;\
static auto const f = cbor::cls::make_fields(__VA_ARGS__);\
return cbor::tag::read<X>(i, e, cx) &&\
cbor::cls::read_fields<X>(t, f, i, e, cx)\
;\
}\
}
# define CXON_CBOR_CLS_WRITE(Type, ...)\
namespace cxon {\
template <typename X, typename O, typename Cx>\
inline auto write_value(O& o, const Type& t, Cx& cx) -> enable_for_t<X, CBOR> {\
using CXON_T_ = Type;\
static auto const f = cbor::cls::make_fields(__VA_ARGS__);\
return cbor::cls::write_fields<X>(o, t, f, cx);\
}\
}
#endif
#define CXON_CBOR_CLS(Type, ...)\
CXON_CBOR_CLS_READ(Type, __VA_ARGS__)\
CXON_CBOR_CLS_WRITE(Type, __VA_ARGS__)

#if defined(__cpp_constexpr) && __cpp_constexpr >= 201603L
# define CXON_CBOR_CLS_READ_MEMBER(Type, ...)\
#define CXON_CBOR_CLS_READ(Type, ...)\
namespace cxon {\
template <typename X, typename II, typename Cx>\
static auto read_value(Type& t, II& i, II e, Cx& cx) -> cxon::enable_for_t<X, cxon::CBOR> {\
inline auto read_value(Type& t, II& i, II e, Cx& cx) -> enable_for_t<X, CBOR> {\
using CXON_T_ = Type;\
static constexpr auto f = cxon::cbor::cls::make_fields(__VA_ARGS__);\
return cxon::cbor::tag::read<X>(i, e, cx) &&\
cxon::cbor::cls::read_fields<X>(t, f, i, e, cx)\
static CXON_CXX17_CONSTEXPR auto f = cbor::cls::make_fields(__VA_ARGS__);\
return cbor::tag::read<X>(i, e, cx) &&\
cbor::cls::read_fields<X>(t, f, i, e, cx)\
;\
}
# define CXON_CBOR_CLS_WRITE_MEMBER(Type, ...)\
template <typename X, typename O, typename Cx>\
static auto write_value(O& o, const Type& t, Cx& cx) -> cxon::enable_for_t<X, cxon::CBOR> {\
using CXON_T_ = Type;\
static constexpr auto f = cxon::cbor::cls::make_fields(__VA_ARGS__);\
return cxon::cbor::cls::write_fields<X>(o, t, f, cx);\
}
#else
# define CXON_CBOR_CLS_READ_MEMBER(Type, ...)\
template <typename X, typename II, typename Cx>\
static auto read_value(Type& t, II& i, II e, Cx& cx) -> cxon::enable_for_t<X, cxon::CBOR> {\
using CXON_T_ = Type;\
static auto const f = cxon::cbor::cls::make_fields(__VA_ARGS__);\
return cxon::cbor::tag::read<X>(i, e, cx) &&\
cxon::cbor::cls::read_fields<X>(t, f, i, e, cx)\
;\
}
# define CXON_CBOR_CLS_WRITE_MEMBER(Type, ...)\
}\
}
#define CXON_CBOR_CLS_WRITE(Type, ...)\
namespace cxon {\
template <typename X, typename O, typename Cx>\
static auto write_value(O& o, const Type& t, Cx& cx) -> cxon::enable_for_t<X, cxon::CBOR> {\
inline auto write_value(O& o, const Type& t, Cx& cx) -> enable_for_t<X, CBOR> {\
using CXON_T_ = Type;\
static auto const f = cxon::cbor::cls::make_fields(__VA_ARGS__);\
return cxon::cbor::cls::write_fields<X>(o, t, f, cx);\
}
#endif
static CXON_CXX17_CONSTEXPR auto f = cbor::cls::make_fields(__VA_ARGS__);\
return cbor::cls::write_fields<X>(o, t, f, cx);\
}\
}
#define CXON_CBOR_CLS(Type, ...)\
CXON_CBOR_CLS_READ(Type, __VA_ARGS__)\
CXON_CBOR_CLS_WRITE(Type, __VA_ARGS__)

#define CXON_CBOR_CLS_READ_MEMBER(Type, ...)\
template <typename X, typename II, typename Cx>\
static auto read_value(Type& t, II& i, II e, Cx& cx) -> cxon::enable_for_t<X, cxon::CBOR> {\
using CXON_T_ = Type;\
static CXON_CXX17_CONSTEXPR auto f = cxon::cbor::cls::make_fields(__VA_ARGS__);\
return cxon::cbor::tag::read<X>(i, e, cx) &&\
cxon::cbor::cls::read_fields<X>(t, f, i, e, cx)\
;\
}
#define CXON_CBOR_CLS_WRITE_MEMBER(Type, ...)\
template <typename X, typename O, typename Cx>\
static auto write_value(O& o, const Type& t, Cx& cx) -> cxon::enable_for_t<X, cxon::CBOR> {\
using CXON_T_ = Type;\
static CXON_CXX17_CONSTEXPR auto f = cxon::cbor::cls::make_fields(__VA_ARGS__);\
return cxon::cbor::cls::write_fields<X>(o, t, f, cx);\
}
#define CXON_CBOR_CLS_MEMBER(Type, ...)\
CXON_CBOR_CLS_READ_MEMBER(Type, __VA_ARGS__)\
CXON_CBOR_CLS_WRITE_MEMBER(Type, __VA_ARGS__)
Expand Down
61 changes: 29 additions & 32 deletions src/cxon/lang/common/cio/char.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,35 @@ namespace cxon { namespace cio { namespace chr {

namespace imp {

static constexpr char should_escape_not_quoted_key_context_[] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
template <typename X>
constexpr auto should_escape_(char c) noexcept -> enable_if_t<!is_quoted_key_context<X>::value, bool> {
return should_escape_not_quoted_key_context_[(unsigned char)c] == '\1';
}
static constexpr char should_escape_quoted_key_context_[] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
template <typename X>
constexpr auto should_escape_(char c) noexcept -> enable_if_t< is_quoted_key_context<X>::value, bool> {
return should_escape_quoted_key_context_[(unsigned char)c] == '\1';
}

template <typename X, typename T>
struct encode_;

Expand Down Expand Up @@ -439,38 +468,6 @@ namespace cxon { namespace cio { namespace chr {
}
return a == f || poke<X>(o, a, f, cx);
}
template <typename Y = X>
static auto should_escape_(char c) noexcept
-> enable_if_t<!is_quoted_key_context<Y>::value, bool>
{
static constexpr char se_[] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
return se_[(unsigned char)c] == '\1';
}
template <typename Y = X>
static auto should_escape_(char c) noexcept
-> enable_if_t< is_quoted_key_context<Y>::value, bool>
{
static constexpr char se_[] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
return se_[(unsigned char)c] == '\1';
}
};

template <typename X>
Expand Down
6 changes: 4 additions & 2 deletions src/cxon/lang/common/cio/cio.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ namespace cxon { namespace cio { // key quoting helpers
template <typename T> struct quoted_traits : T {};
}
template <typename X>
using is_unquoted_key_context = has_traits<key::unquoted_traits<X>, X>;
using is_unquoted_key_context = has_traits<X, key::unquoted_traits>;
template <typename X>
using unquoted_key_context = conditional_t<is_unquoted_key_context<X>::value, X, bind_traits_t<X, key::unquoted_traits>>;
template <typename X>
using is_quoted_key_context = has_traits<key::quoted_traits<X>, X>;
using is_quoted_key_context = has_traits<X, key::quoted_traits>;
template <typename X>
using quoted_key_context = conditional_t<is_quoted_key_context<X>::value, X, bind_traits_t<X, key::quoted_traits>>;

Expand All @@ -104,6 +104,8 @@ namespace cxon { namespace cio { // key quoting helpers

namespace cxon { namespace cio { namespace str {

template <typename T> struct raw_traits : T {};

template <typename X>
inline auto delim_en_check(char c) -> enable_if_t<!is_unquoted_key_context<X>::value, bool> {
CXON_IF_CONSTEXPR (!is_quoted_key_context<X>::value) {
Expand Down
Loading

0 comments on commit 7c6d4ca

Please sign in to comment.