From 95e885e5f989b86a701be0b7704edd266280a505 Mon Sep 17 00:00:00 2001 From: Igor Podoski Date: Mon, 9 Nov 2015 14:33:10 +0100 Subject: [PATCH] Reduce string use in coll_t::calc_str() 1. Reduce string use. 2. Speedup dec and hex to char conversion. Signed-off-by: Igor Podoski --- src/osd/osd_types.cc | 67 +++++++++++++++++++++++++++++++++++-------- src/osd/osd_types.h | 26 ++++++++++++++--- src/test/osd/types.cc | 19 ++++++++++++ 3 files changed, 96 insertions(+), 16 deletions(-) diff --git a/src/osd/osd_types.cc b/src/osd/osd_types.cc index adaf8b3da92..f3e3b085075 100644 --- a/src/osd/osd_types.cc +++ b/src/osd/osd_types.cc @@ -121,6 +121,22 @@ string ceph_osd_op_flag_string(unsigned flags) return string("-"); } +const char *num_char_map = "0123456789abcdef"; +template +static inline +char* ritoa(T u, char *buf) { + if (u < base) { + *--buf = num_char_map[u]; + return buf; + } + + while (u) { + *--buf = num_char_map[u % base]; + u /= base; + } + return buf; +} + void pg_shard_t::encode(bufferlist &bl) const { ENCODE_START(1, 1, bl); @@ -441,11 +457,24 @@ bool spg_t::parse(const char *s) return true; } +char *spg_t::calc_name(char *buf, const char *suffix_backwords) const +{ + while (*suffix_backwords) + *--buf = *suffix_backwords++; + + if (!is_no_shard()) { + buf = ritoa(shard.id, buf); + *--buf = 's'; + } + + return pgid.calc_name(buf, ""); +} + ostream& operator<<(ostream& out, const spg_t &pg) { - out << pg.pgid; - if (!pg.is_no_shard()) - out << "s" << (unsigned)pg.shard; + char buf[spg_t::calc_name_buf_size]; + buf[spg_t::calc_name_buf_size - 1] = '\0'; + out << pg.calc_name(buf + spg_t::calc_name_buf_size - 1, ""); return out; } @@ -561,15 +590,26 @@ void pg_t::generate_test_instances(list& o) o.push_back(new pg_t(131223, 4, 23)); } -ostream& operator<<(ostream& out, const pg_t &pg) +char *pg_t::calc_name(char *buf, const char *suffix_backwords) const { - out << pg.pool() << '.'; - out << hex << pg.ps() << dec; + while (*suffix_backwords) + *--buf = *suffix_backwords++; + + if (m_preferred >= 0) + *--buf ='p'; + + buf = ritoa(m_seed, buf); - if (pg.preferred() >= 0) - out << 'p' << pg.preferred(); + *--buf = '.'; - //out << "=" << hex << (__uint64_t)pg << dec; + return ritoa(m_pool, buf); +} + +ostream& operator<<(ostream& out, const pg_t &pg) +{ + char buf[pg_t::calc_name_buf_size]; + buf[pg_t::calc_name_buf_size - 1] = '\0'; + out << pg.calc_name(buf + pg_t::calc_name_buf_size - 1, ""); return out; } @@ -580,13 +620,16 @@ void coll_t::calc_str() { switch (type) { case TYPE_META: - _str = "meta"; + strcpy(_str_buff, "meta"); + _str = _str_buff; break; case TYPE_PG: - _str = stringify(pgid) + "_head"; + _str_buff[spg_t::calc_name_buf_size - 1] = '\0'; + _str = pgid.calc_name(_str_buff + spg_t::calc_name_buf_size - 1, "daeh_"); break; case TYPE_PG_TEMP: - _str = stringify(pgid) + "_TEMP"; + _str_buff[spg_t::calc_name_buf_size - 1] = '\0'; + _str = pgid.calc_name(_str_buff + spg_t::calc_name_buf_size - 1, "PMET_"); break; default: assert(0 == "unknown collection type"); diff --git a/src/osd/osd_types.h b/src/osd/osd_types.h index b3a5a384040..f4fdc6a8078 100644 --- a/src/osd/osd_types.h +++ b/src/osd/osd_types.h @@ -328,6 +328,9 @@ struct pg_t { return m_preferred; } + static const uint8_t calc_name_buf_size = 36; // max length for max values len("18446744073709551615.ffffffff") + future suffix len("_head") + '\0' + char *calc_name(char *buf, const char *suffix_backwords) const; + void set_ps(ps_t p) { m_seed = p; } @@ -448,6 +451,10 @@ struct spg_t { int32_t preferred() const { return pgid.preferred(); } + + static const uint8_t calc_name_buf_size = pg_t::calc_name_buf_size + 4; // 36 + len('s') + len("255"); + char *calc_name(char *buf, const char *suffix_backwords) const; + bool parse(const char *s); bool parse(const std::string& s) { return parse(s.c_str()); @@ -523,7 +530,8 @@ class coll_t { spg_t pgid; uint64_t removal_seq; // note: deprecated, not encoded - string _str; // cached string + char _str_buff[spg_t::calc_name_buf_size]; + char *_str; void calc_str(); @@ -549,6 +557,15 @@ public: calc_str(); } + coll_t& operator=(const coll_t& rhs) + { + this->type = rhs.type; + this->pgid = rhs.pgid; + this->removal_seq = rhs.removal_seq; + this->calc_str(); + return *this; + } + // named constructors static coll_t meta() { return coll_t(); @@ -557,12 +574,13 @@ public: return coll_t(p); } - const std::string& to_str() const { - return _str; + const std::string to_str() const { + return string(_str); } const char *c_str() const { - return _str.c_str(); + return _str; } + bool parse(const std::string& s); int operator<(const coll_t &rhs) const { diff --git a/src/test/osd/types.cc b/src/test/osd/types.cc index c28ed0df05a..04743045299 100644 --- a/src/test/osd/types.cc +++ b/src/test/osd/types.cc @@ -1372,6 +1372,25 @@ TEST(coll_t, temp) { ASSERT_EQ(pgid, pgid2); } +TEST(coll_t, assigment) { + spg_t pgid; + coll_t right(pgid); + ASSERT_EQ(right.to_str(), string("0.0_head")); + + coll_t left, middle; + + ASSERT_EQ(left.to_str(), string("meta")); + ASSERT_EQ(middle.to_str(), string("meta")); + + left = middle = right; + + ASSERT_EQ(left.to_str(), string("0.0_head")); + ASSERT_EQ(middle.to_str(), string("0.0_head")); + + ASSERT_NE(middle.c_str(), right.c_str()); + ASSERT_NE(left.c_str(), middle.c_str()); +} + TEST(ghobject_t, cmp) { ghobject_t min; ghobject_t sep; -- 2.47.3