This is an automated email from the ASF dual-hosted git repository.

ibessonov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 44e56234ae9 IGNITE-28370 Include partition ID into hash index lock key 
(#7878)
44e56234ae9 is described below

commit 44e56234ae9aca76e4e5e59fa9a189ab117d18ac
Author: Ivan Bessonov <[email protected]>
AuthorDate: Thu Mar 26 13:55:30 2026 +0300

    IGNITE-28370 Include partition ID into hash index lock key (#7878)
    
    Signed-off-by: ibessonov <[email protected]>
---
 .../apache/ignite/internal/table/IndexWrapper.java |  1 +
 .../table/distributed/HashIndexLocker.java         | 16 +++++----
 .../internal/table/distributed/IndexLocker.java    | 38 ++++++++++++++++++++++
 .../table/distributed/SortedIndexLocker.java       | 38 ----------------------
 .../PartitionReplicaListenerIndexLockingTest.java  | 20 +++++++-----
 ...itionReplicaListenerSortedIndexLockingTest.java |  4 +--
 .../replication/PartitionReplicaListenerTest.java  |  4 +--
 .../ZonePartitionReplicaListenerTest.java          |  4 +--
 .../apache/ignite/distributed/ItTxTestCluster.java |  2 +-
 .../table/impl/DummyInternalTableImpl.java         |  2 +-
 10 files changed, 68 insertions(+), 61 deletions(-)

diff --git 
a/modules/table/src/main/java/org/apache/ignite/internal/table/IndexWrapper.java
 
b/modules/table/src/main/java/org/apache/ignite/internal/table/IndexWrapper.java
index 36e84ae7a24..c2e26a38673 100644
--- 
a/modules/table/src/main/java/org/apache/ignite/internal/table/IndexWrapper.java
+++ 
b/modules/table/src/main/java/org/apache/ignite/internal/table/IndexWrapper.java
@@ -126,6 +126,7 @@ abstract class IndexWrapper {
         IndexLocker getLocker(int partitionId) {
             return new HashIndexLocker(
                     indexId,
+                    partitionId,
                     unique,
                     lockManager,
                     indexRowResolver
diff --git 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/HashIndexLocker.java
 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/HashIndexLocker.java
index 1e6c88b8d48..5a53da7c1a8 100644
--- 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/HashIndexLocker.java
+++ 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/HashIndexLocker.java
@@ -34,7 +34,7 @@ import org.apache.ignite.internal.tx.LockMode;
  * <p>Simply acquires lock on a given row.
  */
 public class HashIndexLocker implements IndexLocker {
-    private final int indexId;
+    private final PartitionIndexId contextId;
     private final LockMode modificationMode;
     private final LockManager lockManager;
     private final ColumnsExtractor indexRowResolver;
@@ -43,11 +43,13 @@ public class HashIndexLocker implements IndexLocker {
      * Constructs the object.
      *
      * @param indexId An identifier of the index this locker is created for.
+     * @param partitionId Partition ID.
+     * @param unique Uniqueness flag.
      * @param lockManager A lock manager to acquire locks in.
      * @param indexRowResolver A convertor which derives an index key from 
given table row.
      */
-    public HashIndexLocker(int indexId, boolean unique, LockManager 
lockManager, ColumnsExtractor indexRowResolver) {
-        this.indexId = indexId;
+    public HashIndexLocker(int indexId, int partitionId, boolean unique, 
LockManager lockManager, ColumnsExtractor indexRowResolver) {
+        this.contextId = new PartitionIndexId(partitionId, indexId);
         this.modificationMode = unique ? LockMode.X : LockMode.IX;
         this.lockManager = lockManager;
         this.indexRowResolver = indexRowResolver;
@@ -55,12 +57,12 @@ public class HashIndexLocker implements IndexLocker {
 
     @Override
     public int id() {
-        return indexId;
+        return contextId.indexId;
     }
 
     @Override
     public CompletableFuture<Void> locksForLookupByKey(UUID txId, BinaryTuple 
key) {
-        return lockManager.acquire(txId, new LockKey(indexId, 
key.byteBuffer()), LockMode.S).thenApply(lock -> null);
+        return lockManager.acquire(txId, new LockKey(contextId, 
key.byteBuffer()), LockMode.S).thenApply(lock -> null);
     }
 
     /** {@inheritDoc} */
@@ -76,7 +78,7 @@ public class HashIndexLocker implements IndexLocker {
     public CompletableFuture<Lock> locksForInsert(UUID txId, BinaryRow 
tableRow, RowId rowId) {
         BinaryTuple key = indexRowResolver.extractColumns(tableRow);
 
-        return lockManager.acquire(txId, new LockKey(indexId, 
key.byteBuffer()), modificationMode).thenApply(lock -> null);
+        return lockManager.acquire(txId, new LockKey(contextId, 
key.byteBuffer()), modificationMode).thenApply(lock -> null);
     }
 
     /** {@inheritDoc} */
@@ -84,6 +86,6 @@ public class HashIndexLocker implements IndexLocker {
     public CompletableFuture<Void> locksForRemove(UUID txId, BinaryRow 
tableRow, RowId rowId) {
         BinaryTuple key = indexRowResolver.extractColumns(tableRow);
 
-        return lockManager.acquire(txId, new LockKey(indexId, 
key.byteBuffer()), modificationMode).thenApply(lock -> null);
+        return lockManager.acquire(txId, new LockKey(contextId, 
key.byteBuffer()), modificationMode).thenApply(lock -> null);
     }
 }
diff --git 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/IndexLocker.java
 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/IndexLocker.java
index a03c9eb5963..9368dd7f370 100644
--- 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/IndexLocker.java
+++ 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/IndexLocker.java
@@ -23,6 +23,7 @@ import org.apache.ignite.internal.binarytuple.BinaryTuple;
 import org.apache.ignite.internal.schema.BinaryRow;
 import org.apache.ignite.internal.storage.RowId;
 import org.apache.ignite.internal.tx.Lock;
+import org.apache.ignite.internal.util.IgniteUtils;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -72,4 +73,41 @@ public interface IndexLocker {
      * @return A future representing a result.
      */
     CompletableFuture<Void> locksForRemove(UUID txId, BinaryRow tableRow, 
RowId rowId);
+
+    /**
+     * Composite context ID for lock keys, that includes partition ID and 
index ID.
+     */
+    class PartitionIndexId {
+        final int partitionId;
+        final int indexId;
+        private final int hash;
+
+        /**
+         * Constructor.
+         */
+        public PartitionIndexId(int partitionId, int indexId) {
+            this.partitionId = partitionId;
+            this.indexId = indexId;
+            this.hash = IgniteUtils.hash(65535 * partitionId + indexId);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+
+            PartitionIndexId that = (PartitionIndexId) o;
+            return partitionId == that.partitionId && indexId == that.indexId;
+        }
+
+        @Override
+        public int hashCode() {
+            return hash;
+        }
+    }
 }
diff --git 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/SortedIndexLocker.java
 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/SortedIndexLocker.java
index 658168388ed..301de0cb10d 100644
--- 
a/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/SortedIndexLocker.java
+++ 
b/modules/table/src/main/java/org/apache/ignite/internal/table/distributed/SortedIndexLocker.java
@@ -35,7 +35,6 @@ import org.apache.ignite.internal.tx.LockKey;
 import org.apache.ignite.internal.tx.LockManager;
 import org.apache.ignite.internal.tx.LockMode;
 import org.apache.ignite.internal.util.Cursor;
-import org.apache.ignite.internal.util.IgniteUtils;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -209,41 +208,4 @@ public class SortedIndexLocker implements IndexLocker {
 
         return lockManager.acquire(txId, new LockKey(contextId, 
key.byteBuffer()), LockMode.IX).thenApply(lock -> null);
     }
-
-    /**
-     * Composite context ID for lock keys, that includes partition ID and 
index ID.
-     */
-    public static class PartitionIndexId {
-        private final int partitionId;
-        private final int indexId;
-        private final int hash;
-
-        /**
-         * Constructor.
-         */
-        public PartitionIndexId(int partitionId, int indexId) {
-            this.partitionId = partitionId;
-            this.indexId = indexId;
-            this.hash = IgniteUtils.hash(65535 * partitionId + indexId);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-
-            if (o == null || getClass() != o.getClass()) {
-                return false;
-            }
-
-            PartitionIndexId that = (PartitionIndexId) o;
-            return partitionId == that.partitionId && indexId == that.indexId;
-        }
-
-        @Override
-        public int hashCode() {
-            return hash;
-        }
-    }
 }
diff --git 
a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerIndexLockingTest.java
 
b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerIndexLockingTest.java
index 6573a2773a6..0f935d29b4d 100644
--- 
a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerIndexLockingTest.java
+++ 
b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerIndexLockingTest.java
@@ -146,8 +146,12 @@ public class PartitionReplicaListenerIndexLockingTest 
extends IgniteAbstractTest
     private static final int PK_INDEX_ID = 1;
     private static final int HASH_INDEX_ID = 2;
     private static final int SORTED_INDEX_ID = 3;
-    private static final SortedIndexLocker.PartitionIndexId 
SORTED_INDEX_CONTEXT_ID
-            = new SortedIndexLocker.PartitionIndexId(PART_ID, SORTED_INDEX_ID);
+    private static final IndexLocker.PartitionIndexId PK_INDEX_CONTEXT_ID
+            = new IndexLocker.PartitionIndexId(PART_ID, PK_INDEX_ID);
+    private static final IndexLocker.PartitionIndexId HASH_INDEX_CONTEXT_ID
+            = new IndexLocker.PartitionIndexId(PART_ID, HASH_INDEX_ID);
+    private static final IndexLocker.PartitionIndexId SORTED_INDEX_CONTEXT_ID
+            = new IndexLocker.PartitionIndexId(PART_ID, SORTED_INDEX_ID);
     private static final int ZONE_ID = 4;
     private static final UUID TRANSACTION_ID = 
TestTransactionIds.newTransactionId();
     private static final HybridClock CLOCK = new HybridClockImpl();
@@ -199,8 +203,8 @@ public class PartitionReplicaListenerIndexLockingTest 
extends IgniteAbstractTest
         );
         pkStorage = new Lazy<>(() -> hashIndexStorage);
 
-        IndexLocker pkLocker = new HashIndexLocker(PK_INDEX_ID, true, 
LOCK_MANAGER, row2HashKeyConverter);
-        IndexLocker hashIndexLocker = new HashIndexLocker(HASH_INDEX_ID, 
false, LOCK_MANAGER, row2HashKeyConverter);
+        IndexLocker pkLocker = new HashIndexLocker(PK_INDEX_ID, PART_ID, true, 
LOCK_MANAGER, row2HashKeyConverter);
+        IndexLocker hashIndexLocker = new HashIndexLocker(HASH_INDEX_ID, 
PART_ID, false, LOCK_MANAGER, row2HashKeyConverter);
 
         BinaryTupleSchema rowSchema = 
BinaryTupleSchema.createRowSchema(schemaDescriptor);
         BinaryTupleSchema keySchema = 
BinaryTupleSchema.createKeySchema(schemaDescriptor);
@@ -408,13 +412,13 @@ public class PartitionReplicaListenerIndexLockingTest 
extends IgniteAbstractTest
                 allOf(
                         hasItem(lockThat(
                                 arg.expectedLockOnUniqueHash + " on unique 
hash index",
-                                lock -> Objects.equals(PK_INDEX_ID, 
lock.lockKey().contextId())
+                                lock -> Objects.equals(PK_INDEX_CONTEXT_ID, 
lock.lockKey().contextId())
                                         && 
row2HashKeyConverter.extractColumns(testBinaryRow).byteBuffer().equals(lock.lockKey().key())
                                         && lock.lockMode() == 
arg.expectedLockOnUniqueHash
                         )),
                         hasItem(lockThat(
                                 arg.expectedLockOnNonUniqueHash + " on non 
unique hash index",
-                                lock -> Objects.equals(HASH_INDEX_ID, 
lock.lockKey().contextId())
+                                lock -> Objects.equals(HASH_INDEX_CONTEXT_ID, 
lock.lockKey().contextId())
                                         && lock.lockMode() == 
arg.expectedLockOnNonUniqueHash
                         )),
                         hasItem(lockThat(
@@ -502,13 +506,13 @@ public class PartitionReplicaListenerIndexLockingTest 
extends IgniteAbstractTest
                     allOf(
                             hasItem(lockThat(
                                     arg.expectedLockOnUniqueHash + " on unique 
hash index",
-                                    lock -> Objects.equals(PK_INDEX_ID, 
lock.lockKey().contextId())
+                                    lock -> 
Objects.equals(PK_INDEX_CONTEXT_ID, lock.lockKey().contextId())
                                             && 
row2HashKeyConverter.extractColumns(row).byteBuffer().equals(lock.lockKey().key())
                                             && lock.lockMode() == 
arg.expectedLockOnUniqueHash
                             )),
                             hasItem(lockThat(
                                     arg.expectedLockOnNonUniqueHash + " on non 
unique hash index",
-                                    lock -> Objects.equals(HASH_INDEX_ID, 
lock.lockKey().contextId())
+                                    lock -> 
Objects.equals(HASH_INDEX_CONTEXT_ID, lock.lockKey().contextId())
                                             && 
row2HashKeyConverter.extractColumns(row).byteBuffer().equals(lock.lockKey().key())
                                             && lock.lockMode() == 
arg.expectedLockOnNonUniqueHash
                             )),
diff --git 
a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerSortedIndexLockingTest.java
 
b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerSortedIndexLockingTest.java
index b835a330d0e..d4abcae3bb7 100644
--- 
a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerSortedIndexLockingTest.java
+++ 
b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerSortedIndexLockingTest.java
@@ -140,8 +140,8 @@ public class PartitionReplicaListenerSortedIndexLockingTest 
extends IgniteAbstra
     private static final int TABLE_ID = 1;
     private static final int PK_INDEX_ID = 1;
     private static final int ZONE_ID = 2;
-    private static final SortedIndexLocker.PartitionIndexId PK_INDEX_CONTEXT_ID
-            = new SortedIndexLocker.PartitionIndexId(PART_ID, PK_INDEX_ID);
+    private static final IndexLocker.PartitionIndexId PK_INDEX_CONTEXT_ID
+            = new IndexLocker.PartitionIndexId(PART_ID, PK_INDEX_ID);
     private static final UUID TRANSACTION_ID = 
TestTransactionIds.newTransactionId();
     private static final HybridClock CLOCK = new HybridClockImpl();
     private static final ClockService CLOCK_SERVICE = new 
TestClockService(CLOCK);
diff --git 
a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerTest.java
 
b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerTest.java
index 0dd7d1e3283..0afb63126c6 100644
--- 
a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerTest.java
+++ 
b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/PartitionReplicaListenerTest.java
@@ -588,9 +588,9 @@ public class PartitionReplicaListenerTest extends 
IgniteAbstractTest {
 
         completeBuiltIndexes(sortedIndexStorage.storage(), 
hashIndexStorage.storage());
 
-        IndexLocker pkLocker = new HashIndexLocker(pkIndexId, true, 
lockManager, row2Tuple);
+        IndexLocker pkLocker = new HashIndexLocker(pkIndexId, PART_ID, true, 
lockManager, row2Tuple);
         IndexLocker sortedIndexLocker = new SortedIndexLocker(sortedIndexId, 
PART_ID, lockManager, indexStorage, row2Tuple, false);
-        IndexLocker hashIndexLocker = new HashIndexLocker(hashIndexId, false, 
lockManager, row2Tuple);
+        IndexLocker hashIndexLocker = new HashIndexLocker(hashIndexId, 
PART_ID, false, lockManager, row2Tuple);
 
         IndexUpdateHandler indexUpdateHandler = new IndexUpdateHandler(
                 
DummyInternalTableImpl.createTableIndexStoragesSupplier(Int2ObjectMaps.singleton(pkStorage().id(),
 pkStorage()))
diff --git 
a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/ZonePartitionReplicaListenerTest.java
 
b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/ZonePartitionReplicaListenerTest.java
index 2451958f868..b346873ab17 100644
--- 
a/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/ZonePartitionReplicaListenerTest.java
+++ 
b/modules/table/src/test/java/org/apache/ignite/internal/table/distributed/replication/ZonePartitionReplicaListenerTest.java
@@ -557,9 +557,9 @@ public class ZonePartitionReplicaListenerTest extends 
IgniteAbstractTest {
 
         completeBuiltIndexes(sortedIndexStorage.storage(), 
hashIndexStorage.storage());
 
-        IndexLocker pkLocker = new HashIndexLocker(pkIndexId, true, 
lockManager, row2Tuple);
+        IndexLocker pkLocker = new HashIndexLocker(pkIndexId, PART_ID, true, 
lockManager, row2Tuple);
         IndexLocker sortedIndexLocker = new SortedIndexLocker(sortedIndexId, 
PART_ID, lockManager, indexStorage, row2Tuple, false);
-        IndexLocker hashIndexLocker = new HashIndexLocker(hashIndexId, false, 
lockManager, row2Tuple);
+        IndexLocker hashIndexLocker = new HashIndexLocker(hashIndexId, 
PART_ID, false, lockManager, row2Tuple);
 
         IndexUpdateHandler indexUpdateHandler = new IndexUpdateHandler(
                 
DummyInternalTableImpl.createTableIndexStoragesSupplier(Int2ObjectMaps.singleton(pkStorage().id(),
 pkStorage()))
diff --git 
a/modules/table/src/testFixtures/java/org/apache/ignite/distributed/ItTxTestCluster.java
 
b/modules/table/src/testFixtures/java/org/apache/ignite/distributed/ItTxTestCluster.java
index 4d0c6caf49a..82e0f9cf5c0 100644
--- 
a/modules/table/src/testFixtures/java/org/apache/ignite/distributed/ItTxTestCluster.java
+++ 
b/modules/table/src/testFixtures/java/org/apache/ignite/distributed/ItTxTestCluster.java
@@ -770,7 +770,7 @@ public class ItTxTestCluster {
                         row2Tuple
                 ));
 
-                IndexLocker pkLocker = new HashIndexLocker(indexId, true, 
txManagers.get(assignment).lockManager(), row2Tuple);
+                IndexLocker pkLocker = new HashIndexLocker(indexId, partId, 
true, txManagers.get(assignment).lockManager(), row2Tuple);
 
                 SafeTimeValuesTracker safeTime = 
safeTimeTrackers.computeIfAbsent(assignment, k -> new ConcurrentHashMap<>())
                         .computeIfAbsent(grpId, k -> new 
SafeTimeValuesTracker(HybridTimestamp.MIN_VALUE));
diff --git 
a/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/impl/DummyInternalTableImpl.java
 
b/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/impl/DummyInternalTableImpl.java
index 55f4f56340d..161d80149bd 100644
--- 
a/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/impl/DummyInternalTableImpl.java
+++ 
b/modules/table/src/testFixtures/java/org/apache/ignite/internal/table/impl/DummyInternalTableImpl.java
@@ -440,7 +440,7 @@ public class DummyInternalTableImpl extends 
InternalTableImpl {
                 row2Tuple
         ));
 
-        IndexLocker pkLocker = new HashIndexLocker(indexId, true, 
this.txManager.lockManager(), row2Tuple);
+        IndexLocker pkLocker = new HashIndexLocker(indexId, PART_ID, true, 
this.txManager.lockManager(), row2Tuple);
 
         safeTime = new SafeTimeValuesTracker(HybridTimestamp.MIN_VALUE);
 

Reply via email to