Skip to content

Commit 78c579b

Browse files
authored
Merge pull request ceph#49438 from cfsnyder/wip-58274-bluestore-collection-list-bounds
os/bluestore: set rocksdb iterator bounds for Bluestore::_collection_list() Reviewed-by: Igor Fedotov <[email protected]> Reviewed-by: Adam Kupczyk <[email protected]>
2 parents 53a541c + a6bcb57 commit 78c579b

File tree

1 file changed

+46
-71
lines changed

1 file changed

+46
-71
lines changed

src/os/bluestore/BlueStore.cc

Lines changed: 46 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -12676,16 +12676,14 @@ int BlueStore::_collection_list(
1267612676
Collection *c, const ghobject_t& start, const ghobject_t& end, int max,
1267712677
bool legacy, vector<ghobject_t> *ls, ghobject_t *pnext)
1267812678
{
12679-
1268012679
if (!c->exists)
1268112680
return -ENOENT;
1268212681

1268312682
ghobject_t static_next;
1268412683
std::unique_ptr<CollectionListIterator> it;
1268512684
ghobject_t coll_range_temp_start, coll_range_temp_end;
1268612685
ghobject_t coll_range_start, coll_range_end;
12687-
ghobject_t pend;
12688-
bool temp;
12686+
std::vector<std::tuple<ghobject_t, ghobject_t>> ranges;
1268912687

1269012688
if (!pnext)
1269112689
pnext = &static_next;
@@ -12719,82 +12717,59 @@ int BlueStore::_collection_list(
1271912717
<< " and " << coll_range_start
1272012718
<< " to " << coll_range_end
1272112719
<< " start " << start << dendl;
12722-
if (legacy) {
12723-
it = std::make_unique<SimpleCollectionListIterator>(
12724-
cct, db->get_iterator(PREFIX_OBJ));
12725-
} else {
12726-
it = std::make_unique<SortedCollectionListIterator>(
12727-
db->get_iterator(PREFIX_OBJ));
12728-
}
12729-
if (start == ghobject_t() ||
12730-
start.hobj == hobject_t() ||
12731-
start == c->cid.get_min_hobj()) {
12732-
it->upper_bound(coll_range_temp_start);
12733-
temp = true;
12734-
} else {
12735-
if (start.hobj.is_temp()) {
12736-
temp = true;
12737-
ceph_assert(start >= coll_range_temp_start && start < coll_range_temp_end);
12738-
} else {
12739-
temp = false;
12740-
ceph_assert(start >= coll_range_start && start < coll_range_end);
12741-
}
12742-
dout(20) << __func__ << " temp=" << (int)temp << dendl;
12743-
it->lower_bound(start);
12720+
12721+
// if specified start is not specifically in the pg normal range, we should start with temp iter
12722+
if ((start == ghobject_t() ||
12723+
start.hobj == hobject_t() ||
12724+
start == c->cid.get_min_hobj() ||
12725+
start.hobj.is_temp())
12726+
&& coll_range_temp_start != coll_range_temp_end) {
12727+
ranges.push_back(std::tuple(std::move(coll_range_temp_start), std::move(coll_range_temp_end)));
1274412728
}
12745-
if (end.hobj.is_max()) {
12746-
pend = temp ? coll_range_temp_end : coll_range_end;
12747-
} else {
12748-
if (end.hobj.is_temp()) {
12749-
if (temp) {
12750-
pend = end;
12751-
} else {
12752-
*pnext = ghobject_t::get_max();
12753-
return 0;
12754-
}
12729+
// if end param is in temp section, then we do not need to proceed to the normal section
12730+
if (!end.hobj.is_temp()) {
12731+
ranges.push_back(std::tuple(std::move(coll_range_start), std::move(coll_range_end)));
12732+
}
12733+
12734+
for (const auto & [cur_range_start, cur_range_end] : ranges) {
12735+
dout(30) << __func__ << " cur_range " << cur_range_start << " to " << cur_range_end << dendl;
12736+
12737+
const ghobject_t low = start > cur_range_start ? start : cur_range_start;
12738+
const ghobject_t high = end < cur_range_end ? end : cur_range_end;
12739+
if (low >= high) {
12740+
continue;
12741+
}
12742+
12743+
std::string kv_low_key, kv_high_key;
12744+
_key_encode_prefix(low, &kv_low_key);
12745+
_key_encode_prefix(high, &kv_high_key);
12746+
kv_high_key.push_back('\xff');
12747+
dout(30) << __func__ << " kv_low_key: " << kv_low_key << " kv_high_key: " << kv_high_key << dendl;
12748+
const KeyValueDB::IteratorBounds bounds = KeyValueDB::IteratorBounds{std::move(kv_low_key), std::move(kv_high_key)};
12749+
if (legacy) {
12750+
it = std::make_unique<SimpleCollectionListIterator>(
12751+
cct, db->get_iterator(PREFIX_OBJ, 0, std::move(bounds)));
1275512752
} else {
12756-
pend = temp ? coll_range_temp_end : end;
12753+
it = std::make_unique<SortedCollectionListIterator>(
12754+
db->get_iterator(PREFIX_OBJ, 0, std::move(bounds)));
1275712755
}
12758-
}
12759-
dout(20) << __func__ << " pend " << pend << dendl;
12760-
while (true) {
12761-
if (!it->valid() || it->is_ge(pend)) {
12762-
if (!it->valid())
12763-
dout(20) << __func__ << " iterator not valid (end of db?)" << dendl;
12764-
else
12765-
dout(20) << __func__ << " oid " << it->oid() << " >= " << pend << dendl;
12766-
if (temp) {
12767-
if (end.hobj.is_temp()) {
12768-
if (it->valid() && it->is_lt(coll_range_temp_end)) {
12769-
*pnext = it->oid();
12770-
return 0;
12771-
}
12772-
break;
12773-
}
12774-
dout(30) << __func__ << " switch to non-temp namespace" << dendl;
12775-
temp = false;
12776-
it->upper_bound(coll_range_start);
12777-
if (end.hobj.is_max())
12778-
pend = coll_range_end;
12779-
else
12780-
pend = end;
12781-
dout(30) << __func__ << " pend " << pend << dendl;
12782-
continue;
12756+
it->lower_bound(low);
12757+
while (it->valid()) {
12758+
if (it->oid() < low) {
12759+
it->next();
12760+
continue;
12761+
}
12762+
if (it->oid() > high) {
12763+
break;
1278312764
}
12784-
if (it->valid() && it->is_lt(coll_range_end)) {
12765+
if (ls->size() >= (unsigned)max || it->oid() == high) {
1278512766
*pnext = it->oid();
1278612767
return 0;
1278712768
}
12788-
break;
12789-
}
12790-
dout(20) << __func__ << " oid " << it->oid() << " end " << end << dendl;
12791-
if (ls->size() >= (unsigned)max) {
12792-
dout(20) << __func__ << " reached max " << max << dendl;
12793-
*pnext = it->oid();
12794-
return 0;
12769+
dout(20) << __func__ << " oid " << it->oid() << dendl;
12770+
ls->push_back(it->oid());
12771+
it->next();
1279512772
}
12796-
ls->push_back(it->oid());
12797-
it->next();
1279812773
}
1279912774
*pnext = ghobject_t::get_max();
1280012775
return 0;

0 commit comments

Comments
 (0)