@@ -355,8 +355,7 @@ TransBuffer::Handle TransBuffer::Get(const Detail::BlockId& blockId, size_t shar
355355 strategy_->BucketUnlock (iBucket);
356356 return Handle{this , iNode, owner};
357357 }
358- iNode = Alloc (blockId, shardIdx);
359- MoveTo (iBucket, iNode);
358+ iNode = Alloc (blockId, shardIdx, iBucket);
360359 strategy_->BucketUnlock (iBucket);
361360 return Handle (this , iNode, true );
362361}
@@ -381,7 +380,7 @@ size_t TransBuffer::FindAt(size_t iBucket, const Detail::BlockId& blockId, size_
381380 return iNode;
382381}
383382
384- size_t TransBuffer::Alloc (const Detail::BlockId& blockId, size_t shardIdx)
383+ size_t TransBuffer::Alloc (const Detail::BlockId& blockId, size_t shardIdx, size_t iBucket )
385384{
386385 for (;;) {
387386 auto iNode = strategy_->FetchNode ();
@@ -395,10 +394,14 @@ size_t TransBuffer::Alloc(const Detail::BlockId& blockId, size_t shardIdx)
395394 meta->block = blockId;
396395 meta->shard = shardIdx;
397396 meta->ready = false ;
398- if (meta->hash != invalidIndex) {
399- strategy_->BucketLock (meta->hash );
400- Remove (iNode);
401- strategy_->BucketUnlock (meta->hash );
397+ const auto oldBucket = meta->hash ;
398+ if (oldBucket != iBucket) {
399+ if (oldBucket != invalidIndex) {
400+ strategy_->BucketLock (oldBucket);
401+ Remove (oldBucket, iNode);
402+ strategy_->BucketUnlock (oldBucket);
403+ }
404+ MoveTo (iBucket, iNode);
402405 }
403406 strategy_->NodeUnlock (iNode);
404407 return iNode;
@@ -417,10 +420,11 @@ void TransBuffer::MoveTo(size_t iBucket, size_t iNode)
417420 next->prev = iNode;
418421 strategy_->NodeUnlock (n);
419422 }
423+ meta->hash = iBucket;
420424 head = iNode;
421425}
422426
423- void TransBuffer::Remove (size_t iNode)
427+ void TransBuffer::Remove (size_t iBucket, size_t iNode)
424428{
425429 auto meta = strategy_->MetaAt (iNode);
426430 auto p = meta->prev ;
@@ -437,7 +441,9 @@ void TransBuffer::Remove(size_t iNode)
437441 next->prev = meta->prev ;
438442 strategy_->NodeUnlock (n);
439443 }
444+ if (strategy_->FirstAt (iBucket) == iNode) { strategy_->FirstAt (iBucket) = n; }
440445 meta->prev = meta->next = invalidIndex;
446+ meta->hash = invalidIndex;
441447}
442448
443449void * TransBuffer::DataAt (Index pos) { return strategy_->DataAt (pos); }
0 commit comments