static void get_coll_range(const coll_t& cid, int bits,
ghobject_t *temp_start, ghobject_t *temp_end,
- ghobject_t *start, ghobject_t *end)
+ ghobject_t *start, ghobject_t *end, bool legacy)
{
spg_t pgid;
+ constexpr uint32_t MAX_HASH = std::numeric_limits<uint32_t>::max();
+ // use different nspaces due to we use different schemes when encoding
+ // keys for listing objects
+ const std::string_view MAX_NSPACE = legacy ? "\x7f" : "\xff";
if (cid.is_pg(&pgid)) {
start->shard_id = pgid.shard;
*temp_start = *start;
temp_start->hobj.set_bitwise_key_u32(reverse_hash);
uint64_t end_hash = reverse_hash + (1ull << (32 - bits));
- if (end_hash > 0xffffffffull)
- end_hash = 0xffffffffull;
-
- end->hobj.set_bitwise_key_u32(end_hash);
- temp_end->hobj.set_bitwise_key_u32(end_hash);
+ if (end_hash > MAX_HASH) {
+ // make sure end hobj is even greater than the maximum possible hobj
+ end->hobj.set_bitwise_key_u32(MAX_HASH);
+ temp_end->hobj.set_bitwise_key_u32(MAX_HASH);
+ end->hobj.nspace = MAX_NSPACE;
+ } else {
+ end->hobj.set_bitwise_key_u32(end_hash);
+ temp_end->hobj.set_bitwise_key_u32(end_hash);
+ }
} else {
start->shard_id = shard_id_t::NO_SHARD;
start->hobj.pool = -1ull;
*end = *start;
start->hobj.set_bitwise_key_u32(0);
- end->hobj.set_bitwise_key_u32(0xffffffff);
-
+ end->hobj.set_bitwise_key_u32(MAX_HASH);
+ end->hobj.nspace = MAX_NSPACE;
// no separate temp section
*temp_start = *end;
*temp_end = *end;
return 0;
}
get_coll_range(c->cid, c->cnode.bits, &coll_range_temp_start,
- &coll_range_temp_end, &coll_range_start, &coll_range_end);
+ &coll_range_temp_end, &coll_range_start, &coll_range_end, legacy);
dout(20) << __func__
<< " range " << coll_range_temp_start
<< " to " << coll_range_temp_end
}
}
+TEST_P(StoreTest, List_0xfffffff_Hash_Test_in_meta) {
+ int r = 0;
+ coll_t cid;
+ auto ch = store->create_new_collection(cid);
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(cid, 0);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ ObjectStore::Transaction t;
+ ghobject_t hoid(hobject_t(sobject_t("obj", CEPH_NOSNAP),
+ "", UINT32_C(0xffffffff), -1, "nspace"));
+ t.touch(cid, hoid);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ vector<ghobject_t> objects;
+ r = collection_list(store, ch, ghobject_t(), ghobject_t::get_max(), INT_MAX,
+ &objects, nullptr, true);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(objects.size(), 1);
+ }
+}
+
+TEST_P(StoreTest, List_0xfffffff_Hash_Test_in_PG) {
+ int r = 0;
+ const int64_t poolid = 1;
+ coll_t cid(spg_t(pg_t(0, poolid), shard_id_t::NO_SHARD));
+ auto ch = store->create_new_collection(cid);
+ {
+ ObjectStore::Transaction t;
+ t.create_collection(cid, 0);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ ObjectStore::Transaction t;
+ ghobject_t hoid(hobject_t(sobject_t("obj", CEPH_NOSNAP),
+ "", UINT32_C(0xffffffff), poolid, "nspace"));
+ t.touch(cid, hoid);
+ r = queue_transaction(store, ch, std::move(t));
+ ASSERT_EQ(r, 0);
+ }
+ {
+ vector<ghobject_t> objects;
+ r = collection_list(store, ch, ghobject_t(), ghobject_t::get_max(), INT_MAX,
+ &objects, nullptr, true);
+ ASSERT_EQ(r, 0);
+ ASSERT_EQ(objects.size(), 1);
+ }
+}
+
TEST_P(StoreTest, Sort) {
{
hobject_t a(sobject_t("a", CEPH_NOSNAP));