alex-plekhanov commented on code in PR #11357:
URL: https://github.com/apache/ignite/pull/11357#discussion_r1618812044


##########
modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheGroupView.java:
##########
@@ -18,6 +18,7 @@
 package org.apache.ignite.spi.systemview.view;
 
 import java.util.Map;
+import org.apache.ignite.IgniteCheckedException;

Review Comment:
   Redundant change



##########
modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheGroupView.java:
##########
@@ -26,6 +27,7 @@
 import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.TopologyValidator;
 import org.apache.ignite.internal.managers.systemview.walker.Order;
+import org.apache.ignite.internal.processors.cache.CacheGroupContext;

Review Comment:
   Redundant change



##########
modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewCacheExpiryPolicyTest.java:
##########
@@ -0,0 +1,106 @@
+/*
+ * 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.metric;
+
+import java.util.Arrays;
+import java.util.Collection;
+import javax.cache.configuration.Factory;
+import javax.cache.configuration.FactoryBuilder;
+import javax.cache.expiry.CreatedExpiryPolicy;
+import javax.cache.expiry.Duration;
+import javax.cache.expiry.EternalExpiryPolicy;
+import javax.cache.expiry.ExpiryPolicy;
+import javax.cache.expiry.ModifiedExpiryPolicy;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import 
org.apache.ignite.internal.processors.platform.cache.expiry.PlatformExpiryPolicyFactory;
+import org.apache.ignite.spi.systemview.view.CacheView;
+import org.apache.ignite.spi.systemview.view.SystemView;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static 
org.apache.ignite.internal.processors.cache.ClusterCachesInfo.CACHES_VIEW;
+
+/** Tests for {@link CacheView} expiry policy factory representation. */
+@RunWith(Parameterized.class)
+public class SystemViewCacheExpiryPolicyTest extends GridCommonAbstractTest {
+    /** {@link Factory} instances for test with different expiry policy. */
+    @SuppressWarnings("unchecked")
+    private static final Factory[] TTL_FACTORIES = {
+        null,
+        new FactoryBuilder.SingletonFactory<ExpiryPolicy>(new 
EternalExpiryPolicy()),

Review Comment:
   `SingletonFactory` created via `EternalExpiryPolicy.factoryOf` methods



##########
modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheView.java:
##########
@@ -331,7 +336,46 @@ public String cacheWriterFactory() {
 
     /** @see CacheConfiguration#getExpiryPolicyFactory() */
     public String expiryPolicyFactory() {
-        return 
toStringSafe(cache.cacheConfiguration().getExpiryPolicyFactory());
+        if (cache.cacheConfiguration().getExpiryPolicyFactory() == null)
+            return null;
+
+        ExpiryPolicy expiryPlc = 
(ExpiryPolicy)cache.cacheConfiguration().getExpiryPolicyFactory().create();
+
+        StringBuilder expiryPlcFactoryStrBld = new StringBuilder();
+
+        BiFunction<String, Duration, StringBuilder> func = (msg, duration) -> {
+            StringBuilder result = new StringBuilder();
+
+            if (duration == null || duration.getTimeUnit() == null || 
duration.getDurationAmount() == 0)
+                return result;
+
+            return result
+                
.append('[').append(msg).append('=').append(duration.getDurationAmount())
+                .append(' ').append(duration.getTimeUnit()).append(']');
+        };
+
+        expiryPlcFactoryStrBld.append(func.apply("create", 
expiryPlc.getExpiryForCreation()));
+        expiryPlcFactoryStrBld.append(func.apply("update", 
expiryPlc.getExpiryForUpdate()));
+        expiryPlcFactoryStrBld.append(func.apply("access", 
expiryPlc.getExpiryForAccess()));
+
+        return expiryPlcFactoryStrBld.length() == 0 ? "Eternal" : 
expiryPlcFactoryStrBld.toString();
+    }
+
+    /** @return {@code Yes} if cache has expired entries, {@code No} 
otherwise. If {@code eagerTtl = true} returns 'Unknown'. */
+    public String expiryPolicyEntry() {

Review Comment:
   Perhaps, `hasExpiringEntries`?



##########
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java:
##########
@@ -1180,6 +1180,18 @@ private int expireInternal(
         return pendingEntries != null ? pendingEntries.size() : 0;
     }
 
+    /** {@inheritDoc} */
+    @Override public boolean hasEntriesPendingExpire(int cacheId) throws 
IgniteCheckedException {
+        if (pendingEntries == null)
+            return false;
+
+        PendingRow row = new PendingRow(cacheId);
+
+        GridCursor<PendingRow> cursor = pendingEntries.find(row, row, 
PendingEntriesTree.WITHOUT_KEY);

Review Comment:
   In case of !sharedGroup we should check only `isEmpty':
   ```
           if (grp.sharedGroup()) {
               PendingRow row = new PendingRow(cacheId);
   
               GridCursor<PendingRow> cursor = pendingEntries.find(row, row, 
PendingEntriesTree.WITHOUT_KEY);
   
               return cursor.next();
           }
           else 
               return !pendingEntries.isEmpty();
   ```



##########
modules/core/src/test/java/org/apache/ignite/internal/metric/SystemViewSelfTest.java:
##########
@@ -259,6 +263,114 @@ public void testCacheGroupsView() throws Exception {
         }
     }
 
+    /** Tests work of {@link SystemView} for cache expiry policy info with 
in-memory configuration. */
+    @Test
+    public void testCacheViewExpiryPolicyWithInMemory() throws Exception {
+        testCacheViewExpiryPolicy(false);
+    }
+
+    /** Tests work of {@link SystemView} for cache expiry policy info with 
persist configuration. */
+    @Test
+    public void testCacheViewExpiryPolicyWithPersist() throws Exception {
+        testCacheViewExpiryPolicy(true);
+    }
+
+    /** Tests work of {@link SystemView} for cache groups expiry policy info. 
*/
+    private void testCacheViewExpiryPolicy(boolean withPersistence) throws 
Exception {
+        try (IgniteEx g = !withPersistence ? startGrid() : 
startGrid(getConfiguration().setDataStorageConfiguration(
+            new DataStorageConfiguration().setDefaultDataRegionConfiguration(
+                new DataRegionConfiguration().setPersistenceEnabled(true)
+            )))) {
+
+            if (withPersistence)
+                g.cluster().state(ClusterState.ACTIVE);
+
+            String eternalCacheName = "eternalCache";
+            String createdCacheName = "createdCache";
+            String eagerTtlCacheName = "eagerTtlCache";
+            String withoutGrpCacheName = "withoutGrpCache";
+            String dfltCacheName = "defaultCache";
+
+            CacheConfiguration<Long, Long> eternalCache = new 
CacheConfiguration<Long, Long>(eternalCacheName)
+                .setGroupName("group1")
+                .setExpiryPolicyFactory(EternalExpiryPolicy.factoryOf());
+
+            CacheConfiguration<Long, Long> createdCache = new 
CacheConfiguration<Long, Long>(createdCacheName)
+                .setGroupName("group2")
+                .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new 
Duration(TimeUnit.MILLISECONDS, 500L)));
+
+            CacheConfiguration<Long, Long> eagerTtlCache = new 
CacheConfiguration<Long, Long>(eagerTtlCacheName)
+                .setGroupName("group2")
+                .setEagerTtl(false)
+                .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new 
Duration(TimeUnit.MILLISECONDS, 500L)));
+
+            CacheConfiguration<Long, Long> withoutGrpCache = new 
CacheConfiguration<Long, Long>(withoutGrpCacheName)
+                .setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new 
Duration(TimeUnit.MILLISECONDS, 500L)));
+
+            CacheConfiguration<Long, Long> dfltCache = new 
CacheConfiguration<Long, Long>(dfltCacheName)
+                .setGroupName("group3");
+
+            g.createCache(eternalCache);
+            g.createCache(createdCache);
+            g.createCache(eagerTtlCache);
+            g.createCache(withoutGrpCache);
+            g.createCache(dfltCache);
+
+            SystemView<CacheView> caches = 
g.context().systemView().view(CACHES_VIEW);
+
+            for (CacheView row : caches) {
+                switch (row.cacheName()) {
+                    case "defaultCache":
+                    case "eternalCache":
+                        assertEquals("No", row.expiryPolicyEntry());
+
+                        g.cache(row.cacheName()).put(0, 0);
+
+                        assertEquals("No", row.expiryPolicyEntry());
+
+                        g.cache(row.cacheName())
+                            .withExpiryPolicy(new CreatedExpiryPolicy(new 
Duration(TimeUnit.MILLISECONDS, 200L)))
+                            .put(1, 1);
+
+                        assertEquals("Yes", row.expiryPolicyEntry());
+                        assertTrue(waitForCondition(() -> 
row.expiryPolicyEntry().equals("No"), getTestTimeout()));
+
+                        break;
+
+                    case "createdCache":
+                        assertEquals("No", row.expiryPolicyEntry());
+
+                        g.cache(createdCacheName).put(0, 0);
+
+                        assertEquals("Yes", row.expiryPolicyEntry());
+                        assertTrue(waitForCondition(() -> 
row.expiryPolicyEntry().equals("No"), getTestTimeout()));
+
+                        g.cache(createdCacheName)
+                            .withExpiryPolicy(new ModifiedExpiryPolicy(new 
Duration(TimeUnit.MILLISECONDS, 200L)))
+                            .put(1, 1);
+
+                        assertEquals("Yes", row.expiryPolicyEntry());
+                        assertTrue(waitForCondition(() -> 
row.expiryPolicyEntry().equals("No"), getTestTimeout()));
+
+                        g.cache(eagerTtlCacheName).put(2, 2);
+                        assertEquals("No", row.expiryPolicyEntry());
+
+                        break;
+
+                    case "eagerTtlCache":
+                        assertEquals("Unknown", row.expiryPolicyEntry());
+
+                        break;
+
+                    case "withoutGrpCache":
+                        assertEquals("There is no cache group related data", 
row.expiryPolicyEntry());

Review Comment:
   It's not correct, here cache group is created with `sharedGroup == false` 
flag.



##########
modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java:
##########
@@ -2691,6 +2700,27 @@ public long expiredSize() throws IgniteCheckedException {
             return delegate0 == null ? 0 : pendingTree.size();
         }
 
+        /**
+         * Checks if the cache has entries pending expire.
+         *
+         * @return {@code True} if there are entries pending expire.
+         * @throws IgniteCheckedException If failed to get number of pending 
entries.
+         */
+        public boolean hasEntriesPendingExpire(int cacheId) throws 
IgniteCheckedException {
+            if (pendingTree == null)
+                return false;
+
+            PendingRow row = new PendingRow(cacheId);
+            GridCursor<PendingRow> cur;
+
+            if (grp.sharedGroup())
+                cur = pendingTree.find(row, row, 
PendingEntriesTree.WITHOUT_KEY);
+            else
+                return init0(true) != null && !pendingTree.isEmpty();

Review Comment:
   If store is not inited, than `pendingTree == null`, so we can't reach this 
line.
   We don't need to construct row in case of not shared group, let's refactor 
to something like this:
   ```
               if (grp.sharedGroup()) {
                   PendingRow row = new PendingRow(cacheId);
   
                   GridCursor<PendingRow> cur = pendingTree.find(row, row, 
PendingEntriesTree.WITHOUT_KEY);
   
                   return cur.next();
               }
               else
                   return !pendingTree.isEmpty();
   ```



##########
modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheView.java:
##########
@@ -331,7 +336,46 @@ public String cacheWriterFactory() {
 
     /** @see CacheConfiguration#getExpiryPolicyFactory() */
     public String expiryPolicyFactory() {
-        return 
toStringSafe(cache.cacheConfiguration().getExpiryPolicyFactory());
+        if (cache.cacheConfiguration().getExpiryPolicyFactory() == null)
+            return null;
+
+        ExpiryPolicy expiryPlc = 
(ExpiryPolicy)cache.cacheConfiguration().getExpiryPolicyFactory().create();
+
+        StringBuilder expiryPlcFactoryStrBld = new StringBuilder();
+
+        BiFunction<String, Duration, StringBuilder> func = (msg, duration) -> {
+            StringBuilder result = new StringBuilder();
+
+            if (duration == null || duration.getTimeUnit() == null || 
duration.getDurationAmount() == 0)
+                return result;
+
+            return result
+                
.append('[').append(msg).append('=').append(duration.getDurationAmount())
+                .append(' ').append(duration.getTimeUnit()).append(']');
+        };
+
+        expiryPlcFactoryStrBld.append(func.apply("create", 
expiryPlc.getExpiryForCreation()));
+        expiryPlcFactoryStrBld.append(func.apply("update", 
expiryPlc.getExpiryForUpdate()));
+        expiryPlcFactoryStrBld.append(func.apply("access", 
expiryPlc.getExpiryForAccess()));
+
+        return expiryPlcFactoryStrBld.length() == 0 ? "Eternal" : 
expiryPlcFactoryStrBld.toString();
+    }
+
+    /** @return {@code Yes} if cache has expired entries, {@code No} 
otherwise. If {@code eagerTtl = true} returns 'Unknown'. */
+    public String expiryPolicyEntry() {
+        CacheGroupContext grpCtx = ctx.cache().cacheGroup(cache.groupId());
+
+        if (!cache.cacheConfiguration().isEagerTtl() || grpCtx == null)
+            return "Unknown";
+        else if (grpCtx.name() == null)
+            return "There is no cache group related data";

Review Comment:
   Looks like this is case for `!sharedGroup`



##########
modules/core/src/main/java/org/apache/ignite/spi/systemview/view/CacheView.java:
##########
@@ -331,7 +336,46 @@ public String cacheWriterFactory() {
 
     /** @see CacheConfiguration#getExpiryPolicyFactory() */
     public String expiryPolicyFactory() {
-        return 
toStringSafe(cache.cacheConfiguration().getExpiryPolicyFactory());
+        if (cache.cacheConfiguration().getExpiryPolicyFactory() == null)
+            return null;
+
+        ExpiryPolicy expiryPlc = 
(ExpiryPolicy)cache.cacheConfiguration().getExpiryPolicyFactory().create();

Review Comment:
   We should also expose information about factory (according to method name) 



-- 
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: notifications-unsubscr...@ignite.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to