tkalkirill commented on code in PR #1652:
URL: https://github.com/apache/ignite-3/pull/1652#discussion_r1105577122
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/AbstractPageMemoryMvPartitionStorage.java:
##########
@@ -944,15 +862,67 @@ public void finishCleanup() {
}
}
- @Nullable VersionChain readVersionChain(RowId rowId) {
+ void throwExceptionIfStorageNotInRunnableState() {
+ StorageUtils.throwExceptionIfStorageNotInRunnableState(state.get(),
this::createStorageInfo);
+ }
+
+ /**
+ * Searches version chain by row ID and converts the found version chain
to the result if found.
+ *
+ * @param rowId Row ID.
+ * @param function Function for converting the version chain to a result,
function is executed under the read lock of the page on which
+ * the version chain is located. If the version chain is not found,
then {@code null} will be passed to the function.
+ */
+ <T> @Nullable T findVersionChain(RowId rowId, Function<VersionChain, T>
function) {
try {
- return versionChainTree.findOne(new VersionChainKey(rowId));
+ return versionChainTree.findOne(new VersionChainKey(rowId), new
TreeRowClosure<>() {
+ @Override
+ public boolean apply(BplusTree<VersionChainKey, VersionChain>
tree, BplusIo<VersionChainKey> io, long pageAddr, int idx) {
+ return true;
+ }
+
+ @Override
+ public T map(VersionChain treeRow) {
+ return function.apply(treeRow);
+ }
+ }, null);
} catch (IgniteInternalCheckedException e) {
- throw new StorageException("Error getting version chain:
[rowId={}, {}]", e, rowId, createStorageInfo());
+ if (e.getCause() instanceof StorageException) {
+ throw (StorageException) e.getCause();
+ }
+
+ throw new StorageException("Row version lookup failed: [rowId={},
{}]", e, rowId, createStorageInfo());
}
}
- void throwExceptionIfStorageNotInRunnableState() {
- StorageUtils.throwExceptionIfStorageNotInRunnableState(state.get(),
this::createStorageInfo);
+ /**
+ * Organizes external synchronization of update operations for the same
version chain.
+ *
+ * <p>NOTE: When you try to execute in the closures on the pages of the
tree, it leads to a deadlock.
+ */
+ protected <T> T inUpdateVersionChainLock(RowId rowId, Supplier<T>
supplier) {
+ LockHolder<ReentrantLock> lockHolder =
updateVersionChainLockByRowId.compute(rowId, (rowId1, reentrantLockLockHolder)
-> {
Review Comment:
When not very much, do you think we need to put it in a separate class?
At the moment, this map only locks updates.
I will try to describe it in the documentation for the class.
##########
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/AbstractPageMemoryMvPartitionStorage.java:
##########
@@ -944,15 +862,67 @@ public void finishCleanup() {
}
}
- @Nullable VersionChain readVersionChain(RowId rowId) {
+ void throwExceptionIfStorageNotInRunnableState() {
+ StorageUtils.throwExceptionIfStorageNotInRunnableState(state.get(),
this::createStorageInfo);
+ }
+
+ /**
+ * Searches version chain by row ID and converts the found version chain
to the result if found.
+ *
+ * @param rowId Row ID.
+ * @param function Function for converting the version chain to a result,
function is executed under the read lock of the page on which
+ * the version chain is located. If the version chain is not found,
then {@code null} will be passed to the function.
+ */
+ <T> @Nullable T findVersionChain(RowId rowId, Function<VersionChain, T>
function) {
try {
- return versionChainTree.findOne(new VersionChainKey(rowId));
+ return versionChainTree.findOne(new VersionChainKey(rowId), new
TreeRowClosure<>() {
+ @Override
+ public boolean apply(BplusTree<VersionChainKey, VersionChain>
tree, BplusIo<VersionChainKey> io, long pageAddr, int idx) {
+ return true;
+ }
+
+ @Override
+ public T map(VersionChain treeRow) {
+ return function.apply(treeRow);
+ }
+ }, null);
} catch (IgniteInternalCheckedException e) {
- throw new StorageException("Error getting version chain:
[rowId={}, {}]", e, rowId, createStorageInfo());
+ if (e.getCause() instanceof StorageException) {
+ throw (StorageException) e.getCause();
+ }
+
+ throw new StorageException("Row version lookup failed: [rowId={},
{}]", e, rowId, createStorageInfo());
}
}
- void throwExceptionIfStorageNotInRunnableState() {
- StorageUtils.throwExceptionIfStorageNotInRunnableState(state.get(),
this::createStorageInfo);
+ /**
+ * Organizes external synchronization of update operations for the same
version chain.
+ *
+ * <p>NOTE: When you try to execute in the closures on the pages of the
tree, it leads to a deadlock.
+ */
+ protected <T> T inUpdateVersionChainLock(RowId rowId, Supplier<T>
supplier) {
+ LockHolder<ReentrantLock> lockHolder =
updateVersionChainLockByRowId.compute(rowId, (rowId1, reentrantLockLockHolder)
-> {
Review Comment:
When not very much, do you think we need to put it in a separate class?
At the moment, this map only locks updates.
I will try to describe it in the documentation for the class.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]