# # # patch "vocab.cc" # from [9e7e99b5b2e0088d4b2e2f41b0cb0682fb2024c0] # to [05c0e03920108f99c1f89b9438a516736cc1b857] # # patch "vocab.hh" # from [2bd8cac9e74aecc7e0de12a440d08fd9153bfdfa] # to [31f55c37c36cb02f5549724bc59df9e8fcaa0f5a] # # patch "vocab_macros.hh" # from [c80d10b6ae90fb581c2e86cb989a3262b566cabc] # to [7025028f87c647715e14fb50c13866e8df52d684] # ============================================================ --- vocab.cc 9e7e99b5b2e0088d4b2e2f41b0cb0682fb2024c0 +++ vocab.cc 05c0e03920108f99c1f89b9438a516736cc1b857 @@ -124,7 +124,7 @@ verify_full(netsync_session_key & val) { if (val().size() == 0) { - val.s.append(constants::netsync_session_key_length_in_bytes, 0); + val.s = std::string(constants::netsync_session_key_length_in_bytes, 0); return; } @@ -139,7 +139,7 @@ verify_full(netsync_hmac_value & val) { if (val().size() == 0) { - val.s.append(constants::netsync_hmac_value_length_in_bytes, 0); + val.s = std::string(constants::netsync_hmac_value_length_in_bytes, 0); return; } ============================================================ --- vocab.hh 2bd8cac9e74aecc7e0de12a440d08fd9153bfdfa +++ vocab.hh 31f55c37c36cb02f5549724bc59df9e8fcaa0f5a @@ -16,6 +16,8 @@ #include #include +#include + // the purpose of this file is to wrap things which are otherwise strings // in a bit of typesafety, set up enumerations and tuple-types, and // generally describe the "vocabulary" (nouns anyways) that modules in this @@ -35,6 +37,34 @@ void dump(T const &, std::string &) == sizeof(T)) }; } +// For some reason, shared_ptr copy is about a hundred times faster +// than string refcopy on my system (g++ 4). This only happens because +// we tell Boost not to worry about threads... but I don't recognize any +// thread stuff in the string headers. +class immutable_string +{ + boost::shared_ptr _rep; + +public: + immutable_string() + {} + immutable_string(std::string const & s) + : _rep(new std::string(s)) + {} + + std::string const & get() const + { + static std::string empty; + if (_rep) + return *_rep; + else + return empty; + } +}; + + + + #include "vocab_macros.hh" #define ENCODING(enc) hh_ENCODING(enc) #define DECORATE(dec) hh_DECORATE(dec) ============================================================ --- vocab_macros.hh c80d10b6ae90fb581c2e86cb989a3262b566cabc +++ vocab_macros.hh 7025028f87c647715e14fb50c13866e8df52d684 @@ -75,21 +75,21 @@ class ty { #define hh_ATOMIC(ty) \ class ty { \ - std::string s; \ + immutable_string s; \ public: \ bool ok; \ ty() : ok(false) {} \ explicit ty(std::string const & str); \ ty(ty const & other); \ std::string const & operator()() const \ - { return s; } \ + { return s.get(); } \ bool operator<(ty const & other) const \ - { return s < other(); } \ + { return s.get() < other(); } \ ty const & operator=(ty const & other); \ bool operator==(ty const & other) const \ - { return s == other(); } \ + { return s.get() == other(); } \ bool operator!=(ty const & other) const \ - { return s != other(); } \ + { return s.get() != other(); } \ friend void verify(ty &); \ friend void verify_full(ty &); \ friend std::ostream & operator<<(std::ostream &, \ @@ -136,7 +136,7 @@ ty const & ty::operator=(ty const & othe \ std::ostream & operator<<(std::ostream & o,\ ty const & a) \ -{ return (o << a.s); } \ + { return (o << a.s.get()); } \ \ template <> \ void dump(ty const & obj, std::string & out) \ @@ -166,7 +166,7 @@ enc::enc(enc const & other \ template \ enc::enc(enc const & other) \ - : i(other.i()), ok(other.ok) { verify(*this); } \ + : i(other.i), ok(other.ok) { verify(*this); } \ \ template \ enc::enc(INNER const & inner) : \