@@ -424,11 +424,13 @@ class TPipeline : TNonCopyable {
424
424
ui64 Step;
425
425
ui64 TxId;
426
426
mutable ui32 Counter;
427
+ mutable ui32 TxCounter;
427
428
428
429
TItem (const TRowVersion& from)
429
430
: Step(from.Step)
430
431
, TxId(from.TxId)
431
432
, Counter(1u )
433
+ , TxCounter(0u )
432
434
{}
433
435
434
436
friend constexpr bool operator <(const TItem& a, const TItem& b) {
@@ -442,6 +444,7 @@ class TPipeline : TNonCopyable {
442
444
443
445
using TItemsSet = TSet<TItem>;
444
446
using TTxIdMap = THashMap<ui64, TItemsSet::iterator>;
447
+
445
448
public:
446
449
inline void Add (ui64 txId, TRowVersion version) {
447
450
auto res = ItemsSet.emplace (version);
@@ -450,6 +453,7 @@ class TPipeline : TNonCopyable {
450
453
auto res2 = TxIdMap.emplace (txId, res.first );
451
454
Y_VERIFY_S (res2.second , " Unexpected duplicate immediate tx " << txId
452
455
<< " committing at " << version);
456
+ res.first ->TxCounter += 1 ;
453
457
}
454
458
455
459
inline void Add (TRowVersion version) {
@@ -458,17 +462,29 @@ class TPipeline : TNonCopyable {
458
462
res.first ->Counter += 1 ;
459
463
}
460
464
461
- inline void Remove (ui64 txId) {
462
- if (auto it = TxIdMap.find (txId); it != TxIdMap.end ()) {
463
- if (--it->second ->Counter == 0 )
464
- ItemsSet.erase (it->second );
465
- TxIdMap.erase (it);
466
- }
465
+ inline void Remove (ui64 txId, TRowVersion version) {
466
+ auto it = TxIdMap.find (txId);
467
+ Y_VERIFY_S (it != TxIdMap.end (), " Removing immediate tx " << txId << " " << version
468
+ << " does not match a previous Add" );
469
+ Y_VERIFY_S (TRowVersion (it->second ->Step , it->second ->TxId ) == version, " Removing immediate tx " << txId << " " << version
470
+ << " does not match a previous Add " << TRowVersion (it->second ->Step , it->second ->TxId ));
471
+ Y_VERIFY_S (it->second ->TxCounter > 0 , " Removing immediate tx " << txId << " " << version
472
+ << " with a mismatching TxCounter" );
473
+ --it->second ->TxCounter ;
474
+ if (--it->second ->Counter == 0 )
475
+ ItemsSet.erase (it->second );
476
+ TxIdMap.erase (it);
467
477
}
468
478
469
479
inline void Remove (TRowVersion version) {
470
- if (auto it = ItemsSet.find (version); it != ItemsSet.end () && --it->Counter == 0 )
480
+ auto it = ItemsSet.find (version);
481
+ Y_VERIFY_S (it != ItemsSet.end (), " Removing version " << version
482
+ << " does not match a previous Add" );
483
+ if (--it->Counter == 0 ) {
484
+ Y_VERIFY_S (it->TxCounter == 0 , " Removing version " << version
485
+ << " while TxCounter has active references, possible Add/Remove mismatch" );
471
486
ItemsSet.erase (it);
487
+ }
472
488
}
473
489
474
490
inline bool HasOpsBelow (TRowVersion upperBound) const {
0 commit comments