@@ -126,6 +126,7 @@ class Transaction {
126126 add_present_to_retired_set (ref);
127127 }
128128
129+ using extent_cmp_t = read_set_item_t <Transaction>::extent_cmp_t ;
129130 void add_present_to_retired_set (CachedExtentRef ref) {
130131 assert (ref->get_paddr ().is_real_location ());
131132 assert (!is_weak ());
@@ -147,7 +148,7 @@ class Transaction {
147148 write_set.erase (*ref);
148149 assert (ref->prior_instance );
149150 retired_set.emplace (ref->prior_instance , trans_id);
150- assert (read_set.count (ref->prior_instance ->get_paddr ()));
151+ assert (read_set.count (ref->prior_instance ->get_paddr (), extent_cmp_t {} ));
151152 ref->prior_instance .reset ();
152153 } else {
153154 // && retired_set.count(ref->get_paddr()) == 0
@@ -269,7 +270,7 @@ class Transaction {
269270 assert (ref->get_paddr ().is_absolute () ||
270271 ref->get_paddr ().is_root ());
271272 assert (ref->is_exist_mutation_pending () ||
272- read_set.count (ref->prior_instance ->get_paddr ()));
273+ read_set.count (ref->prior_instance ->get_paddr (), extent_cmp_t {} ));
273274 mutated_block_list.push_back (ref);
274275 if (!ref->is_exist_mutation_pending ()) {
275276 write_set.insert (*ref);
@@ -288,12 +289,19 @@ class Transaction {
288289 assert (extent.get_paddr () == placeholder.get_paddr ());
289290 assert (extent.get_paddr ().is_absolute ());
290291 {
291- auto where = read_set.find (placeholder.get_paddr ());
292+ auto where = read_set.find (placeholder.get_paddr (), extent_cmp_t {} );
292293 assert (where != read_set.end ());
293294 assert (where->ref .get () == &placeholder);
294295 where = read_set.erase (where);
295- auto it = read_set.emplace_hint (where, this , &extent);
296+ placeholder.read_transactions .erase (
297+ read_trans_set_t <Transaction>::s_iterator_to (*where));
298+ // Note, the retired-placeholder is not removed from read_items after replace.
299+ read_items.emplace_back (this , &extent);
300+ auto it = read_set.insert_before (where, read_items.back ());
296301 extent.read_transactions .insert (const_cast <read_set_item_t <Transaction>&>(*it));
302+ #ifndef NDEBUG
303+ num_replace_placeholder++;
304+ #endif
297305 }
298306 {
299307 auto where = retired_set.find (&placeholder);
@@ -428,7 +436,7 @@ class Transaction {
428436 root.reset ();
429437 offset = 0 ;
430438 delayed_temp_offset = 0 ;
431- read_set .clear ();
439+ read_items .clear ();
432440 fresh_backref_extents = 0 ;
433441 invalidate_clear_write_set ();
434442 mutated_block_list.clear ();
@@ -587,7 +595,7 @@ class Transaction {
587595 } else if (retired_set.count (addr)) {
588596 return {get_extent_ret::RETIRED, nullptr };
589597 } else if (
590- auto iter = read_set.find (addr);
598+ auto iter = read_set.find (addr, extent_cmp_t {} );
591599 iter != read_set.end ()) {
592600 auto ret = iter->ref ;
593601 SUBTRACET (seastore_cache, " {} is present in read_set -- {}" ,
@@ -617,7 +625,8 @@ class Transaction {
617625 return false ;
618626 }
619627
620- auto [iter, inserted] = read_set.emplace (this , ref);
628+ read_items.emplace_back (this , ref);
629+ auto [iter, inserted] = read_set.insert (read_items.back ());
621630 ceph_assert (inserted);
622631 ref->read_transactions .insert_before (
623632 it, const_cast <read_set_item_t <Transaction>&>(*iter));
@@ -652,6 +661,10 @@ class Transaction {
652661 * invalidate *this.
653662 */
654663 read_extent_set_t <Transaction> read_set; // /< set of extents read by paddr
664+ std::list<read_set_item_t <Transaction>> read_items;
665+ #ifndef NDEBUG
666+ size_t num_replace_placeholder = 0 ;
667+ #endif
655668
656669 uint64_t fresh_backref_extents = 0 ; // counter of new backref extents
657670
0 commit comments