# # # patch "ChangeLog" # from [a27f617a57fa0b5b988daeb5da4ff36fa380bb48] # to [16b731037f6777690487f049aecf18433464010c] # # patch "NEWS" # from [b1818f6d7724208e8964ecece0747e8a6fc4f134] # to [8a22696a8b20242598eb23e86473d7f9a0a77469] # # patch "sanity.cc" # from [e20f5573026da8b26fdbabd38e2ff3c052bfe6e7] # to [8f3a76c6b8fb31c61d396288e92de81edbea655f] # # patch "sanity.hh" # from [53c9635abadc5a4f853ef12419ccc110c30212e6] # to [c812da629224b2ebf80e0f576f6dee8aeb7afd2c] # ============================================================ --- ChangeLog a27f617a57fa0b5b988daeb5da4ff36fa380bb48 +++ ChangeLog 16b731037f6777690487f049aecf18433464010c @@ -1,3 +1,8 @@ +2006-06-05 Graydon Hoare + + * sanity.{cc,hh}: Specialize formatters to number types. + * NEWS: Mention some optimizations. + 2006-06-05 Matt Johnston * NEWS: fix ssh:// syntax to match what works ============================================================ --- NEWS b1818f6d7724208e8964ecece0747e8a6fc4f134 +++ NEWS 8a22696a8b20242598eb23e86473d7f9a0a77469 @@ -39,6 +39,10 @@ - Bug in select() loop fixed, server should no longer pause in processing other clients while busy with one, but multiplex fairly. + - The database has a new write buffer which gives significant + speed improvements in initial pulls by cancelling redundant + database writes. + - There's been a fair bit of performance tuning all around. Bug fixes: ============================================================ --- sanity.cc e20f5573026da8b26fdbabd38e2ff3c052bfe6e7 +++ sanity.cc 8f3a76c6b8fb31c61d396288e92de81edbea655f @@ -420,18 +420,31 @@ {} ostream & -format_base::get_stream() +format_base::get_stream() const { return pimpl->oss; } void -format_base::flush() +format_base::flush_stream() const { pimpl->fmt % pimpl->oss.str(); pimpl->oss.str(string()); } +void format_base::put_and_flush_signed(int64_t const & s) const { pimpl->fmt % s; } +void format_base::put_and_flush_signed(int32_t const & s) const { pimpl->fmt % s; } +void format_base::put_and_flush_signed(int16_t const & s) const { pimpl->fmt % s; } +void format_base::put_and_flush_signed(int8_t const & s) const { pimpl->fmt % s; } + +void format_base::put_and_flush_unsigned(uint64_t const & u) const { pimpl->fmt % u; } +void format_base::put_and_flush_unsigned(uint32_t const & u) const { pimpl->fmt % u; } +void format_base::put_and_flush_unsigned(uint16_t const & u) const { pimpl->fmt % u; } +void format_base::put_and_flush_unsigned(uint8_t const & u) const { pimpl->fmt % u; } + +void format_base::put_and_flush_float(float const & f) const { pimpl->fmt % f; } +void format_base::put_and_flush_double(double const & d) const { pimpl->fmt % d; } + std::string format_base::str() const { ============================================================ --- sanity.hh 53c9635abadc5a4f853ef12419ccc110c30212e6 +++ sanity.hh c812da629224b2ebf80e0f576f6dee8aeb7afd2c @@ -21,6 +21,7 @@ #include "boost/current_function.hpp" #include "i18n.h" +#include "mt-stdint.h" #include "paths.hh" #include "quick_alloc.hh" // to get the QA() macro @@ -117,10 +118,22 @@ explicit format_base(std::string const & pattern); explicit format_base(char const * pattern, std::locale const & loc); explicit format_base(std::string const & pattern, std::locale const & loc); - std::ostream & get_stream(); - void flush(); +public: + // It is a lie that these are const; but then, everything about this + // class is a lie. + std::ostream & get_stream() const; + void flush_stream() const; + void put_and_flush_signed(int64_t const & s) const; + void put_and_flush_signed(int32_t const & s) const; + void put_and_flush_signed(int16_t const & s) const; + void put_and_flush_signed(int8_t const & s) const; + void put_and_flush_unsigned(uint64_t const & u) const; + void put_and_flush_unsigned(uint32_t const & u) const; + void put_and_flush_unsigned(uint16_t const & u) const; + void put_and_flush_unsigned(uint8_t const & u) const; + void put_and_flush_float(float const & f) const; + void put_and_flush_double(double const & d) const; -public: std::string str() const; }; @@ -139,23 +152,68 @@ explicit plain_format(std::string const & pattern) : format_base(pattern) {} +}; - template plain_format & operator %(T const & t) - { - get_stream() << t; - flush(); - return *this; - } +template inline plain_format const & +operator %(plain_format const & f, T const & t) +{ + f.get_stream() << t; + f.flush_stream(); + return f; +} - template plain_format & operator %(T & t) - { - get_stream() << t; - flush(); - return *this; - } -}; +template inline plain_format const & +operator %(const plain_format & f, T & t) +{ + f.get_stream() << t; + f.flush_stream(); + return f; +} +template inline plain_format & +operator %(plain_format & f, T const & t) +{ + f.get_stream() << t; + f.flush_stream(); + return f; +} +template inline plain_format & +operator %(plain_format & f, T & t) +{ + f.get_stream() << t; + f.flush_stream(); + return f; +} + +#define SPECIALIZED_OP(format_ty, specialize_arg_ty, overload_arg_ty, s) \ +template <> inline format_ty & \ +operator %(format_ty & f, overload_arg_ty & a) \ +{ \ + f.put_and_flush_ ## s (a); \ + return f; \ +} + +#define ALL_CONST_VARIANTS(fmt_ty, arg_ty, stem) \ +SPECIALIZED_OP( fmt_ty, arg_ty, arg_ty, stem) \ +SPECIALIZED_OP( fmt_ty, arg_ty, const arg_ty, stem) \ +SPECIALIZED_OP(const fmt_ty, arg_ty, arg_ty, stem) \ +SPECIALIZED_OP(const fmt_ty, arg_ty, const arg_ty, stem) + +ALL_CONST_VARIANTS(plain_format, int64_t, signed) +ALL_CONST_VARIANTS(plain_format, int32_t, signed) +ALL_CONST_VARIANTS(plain_format, int16_t, signed) +ALL_CONST_VARIANTS(plain_format, int8_t, signed) + +ALL_CONST_VARIANTS(plain_format, uint64_t, unsigned) +ALL_CONST_VARIANTS(plain_format, uint32_t, unsigned) +ALL_CONST_VARIANTS(plain_format, uint16_t, unsigned) +ALL_CONST_VARIANTS(plain_format, uint8_t, unsigned) + +ALL_CONST_VARIANTS(plain_format, float, float) +ALL_CONST_VARIANTS(plain_format, double, double) + + struct i18n_format : public format_base @@ -163,22 +221,56 @@ i18n_format() {} explicit i18n_format(const char * localized_pattern); explicit i18n_format(std::string const & localized_pattern); +}; - template i18n_format & operator%(T const & t) - { - get_stream() << t; - flush(); - return *this; - } +template inline i18n_format const & +operator %(i18n_format const & f, T const & t) +{ + f.get_stream() << t; + f.flush_stream(); + return f; +} - template i18n_format & operator%(T & t) - { - get_stream() << t; - flush(); - return *this; - } -}; +template inline i18n_format const & +operator %(i18n_format const & f, T & t) +{ + f.get_stream() << t; + f.flush_stream(); + return f; +} +template inline i18n_format & +operator %(i18n_format & f, T const & t) +{ + f.get_stream() << t; + f.flush_stream(); + return f; +} + +template inline i18n_format & +operator %(i18n_format & f, T & t) +{ + f.get_stream() << t; + f.flush_stream(); + return f; +} + +ALL_CONST_VARIANTS(i18n_format, int64_t, signed) +ALL_CONST_VARIANTS(i18n_format, int32_t, signed) +ALL_CONST_VARIANTS(i18n_format, int16_t, signed) +ALL_CONST_VARIANTS(i18n_format, int8_t, signed) + +ALL_CONST_VARIANTS(i18n_format, uint64_t, unsigned) +ALL_CONST_VARIANTS(i18n_format, uint32_t, unsigned) +ALL_CONST_VARIANTS(i18n_format, uint16_t, unsigned) +ALL_CONST_VARIANTS(i18n_format, uint8_t, unsigned) + +ALL_CONST_VARIANTS(i18n_format, float, float) +ALL_CONST_VARIANTS(i18n_format, double, double) + +#undef ALL_CONST_VARIANTS +#undef SPECIALIZED_OP + std::ostream & operator<<(std::ostream & os, format_base const & fmt); // F is for when you want to build a boost formatter for display