ignite-3957: clear swap space when cache is destroyed
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/106d496d Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/106d496d Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/106d496d Branch: refs/heads/ignite-2788 Commit: 106d496d7dd07f56940adc62b666e28974fe789d Parents: 2489b8a Author: Andrey Martianov <[email protected]> Authored: Thu Sep 29 16:33:04 2016 +0300 Committer: sboikov <[email protected]> Committed: Thu Sep 29 17:00:48 2016 +0300 ---------------------------------------------------------------------- .../processors/cache/GridCacheSwapManager.java | 7 ++ .../spi/swapspace/file/FileSwapSpaceSpi.java | 53 +++++++---- .../cache/GridCacheSwapCleanupTest.java | 99 ++++++++++++++++++++ .../ignite/testsuites/IgniteCacheTestSuite.java | 2 + 4 files changed, 141 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/106d496d/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSwapManager.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSwapManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSwapManager.java index 8ba960a..5ada8dc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSwapManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSwapManager.java @@ -143,6 +143,13 @@ public class GridCacheSwapManager extends GridCacheManagerAdapter { @Override protected void stop0(boolean cancel) { if (offheapEnabled) offheap.destruct(spaceName); + + try { + clearSwap(); + } + catch (IgniteCheckedException e) { + U.error(log, "Failed to clear cache swap space", e); + } } /** http://git-wip-us.apache.org/repos/asf/ignite/blob/106d496d/modules/core/src/main/java/org/apache/ignite/spi/swapspace/file/FileSwapSpaceSpi.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/spi/swapspace/file/FileSwapSpaceSpi.java b/modules/core/src/main/java/org/apache/ignite/spi/swapspace/file/FileSwapSpaceSpi.java index 9be5b93..1f6004d 100644 --- a/modules/core/src/main/java/org/apache/ignite/spi/swapspace/file/FileSwapSpaceSpi.java +++ b/modules/core/src/main/java/org/apache/ignite/spi/swapspace/file/FileSwapSpaceSpi.java @@ -333,12 +333,7 @@ public class FileSwapSpaceSpi extends IgniteSpiAdapter implements SwapSpaceSpi, /** {@inheritDoc} */ @Override public void clear(@Nullable String spaceName) throws IgniteSpiException { - Space space = space(spaceName, false); - - if (space == null) - return; - - space.clear(); + destruct(spaceName); notifyListener(EVT_SWAP_SPACE_CLEARED, spaceName); } @@ -630,7 +625,7 @@ public class FileSwapSpaceSpi extends IgniteSpiAdapter implements SwapSpaceSpi, * @throws org.apache.ignite.spi.IgniteSpiException In case of error. */ @Nullable private Space space(@Nullable String name, boolean create) throws IgniteSpiException { - String masked = name != null ? name : DFLT_SPACE_NAME; + String masked = maskNull(name); assert masked != null; @@ -652,6 +647,36 @@ public class FileSwapSpaceSpi extends IgniteSpiAdapter implements SwapSpaceSpi, } /** + * Destructs space. + * + * @param spaceName space name. + * */ + private void destruct(@Nullable String spaceName) { + String masked = maskNull(spaceName); + + Space space = spaces.remove(masked); + + if (space != null) { + try { + space.stop(); + } + catch (IgniteInterruptedCheckedException e) { + U.error(log, "Interrupted.", e); + } + } + } + + /** + * Masks null space name with default space name. + * + * @param spaceName Space name. + * @return Space name or default space name if space name is null. + * */ + private static String maskNull(String spaceName) { + return spaceName != null ? spaceName : DFLT_SPACE_NAME; + } + + /** * Validates space name. * * @param name Space name. @@ -1623,18 +1648,6 @@ public class FileSwapSpaceSpi extends IgniteSpiAdapter implements SwapSpaceSpi, } /** - * Clears space. - * - * @throws org.apache.ignite.spi.IgniteSpiException If failed. - */ - public void clear() throws IgniteSpiException { - Iterator<Map.Entry<SwapKey, byte[]>> iter = entriesIterator(); - - while (iter.hasNext()) - remove(iter.next().getKey(), false); - } - - /** * Stops space. * * @throws org.apache.ignite.internal.IgniteInterruptedCheckedException If interrupted. @@ -1931,4 +1944,4 @@ public class FileSwapSpaceSpi extends IgniteSpiAdapter implements SwapSpaceSpi, }; } } -} \ No newline at end of file +} http://git-wip-us.apache.org/repos/asf/ignite/blob/106d496d/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheSwapCleanupTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheSwapCleanupTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheSwapCleanupTest.java new file mode 100644 index 0000000..5835ef0 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/GridCacheSwapCleanupTest.java @@ -0,0 +1,99 @@ +/* + * 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; + +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.cache.eviction.lru.LruEvictionPolicy; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.managers.swapspace.GridSwapSpaceManager; +import org.apache.ignite.internal.util.typedef.internal.CU; +import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; +import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; +import org.apache.ignite.spi.swapspace.file.FileSwapSpaceSpi; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; + +/** + * Check swap is cleaned after cache destroy. + */ +public class GridCacheSwapCleanupTest extends GridCommonAbstractTest { + /** IP finder. */ + private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true); + + /** Cache name. */ + private static final String CACHE_NAME = "swapCleanupCache"; + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String gridName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(gridName); + + ((TcpDiscoverySpi)cfg.getDiscoverySpi()).setIpFinder(IP_FINDER); + + cfg.setSwapSpaceSpi(new FileSwapSpaceSpi()); + + return cfg; + } + + /** + * Creates cache configuration. + * + * @return Cache configuration. + * */ + private CacheConfiguration createCacheConfiguration() { + CacheConfiguration ccfg = new CacheConfiguration(); + + ccfg.setName(CACHE_NAME); + ccfg.setEvictionPolicy(new LruEvictionPolicy(10)); + ccfg.setSwapEnabled(true); + + return ccfg; + } + + /** + * Checks swap is cleaned after cache destroy. + * + * @throws Exception If failed. + * */ + public void testSwapCleanupAfterCacheDestroy() throws Exception { + try (Ignite g = startGrid()) { + for (int iter = 0; iter < 3; iter++) { + IgniteCache cache = g.getOrCreateCache(createCacheConfiguration()); + + for (int i = 0; i < 20; i++) { + assertNull(cache.get(i)); + + cache.put(i, i); + } + + String spaceName = CU.swapSpaceName(internalCache(cache).context()); + + GridSwapSpaceManager swapSpaceMgr = ((IgniteEx)g).context().swap(); + + assertEquals(10, swapSpaceMgr.swapKeys(spaceName)); + + g.destroyCache(cache.getName()); + + assertEquals(0, swapSpaceMgr.swapKeys(spaceName)); + assertEquals(0, swapSpaceMgr.swapSize(spaceName)); + } + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/106d496d/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java index 5ad4cb8..711453c 100755 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgniteCacheTestSuite.java @@ -81,6 +81,7 @@ import org.apache.ignite.internal.processors.cache.GridCacheReplicatedTxStoreExc import org.apache.ignite.internal.processors.cache.GridCacheStopSelfTest; import org.apache.ignite.internal.processors.cache.GridCacheStorePutxSelfTest; import org.apache.ignite.internal.processors.cache.GridCacheStoreValueBytesSelfTest; +import org.apache.ignite.internal.processors.cache.GridCacheSwapCleanupTest; import org.apache.ignite.internal.processors.cache.GridCacheSwapPreloadSelfTest; import org.apache.ignite.internal.processors.cache.GridCacheSwapReloadSelfTest; import org.apache.ignite.internal.processors.cache.GridCacheTtlManagerSelfTest; @@ -227,6 +228,7 @@ public class IgniteCacheTestSuite extends TestSuite { // Swap tests. suite.addTestSuite(GridCacheSwapPreloadSelfTest.class); suite.addTestSuite(GridCacheSwapReloadSelfTest.class); + suite.addTestSuite(GridCacheSwapCleanupTest.class); // Common tests. suite.addTestSuite(CacheNamesSelfTest.class);
