crimson/onode-staged-tree: support empty ns and oid

Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
This commit is contained in:
Yingxin Cheng 2021-02-07 11:09:14 +08:00
parent 7bafcfbb01
commit 42ae838af5
2 changed files with 47 additions and 32 deletions

View File

@ -128,9 +128,9 @@ inline MatchKindCMP compare_to(const snap_gen_t& l, const snap_gen_t& r) {
* The layout to store char array as an oid or an ns string which may be
* compressed.
*
* If compressed, the physical block only stores an unsigned int of
* string_size_t, with value 0 denoting Type::MIN, and value max() denoting
* Type::MAX.
* (TODO) If compressed, the physical block only stores an unsigned
* int of string_size_t, with value MIN denoting Type::MIN, and value MAX
* denoting Type::MAX.
*
* If not compressed (Type::STR), the physical block stores the char array and
* a valid string_size_t value.
@ -140,9 +140,9 @@ struct string_key_view_t {
// presumably the maximum string length is 2KiB
using string_size_t = uint16_t;
static constexpr auto MAX = std::numeric_limits<string_size_t>::max();
static constexpr auto MIN = string_size_t(0u);
static auto is_valid_size(size_t size) {
return (size > MIN && size < MAX);
static constexpr auto MIN = MAX - 1;
static bool is_valid_size(size_t size) {
return size < MIN;
}
string_key_view_t(const char* p_end) {
@ -326,7 +326,8 @@ inline MatchKindCMP compare_to(const string_view_masked_t& l, const string_view_
auto l_type = l.get_type();
auto r_type = r.get_type();
if (l_type == Type::STR && r_type == Type::STR) {
assert(l.size() && r.size());
assert(string_key_view_t::is_valid_size(l.size()));
assert(string_key_view_t::is_valid_size(r.size()));
return toMatchKindCMP(l.to_string_view(), r.to_string_view());
} else if (l_type == r_type) {
return MatchKindCMP::EQ;
@ -338,14 +339,14 @@ inline MatchKindCMP compare_to(const string_view_masked_t& l, const string_view_
}
inline MatchKindCMP compare_to(std::string_view l, const string_view_masked_t& r) {
using Type = string_view_masked_t::Type;
assert(l.length());
assert(string_key_view_t::is_valid_size(l.size()));
auto r_type = r.get_type();
if (r_type == Type::MIN) {
return MatchKindCMP::GT;
} else if (r_type == Type::MAX) {
return MatchKindCMP::LT;
} else { // r_type == Type::STR
assert(r.size());
assert(string_key_view_t::is_valid_size(r.size()));
return toMatchKindCMP(l, r.to_string_view());
}
}

View File

@ -102,9 +102,9 @@ class Values {
class KVPool {
struct kv_conf_t {
unsigned index2;
unsigned index1;
unsigned index0;
index_t index2;
index_t index1;
index_t index0;
size_t ns_size;
size_t oid_size;
value_item_t value;
@ -112,16 +112,21 @@ class KVPool {
ghobject_t get_ghobj() const {
assert(index1 < 10);
std::ostringstream os_ns;
os_ns << "ns" << index1;
unsigned current_size = (unsigned)os_ns.tellp();
assert(ns_size >= current_size);
os_ns << std::string(ns_size - current_size, '_');
std::ostringstream os_oid;
os_oid << "oid" << index1;
current_size = (unsigned)os_oid.tellp();
assert(oid_size >= current_size);
os_oid << std::string(oid_size - current_size, '_');
if (index1 == 0) {
assert(!ns_size);
assert(!oid_size);
} else {
os_ns << "ns" << index1;
auto current_size = (size_t)os_ns.tellp();
assert(ns_size >= current_size);
os_ns << std::string(ns_size - current_size, '_');
os_oid << "oid" << index1;
current_size = (size_t)os_oid.tellp();
assert(oid_size >= current_size);
os_oid << std::string(oid_size - current_size, '_');
}
return ghobject_t(shard_id_t(index2), index2, index2,
os_ns.str(), os_oid.str(), index0, index0);
@ -134,22 +139,31 @@ class KVPool {
KVPool(const std::vector<size_t>& str_sizes,
const std::vector<size_t>& value_sizes,
const std::pair<unsigned, unsigned>& range2,
const std::pair<unsigned, unsigned>& range1,
const std::pair<unsigned, unsigned>& range0)
const std::pair<index_t, index_t>& range2,
const std::pair<index_t, index_t>& range1,
const std::pair<index_t, index_t>& range0)
: str_sizes{str_sizes}, values{value_sizes} {
ceph_assert(range2.first < range2.second);
ceph_assert(range2.second - 1 <= (unsigned)std::numeric_limits<shard_t>::max());
ceph_assert(range2.second - 1 <= (index_t)std::numeric_limits<shard_t>::max());
ceph_assert(range2.second - 1 <= std::numeric_limits<crush_hash_t>::max());
ceph_assert(range1.first < range1.second);
ceph_assert(range1.second - 1 <= 9);
ceph_assert(range0.first < range0.second);
std::random_device rd;
for (unsigned i = range2.first; i < range2.second; ++i) {
for (unsigned j = range1.first; j < range1.second; ++j) {
auto ns_size = (unsigned)str_sizes[rd() % str_sizes.size()];
auto oid_size = (unsigned)str_sizes[rd() % str_sizes.size()];
for (unsigned k = range0.first; k < range0.second; ++k) {
for (index_t i = range2.first; i < range2.second; ++i) {
for (index_t j = range1.first; j < range1.second; ++j) {
size_t ns_size;
size_t oid_size;
if (j == 0) {
// store ns0, oid0 as empty strings for test purposes
ns_size = 0;
oid_size = 0;
} else {
ns_size = str_sizes[rd() % str_sizes.size()];
oid_size = str_sizes[rd() % str_sizes.size()];
assert(ns_size && oid_size);
}
for (index_t k = range0.first; k < range0.second; ++k) {
kvs.emplace_back(kv_conf_t{i, j, k, ns_size, oid_size, values.pick()});
}
}
@ -172,7 +186,7 @@ class KVPool {
return std::make_pair(conf.get_ghobj(), conf.value);
}
bool is_end() const { return !p_kvs || i >= p_kvs->size(); }
size_t index() const { return i; }
index_t index() const { return i; }
iterator_t& operator++() {
assert(!is_end());
@ -190,7 +204,7 @@ class KVPool {
iterator_t(const kv_vector_t& kvs) : p_kvs{&kvs} {}
const kv_vector_t* p_kvs = nullptr;
size_t i = 0;
index_t i = 0;
friend class KVPool;
};