@@ -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