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

nizhikov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 911c54c7d73 IGNITE-27372 Fix snapshot restoration when indexPath equal 
to storagePath (#12585)
911c54c7d73 is described below

commit 911c54c7d73596e71654c1426729b050a3e9a950
Author: Nikolay <[email protected]>
AuthorDate: Wed Dec 17 18:07:56 2025 +0300

    IGNITE-27372 Fix snapshot restoration when indexPath equal to storagePath 
(#12585)
---
 .../cache/persistence/filename/NodeFileTree.java   |  32 ++++-
 .../filename/SnapshotRestoreIndexPathTest.java     | 129 +++++++++++++++++++++
 .../ignite/testsuites/IgnitePdsTestSuite8.java     |   2 +
 3 files changed, 158 insertions(+), 5 deletions(-)

diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/NodeFileTree.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/NodeFileTree.java
index 76feaf6e9ee..dbf07261067 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/NodeFileTree.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/filename/NodeFileTree.java
@@ -594,9 +594,16 @@ public class NodeFileTree extends SharedFileTree {
         boolean idxPathEmpty = !includeIdxPath || F.isEmpty(idxPath);
 
         if (F.isEmpty(csp)) {
-            return idxPathEmpty
-                ? new File[]{cacheStorage(null, cacheDirName)}
-                : new File[]{cacheStorage(null, cacheDirName), 
cacheStorage(idxPath, cacheDirName)};
+            File cs = cacheStorage(null, cacheDirName);
+
+            if (idxPathEmpty)
+                return new File[]{cs};
+
+            File idxStorage = cacheStorage(idxPath, cacheDirName);
+
+            return idxStorage.equals(cs)
+                ? new File[]{cs}
+                : new File[]{cs, idxStorage};
         }
 
         File[] cs = new File[csp.length + (idxPathEmpty ? 0 : 1)];
@@ -604,8 +611,23 @@ public class NodeFileTree extends SharedFileTree {
         for (int i = 0; i < csp.length; i++)
             cs[i] = cacheStorage(csp[i], cacheDirName);
 
-        if (!idxPathEmpty)
-            cs[cs.length - 1] = cacheStorage(idxPath, cacheDirName);
+        if (!idxPathEmpty) {
+            File idxStorage = cacheStorage(idxPath, cacheDirName);
+
+            for (int i = 0; i < csp.length; i++) {
+                // indexPath equals to some storagePath.
+                // No need to add twice.
+                if (cs[i].equals(idxStorage)) {
+                    File[] cs2 = new File[csp.length];
+
+                    System.arraycopy(cs, 0, cs2, 0, cs2.length);
+
+                    return cs2;
+                }
+            }
+
+            cs[cs.length - 1] = idxStorage;
+        }
 
         return cs;
     }
diff --git 
a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/filename/SnapshotRestoreIndexPathTest.java
 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/filename/SnapshotRestoreIndexPathTest.java
new file mode 100644
index 00000000000..6723d0a9399
--- /dev/null
+++ 
b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/filename/SnapshotRestoreIndexPathTest.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.cache.persistence.filename;
+
+import java.io.File;
+import java.util.stream.IntStream;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.cluster.ClusterState;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+
+import static 
org.apache.ignite.internal.processors.cache.persistence.filename.AbstractDataRegionRelativeStoragePathTest.consId;
+
+/** Check snapshot restore when {@link CacheConfiguration#getIndexPath()} 
equals to some of {@link CacheConfiguration#getStoragePaths()}. */
+public class SnapshotRestoreIndexPathTest extends GridCommonAbstractTest {
+    /** */
+    private boolean defaultStoragePath;
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String 
igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        DataStorageConfiguration dsCfg = new DataStorageConfiguration()
+            .setStoragePath(path("path1"))
+            .setExtraStoragePaths(path("path2"), path("path3"), path("path4"));
+
+        dsCfg.getDefaultDataRegionConfiguration()
+            .setPersistenceEnabled(true);
+
+        return cfg
+            .setConsistentId(consId(cfg))
+            .setDataStorageConfiguration(dsCfg);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        U.delete(new File(U.defaultWorkDirectory()));
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        U.delete(new File(U.defaultWorkDirectory()));
+    }
+
+    /** */
+    @Test
+    public void testSameIndexAndExtraStorage() throws Exception {
+        defaultStoragePath = false;
+        doTest();
+    }
+
+    /** */
+    @Test
+    public void testSameIndexAndDefaultStorage() throws Exception {
+        defaultStoragePath = true;
+        doTest();
+    }
+
+    /** */
+    private void doTest() throws Exception {
+        IgniteEx srv = startGrid(0);
+
+        srv.cluster().state(ClusterState.ACTIVE);
+
+        CacheConfiguration<Integer, Integer> ccfg = new 
CacheConfiguration<>(DEFAULT_CACHE_NAME);
+
+        if (defaultStoragePath) {
+            ccfg.setIndexPath(path("path1"));
+        }
+        else {
+            ccfg.setStoragePaths(path("path1"), path("path2"), path("path3"), 
path("path4"))
+                .setIndexPath(path("path2"));
+        }
+
+        IgniteCache<Integer, Integer> c = srv.createCache(ccfg);
+
+        IntStream.range(0, 100).forEach(i -> c.put(i, i));
+
+        srv.snapshot().createSnapshot("snapshot").get();
+
+        stopAllGrids();
+
+        cleanPersistenceDir(true);
+        U.delete(new File(path("path1")));
+        U.delete(new File(path("path2"), "db"));
+        U.delete(new File(path("path3"), "db"));
+        U.delete(new File(path("path4"), "db"));
+
+        srv = startGrid(0);
+
+        srv.cluster().state(ClusterState.ACTIVE);
+
+        srv.snapshot().restoreSnapshot("snapshot", null).get();
+
+        IgniteCache<Integer, Integer> c2 = srv.cache(DEFAULT_CACHE_NAME);
+
+        IntStream.range(0, 100).boxed().forEach(i -> assertEquals(i, 
c2.get(i)));
+    }
+
+    /** */
+    public String path(String folder) throws IgniteCheckedException {
+        return new File(new File(U.defaultWorkDirectory()), 
folder).getAbsolutePath();
+    }
+}
diff --git 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite8.java
 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite8.java
index 29be9f1c383..914156bb9af 100644
--- 
a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite8.java
+++ 
b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite8.java
@@ -51,6 +51,7 @@ import 
org.apache.ignite.internal.processors.cache.persistence.diagnostic.pagelo
 import 
org.apache.ignite.internal.processors.cache.persistence.filename.CacheConfigStoragePathTest;
 import 
org.apache.ignite.internal.processors.cache.persistence.filename.CustomCacheStorageConfigurationSelfTest;
 import 
org.apache.ignite.internal.processors.cache.persistence.filename.SnapshotCreationNonDefaultStoragePathTest;
+import 
org.apache.ignite.internal.processors.cache.persistence.filename.SnapshotRestoreIndexPathTest;
 import 
org.apache.ignite.internal.processors.cache.warmup.LoadAllWarmUpStrategySelfTest;
 import org.apache.ignite.internal.processors.cache.warmup.WarmUpSelfTest;
 import org.apache.ignite.testframework.GridTestUtils;
@@ -114,6 +115,7 @@ public class IgnitePdsTestSuite8 {
         GridTestUtils.addTestIfNeeded(suite, 
IgnitePdsCheckpointRecoveryTest.class, ignoredTests);
         GridTestUtils.addTestIfNeeded(suite, CacheConfigStoragePathTest.class, 
ignoredTests);
         GridTestUtils.addTestIfNeeded(suite, 
SnapshotCreationNonDefaultStoragePathTest.class, ignoredTests);
+        GridTestUtils.addTestIfNeeded(suite, 
SnapshotRestoreIndexPathTest.class, ignoredTests);
         GridTestUtils.addTestIfNeeded(suite, 
CustomCacheStorageConfigurationSelfTest.class, ignoredTests);
 
         return suite;

Reply via email to