From 03e53308442ed6de6b0ae447f14dd5c604e5a9d7 Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Fri, 1 Mar 2013 16:04:04 -0800 Subject: [PATCH] DBObjectMap, hobject: add helpers for pgid bit matching Create helpers in hobject for generating prefixes for a pg as well as matching hobjects against a pgid/numpgs combo. Use these in HashIndex.cc. Signed-off-by: Samuel Just --- src/os/HashIndex.cc | 6 +-- src/os/hobject.cc | 99 ++++++++++++++++++++++++++++++++++++++ src/os/hobject.h | 27 ++++++++++- src/test/test_osd_types.cc | 94 ++++++++++++++++++++++++++++++++++++ 4 files changed, 222 insertions(+), 4 deletions(-) diff --git a/src/os/HashIndex.cc b/src/os/HashIndex.cc index b3902b056a55d..d5f2d74080c57 100644 --- a/src/os/HashIndex.cc +++ b/src/os/HashIndex.cc @@ -113,7 +113,7 @@ int HashIndex::col_split_level( sub_path.push_back(*i); path_to_hobject_hash_prefix(sub_path, &bits, &hash); if (bits < inbits) { - if ((match & ~((~0)<::iterator i = objects.begin(); i != objects.end(); ++i) { - if ((i->second.hash & ~((~0)<second.match(inbits, match)) { objs_to_move.insert(*i); } } diff --git a/src/os/hobject.cc b/src/os/hobject.cc index 0134b30ebd1d6..1387a0ce280bf 100644 --- a/src/os/hobject.cc +++ b/src/os/hobject.cc @@ -1,8 +1,107 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab #include "include/types.h" #include "hobject.h" #include "common/Formatter.h" +static void append_escaped(const string &in, string *out) +{ + for (string::const_iterator i = in.begin(); i != in.end(); ++i) { + if (*i == '%') { + out->push_back('%'); + out->push_back('p'); + } else if (*i == '.') { + out->push_back('%'); + out->push_back('e'); + } else if (*i == '_') { + out->push_back('%'); + out->push_back('u'); + } else { + out->push_back(*i); + } + } +} + +set hobject_t::get_prefixes( + uint32_t bits, + uint32_t mask, + int64_t pool) +{ + uint32_t len = bits; + while (len % 4 /* nibbles */) len++; + + set from; + if (bits < 32) + from.insert(mask & ~((uint32_t)(~0) << bits)); + else if (bits == 32) + from.insert(mask); + else + assert(0); + + + set to; + for (uint32_t i = bits; i < len; ++i) { + for (set::iterator j = from.begin(); + j != from.end(); + ++j) { + to.insert(*j | (1 << i)); + to.insert(*j); + } + to.swap(from); + to.clear(); + } + + char buf[20]; + char *t = buf; + uint64_t poolid(pool); + t += snprintf(t, sizeof(buf), "%.*lX", 16, poolid); + *(t++) = '.'; + string poolstr(buf, t - buf); + set ret; + for (set::iterator i = from.begin(); + i != from.end(); + ++i) { + uint32_t revhash(hobject_t::_reverse_nibbles(*i)); + snprintf(buf, sizeof(buf), "%.*X", (int)(sizeof(revhash))*2, revhash); + ret.insert(poolstr + string(buf, len/4)); + } + return ret; +} + +string hobject_t::to_str() const +{ + string out; + + char snap_with_hash[1000]; + char *t = snap_with_hash; + char *end = t + sizeof(snap_with_hash); + + uint64_t poolid(pool); + t += snprintf(t, end - t, "%.*lX", 16, poolid); + + uint32_t revhash(get_filestore_key_u32()); + t += snprintf(t, end - t, ".%.*X", 8, revhash); + + if (snap == CEPH_NOSNAP) + t += snprintf(t, end - t, ".head"); + else if (snap == CEPH_SNAPDIR) + t += snprintf(t, end - t, ".snapdir"); + else + t += snprintf(t, end - t, ".%llx", (long long unsigned)snap); + + out += string(snap_with_hash); + + out.push_back('.'); + append_escaped(oid.name, &out); + out.push_back('.'); + append_escaped(get_key(), &out); + out.push_back('.'); + append_escaped(nspace, &out); + + return out; +} + void hobject_t::encode(bufferlist& bl) const { ENCODE_START(4, 3, bl); diff --git a/src/os/hobject.h b/src/os/hobject.h index d75ae8570c4df..28e0da0d82a04 100644 --- a/src/os/hobject.h +++ b/src/os/hobject.h @@ -44,6 +44,15 @@ public: const string &get_key() const { return key; } + + string to_str() const; + + static bool match_hash(uint32_t to_check, uint32_t bits, uint32_t match) { + return (match & ~((~0)< get_prefixes( + uint32_t bits, + uint32_t mask, + int64_t pool); + + filestore_hobject_key_t get_filestore_key_u32() const { + assert(!max); + return _reverse_nibbles(hash); + } filestore_hobject_key_t get_filestore_key() const { if (max) return 0x100000000ull; else - return _reverse_nibbles(hash); + return get_filestore_key_u32(); } void set_filestore_key(uint32_t v) { hash = _reverse_nibbles(v); diff --git a/src/test/test_osd_types.cc b/src/test/test_osd_types.cc index 4ee1a1404cc0f..b696ace3ac2cd 100644 --- a/src/test/test_osd_types.cc +++ b/src/test/test_osd_types.cc @@ -18,6 +18,100 @@ #include +TEST(hobject, prefixes0) +{ + uint32_t mask = 0xE947FA20; + uint32_t bits = 12; + int64_t pool = 0; + + set prefixes_correct; + prefixes_correct.insert(string("0000000000000000.02A")); + + set prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); + ASSERT_EQ(prefixes_out, prefixes_correct); +} + +TEST(hobject, prefixes1) +{ + uint32_t mask = 0x0000000F; + uint32_t bits = 6; + int64_t pool = 20; + + set prefixes_correct; + prefixes_correct.insert(string("0000000000000014.F0")); + prefixes_correct.insert(string("0000000000000014.F4")); + prefixes_correct.insert(string("0000000000000014.F8")); + prefixes_correct.insert(string("0000000000000014.FC")); + + set prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); + ASSERT_EQ(prefixes_out, prefixes_correct); +} + +TEST(hobject, prefixes2) +{ + uint32_t mask = 0xDEADBEAF; + uint32_t bits = 25; + int64_t pool = 0; + + set prefixes_correct; + prefixes_correct.insert(string("0000000000000000.FAEBDA0")); + prefixes_correct.insert(string("0000000000000000.FAEBDA2")); + prefixes_correct.insert(string("0000000000000000.FAEBDA4")); + prefixes_correct.insert(string("0000000000000000.FAEBDA6")); + prefixes_correct.insert(string("0000000000000000.FAEBDA8")); + prefixes_correct.insert(string("0000000000000000.FAEBDAA")); + prefixes_correct.insert(string("0000000000000000.FAEBDAC")); + prefixes_correct.insert(string("0000000000000000.FAEBDAE")); + + set prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); + ASSERT_EQ(prefixes_out, prefixes_correct); +} + +TEST(hobject, prefixes3) +{ + uint32_t mask = 0xE947FA20; + uint32_t bits = 32; + int64_t pool = 0x23; + + set prefixes_correct; + prefixes_correct.insert(string("0000000000000023.02AF749E")); + + set prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); + ASSERT_EQ(prefixes_out, prefixes_correct); +} + +TEST(hobject, prefixes4) +{ + uint32_t mask = 0xE947FA20; + uint32_t bits = 0; + int64_t pool = 0x23; + + set prefixes_correct; + prefixes_correct.insert(string("0000000000000023.")); + + set prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); + ASSERT_EQ(prefixes_out, prefixes_correct); +} + +TEST(hobject, prefixes5) +{ + uint32_t mask = 0xDEADBEAF; + uint32_t bits = 1; + int64_t pool = 0x34AC5D00; + + set prefixes_correct; + prefixes_correct.insert(string("0000000034AC5D00.1")); + prefixes_correct.insert(string("0000000034AC5D00.3")); + prefixes_correct.insert(string("0000000034AC5D00.5")); + prefixes_correct.insert(string("0000000034AC5D00.7")); + prefixes_correct.insert(string("0000000034AC5D00.9")); + prefixes_correct.insert(string("0000000034AC5D00.B")); + prefixes_correct.insert(string("0000000034AC5D00.D")); + prefixes_correct.insert(string("0000000034AC5D00.F")); + + set prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); + ASSERT_EQ(prefixes_out, prefixes_correct); +} TEST(pg_t, split) { -- 2.39.5