Repository: incubator-ignite
Updated Branches:
  refs/heads/ignite-49 [created] 996cc086a


IGNITE-49 Implemented CacheStatisticsMXBean#getCacheEvictions()


Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/c04013d9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/c04013d9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/c04013d9

Branch: refs/heads/ignite-49
Commit: c04013d9b89e94fba80bdcae3723cc337cdf09ea
Parents: 70d98c2
Author: nikolay_tikhonov <ntikho...@gridgain.com>
Authored: Fri Dec 26 12:58:51 2014 +0300
Committer: nikolay_tikhonov <ntikho...@gridgain.com>
Committed: Fri Jan 16 14:13:33 2015 +0300

----------------------------------------------------------------------
 .../cache/GridCacheEvictionManager.java         |   2 +
 .../cache/GridCacheMetricsAdapter.java          |  51 +--
 .../processors/cache/GridCacheTtlManager.java   |   2 +
 .../cache/GridCacheAbstractMetricsSelfTest.java | 309 ++++++++++++++++++-
 4 files changed, 344 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/c04013d9/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEvictionManager.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEvictionManager.java
 
b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEvictionManager.java
index d05a347..6894ed0 100644
--- 
a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEvictionManager.java
+++ 
b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEvictionManager.java
@@ -668,6 +668,8 @@ public class GridCacheEvictionManager<K, V> extends 
GridCacheManagerAdapter<K, V
 
             cache.removeEntry(entry);
 
+            cache.metrics0().onEvict();
+
             if (recordable)
                 cctx.events().addEvent(entry.partition(), entry.key(), 
cctx.nodeId(), (IgniteUuid)null, null,
                     EVT_CACHE_ENTRY_EVICTED, null, false, oldVal, hasVal, 
null, null, null);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/c04013d9/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMetricsAdapter.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMetricsAdapter.java
 
b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMetricsAdapter.java
index 63899f8..4849fa5 100644
--- 
a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMetricsAdapter.java
+++ 
b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMetricsAdapter.java
@@ -64,8 +64,10 @@ public class GridCacheMetricsAdapter implements 
GridCacheMetrics, Externalizable
     /** Number of transaction rollbacks. */
     private volatile int txRollbacks;
 
-    private volatile long getCnt;
-    private volatile long putCnt;
+    /** Number of evictions. */
+    private volatile long evictCnt;
+
+    /** Number of removed entries. */
     private volatile long rmCnt;
 
     /** Cache metrics. */
@@ -95,6 +97,7 @@ public class GridCacheMetricsAdapter implements 
GridCacheMetrics, Externalizable
         txCommits = m.txCommits();
         txRollbacks = m.txRollbacks();
         rmCnt = m.getCacheRemovals();
+        evictCnt = m.getCacheEvictions();
     }
 
     /**
@@ -161,7 +164,6 @@ public class GridCacheMetricsAdapter implements 
GridCacheMetrics, Externalizable
 
     /** {@inheritDoc} */
     @Override public void clear() {
-        //TODO: rewrite
         createTime = U.currentTimeMillis();
         readTime = createTime;
         writeTime = createTime;
@@ -207,39 +209,36 @@ public class GridCacheMetricsAdapter implements 
GridCacheMetrics, Externalizable
 
     /** {@inheritDoc} */
     @Override public long getCacheGets() {
-        //TODO: split read
-        return 0;
+        return reads;
     }
 
     /** {@inheritDoc} */
     @Override public long getCachePuts() {
-        //TODO: split write
-        return 0;
+        return writes;
     }
 
-    @Override
-    public long getCacheRemovals() {
+    /** {@inheritDoc} */
+    @Override public long getCacheRemovals() {
         return rmCnt;
     }
 
-    @Override
-    public long getCacheEvictions() {
-        //TODO: discuss with Semen
-        return 0;
+    /** {@inheritDoc} */
+    @Override public long getCacheEvictions() {
+        return evictCnt;
     }
 
-    @Override
-    public float getAverageGetTime() {
+    /** {@inheritDoc} */
+    @Override public float getAverageGetTime() {
         return 0;
     }
 
-    @Override
-    public float getAveragePutTime() {
+    /** {@inheritDoc} */
+    @Override public float getAveragePutTime() {
         return 0;
     }
 
-    @Override
-    public float getAverageRemoveTime() {
+    /** {@inheritDoc} */
+    @Override public float getAverageRemoveTime() {
         return 0;
     }
 
@@ -286,6 +285,16 @@ public class GridCacheMetricsAdapter implements 
GridCacheMetrics, Externalizable
     }
 
     /**
+     * Cache remove callback.
+     */
+    public void onEvict() {
+        evictCnt++;
+
+        if (delegate != null)
+            delegate.onEvict();
+    }
+
+    /**
      * Transaction commit callback.
      */
     public void onTxCommit() {
@@ -336,6 +345,8 @@ public class GridCacheMetricsAdapter implements 
GridCacheMetrics, Externalizable
         out.writeInt(misses);
         out.writeInt(txCommits);
         out.writeInt(txRollbacks);
+        out.writeLong(rmCnt);
+        out.writeLong(evictCnt);
     }
 
     /** {@inheritDoc} */
@@ -352,6 +363,8 @@ public class GridCacheMetricsAdapter implements 
GridCacheMetrics, Externalizable
         misses = in.readInt();
         txCommits = in.readInt();
         txRollbacks = in.readInt();
+        rmCnt = in.readLong();
+        evictCnt = in.readLong();
     }
 
     /** {@inheritDoc} */

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/c04013d9/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheTtlManager.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheTtlManager.java
 
b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheTtlManager.java
index 20791e2..33ead3a 100644
--- 
a/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheTtlManager.java
+++ 
b/modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheTtlManager.java
@@ -127,6 +127,8 @@ public class GridCacheTtlManager<K, V> extends 
GridCacheManagerAdapter<K, V> {
                         if (wrapper.entry.onTtlExpired(obsoleteVer))
                             
wrapper.entry.context().cache().removeEntry(wrapper.entry);
 
+                        wrapper.entry.context().cache().metrics0().onEvict();
+
                         it.remove();
                     }
                     else

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/c04013d9/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractMetricsSelfTest.java
----------------------------------------------------------------------
diff --git 
a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractMetricsSelfTest.java
 
b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractMetricsSelfTest.java
index 33fa252..5173837 100644
--- 
a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractMetricsSelfTest.java
+++ 
b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractMetricsSelfTest.java
@@ -18,7 +18,16 @@
 package org.gridgain.grid.kernal.processors.cache;
 
 import org.apache.ignite.*;
+import org.apache.ignite.transactions.*;
 import org.gridgain.grid.cache.*;
+import org.gridgain.grid.util.lang.*;
+import org.gridgain.grid.util.typedef.internal.*;
+import org.gridgain.testframework.*;
+
+import javax.cache.expiry.*;
+import java.util.*;
+
+import static java.util.concurrent.TimeUnit.*;
 
 /**
  * Cache metrics test.
@@ -134,6 +143,41 @@ public abstract class GridCacheAbstractMetricsSelfTest 
extends GridCacheAbstract
         assertEquals(expMisses, misses);
     }
 
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testMissHitPercentage() throws Exception {
+        GridCache<Integer, Integer> cache0 = grid(0).cache(null);
+
+        int keyCnt = keyCount();
+
+        // Put and get a few keys.
+        for (int i = 0; i < keyCnt; i++) {
+            cache0.put(i, i); // +1 read
+
+            info("Writes: " + cache0.metrics().writes());
+
+            for (int j = 0; j < gridCount(); j++) {
+                GridCache<Integer, Integer> cache = grid(j).cache(null);
+
+                int cacheWrites = cache.metrics().writes();
+
+                assertEquals("Wrong cache metrics [i=" + i + ", grid=" + j + 
']', i + 1, cacheWrites);
+            }
+
+            assertEquals("Wrong value for key: " + i, Integer.valueOf(i), 
cache0.get(i)); // +1 read
+        }
+
+        // Check metrics for the whole cache.
+        for (int i = 0; i < gridCount(); i++) {
+            GridCacheMetrics m = grid(i).cache(null).metrics();
+
+            assertEquals(m.getCacheHits() * 100f / m.getCacheGets(), 
m.getCacheHitPercentage(), 0.1f);
+            assertEquals(m.getCacheMisses() * 100f / m.getCacheGets(), 
m.getCacheMissPercentage(), 0.1f);
+        }
+    }
+
     /**
      * @throws Exception If failed.
      */
@@ -216,6 +260,9 @@ public abstract class GridCacheAbstractMetricsSelfTest 
extends GridCacheAbstract
         assertEquals("Expected 1 hit", 1, cache.metrics().hits());
     }
 
+    /**
+     * @throws Exception If failed.
+     */
     public void testRemoves() throws Exception {
         GridCache<Integer, Integer> cache = grid(0).cache(null);
 
@@ -224,6 +271,266 @@ public abstract class GridCacheAbstractMetricsSelfTest 
extends GridCacheAbstract
         // +1 remove
         cache.remove(1);
 
-        assert cache.metrics().getCacheRemovals() == 1;
+        assertEquals(1L, cache.metrics().getCacheRemovals());
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testManualEvictions() throws Exception {
+        GridCache<Integer, Integer> cache = grid(0).cache(null);
+
+        if (cache.configuration().getCacheMode() == GridCacheMode.PARTITIONED)
+            return;
+
+        cache.put(1, 1);
+
+        cache.evict(1);
+
+        assertEquals(0L, cache.metrics().getCacheRemovals());
+        assertEquals(1L, cache.metrics().getCacheEvictions());
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testTxEvictions() throws Exception {
+        if (grid(0).cache(null).configuration().getAtomicityMode() != 
GridCacheAtomicityMode.ATOMIC)
+            checkTtl(true);
+    }
+
+    /**
+     * @throws Exception If failed.
+     */
+    public void testNonTxEvictions() throws Exception {
+        if (grid(0).cache(null).configuration().getAtomicityMode() == 
GridCacheAtomicityMode.ATOMIC)
+            checkTtl(false);
+    }
+
+    /**
+     * @param inTx
+     * @throws Exception If failed.
+     */
+    private void checkTtl(boolean inTx) throws Exception {
+        int ttl = 1000;
+
+        final ExpiryPolicy expiry = new TouchedExpiryPolicy(new 
Duration(MILLISECONDS, ttl));
+
+        final GridCache<Integer, Integer> c = grid(0).cache(null);
+
+        final Integer key = primaryKeysForCache(c, 1, 0).get(0);
+
+        c.put(key, 1);
+
+        GridCacheEntry<Integer, Integer> entry = c.entry(key);
+
+        assert entry != null;
+
+        assertEquals(0, entry.timeToLive());
+        assertEquals(0, entry.expirationTime());
+        assertEquals(0, grid(0).cache(null).metrics().getCacheEvictions());
+
+        long startTime = System.currentTimeMillis();
+
+        if (inTx) {
+            // Rollback transaction for the first time.
+            IgniteTx tx = grid(0).transactions().txStart();
+
+            try {
+                grid(0).jcache(null).withExpiryPolicy(expiry).put(key, 1);
+            }
+            finally {
+                tx.rollback();
+            }
+
+            assertEquals(0, entry.timeToLive());
+            assertEquals(0, entry.expirationTime());
+        }
+
+        // Now commit transaction and check that ttl and expire time have been 
saved.
+        IgniteTx tx = inTx ? c.txStart() : null;
+
+        try {
+            grid(0).jcache(null).withExpiryPolicy(expiry).put(key, 1);
+        }
+        finally {
+            if (tx != null)
+                tx.commit();
+        }
+
+        long[] expireTimes = new long[gridCount()];
+
+        for (int i = 0; i < gridCount(); i++) {
+            GridCacheEntry<Object, Object> curEntry = 
grid(i).cache(null).entry(key);
+
+            if (curEntry.primary() || curEntry.backup()) {
+                assertEquals(ttl, curEntry.timeToLive());
+
+                assert curEntry.expirationTime() > startTime;
+
+                expireTimes[i] = curEntry.expirationTime();
+            }
+        }
+
+        // One more update from the same cache entry to ensure that expire 
time is shifted forward.
+        U.sleep(100);
+
+        tx = inTx ? c.txStart() : null;
+
+        try {
+            grid(0).jcache(null).withExpiryPolicy(expiry).put(key, 2);
+        }
+        finally {
+            if (tx != null)
+                tx.commit();
+        }
+
+        for (int i = 0; i < gridCount(); i++) {
+            GridCacheEntry<Object, Object> curEntry = 
grid(i).cache(null).entry(key);
+
+            if (curEntry.primary() || curEntry.backup()) {
+                assertEquals(ttl, curEntry.timeToLive());
+
+                assert curEntry.expirationTime() > expireTimes[i];
+
+                expireTimes[i] = curEntry.expirationTime();
+            }
+        }
+
+        // And one more direct update to ensure that expire time is shifted 
forward.
+        U.sleep(100);
+
+        assertEquals(0, grid(0).cache(null).metrics().getCacheEvictions());
+
+        tx = inTx ? c.txStart() : null;
+
+        try {
+            grid(0).jcache(null).withExpiryPolicy(expiry).put(key, 3);
+        }
+        finally {
+            if (tx != null)
+                tx.commit();
+        }
+
+        for (int i = 0; i < gridCount(); i++) {
+            GridCacheEntry<Object, Object> curEntry = 
grid(i).cache(null).entry(key);
+
+            if (curEntry.primary() || curEntry.backup()) {
+                assertEquals(ttl, curEntry.timeToLive());
+
+                assert curEntry.expirationTime() > expireTimes[i];
+
+                expireTimes[i] = curEntry.expirationTime();
+            }
+        }
+
+        // And one more update to ensure that ttl is not changed and expire 
time is not shifted forward.
+        U.sleep(100);
+
+        assertEquals(0, grid(0).cache(null).metrics().getCacheEvictions());
+
+        log.info("Put 4");
+
+        tx = inTx ? c.txStart() : null;
+
+        try {
+            grid(0).jcache(null).put(key, 4);
+        }
+        finally {
+            if (tx != null)
+                tx.commit();
+        }
+
+        log.info("Put 4 done");
+
+        for (int i = 0; i < gridCount(); i++) {
+            GridCacheEntry<Object, Object> curEntry = 
grid(i).cache(null).entry(key);
+
+            if (curEntry.primary() || curEntry.backup()) {
+                assertEquals(ttl, curEntry.timeToLive());
+                assertEquals(expireTimes[i], curEntry.expirationTime());
+            }
+        }
+
+        assertEquals(0, grid(0).cache(null).metrics().getCacheEvictions());
+
+        // Avoid reloading from store.
+        map.remove(key);
+
+        assertTrue(GridTestUtils.waitForCondition(new GridAbsPredicateX() {
+            @SuppressWarnings("unchecked")
+            @Override
+            public boolean applyx() throws IgniteCheckedException {
+                try {
+                    if (c.get(key) != null)
+                        return false;
+
+                    // Get "cache" field from GridCacheProxyImpl.
+                    GridCacheAdapter c0 = GridTestUtils.getFieldValue(c, 
"cache");
+
+                    if (!c0.context().deferredDelete()) {
+                        GridCacheEntryEx e0 = c0.peekEx(key);
+
+                        return e0 == null || (e0.rawGet() == null && 
e0.valueBytes() == null);
+                    } else
+                        return true;
+                } catch (GridCacheEntryRemovedException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        }, Math.min(ttl * 10, getTestTimeout())));
+
+        // Ensure that old TTL and expire time are not longer "visible".
+        entry = c.entry(key);
+
+        assertEquals(0, entry.timeToLive());
+        assertEquals(0, entry.expirationTime());
+
+        // Ensure that next update will not pick old expire time.
+
+        tx = inTx ? c.txStart() : null;
+
+        try {
+            entry.set(10);
+        }
+        finally {
+            if (tx != null)
+                tx.commit();
+        }
+
+        U.sleep(2000);
+
+        entry = c.entry(key);
+
+        assertEquals((Integer)10, entry.get());
+
+        assertEquals(0, entry.timeToLive());
+        assertEquals(0, entry.expirationTime());
+
+        if (c.configuration().getCacheMode() != GridCacheMode.PARTITIONED && 
inTx)
+            assertEquals(1, grid(0).cache(null).metrics().getCacheEvictions());
+    }
+
+    /**
+     * @param cache Cache.
+     * @param cnt Keys count.
+     * @param startFrom Start value for keys search.
+     * @return Collection of keys for which given cache is primary.
+     * @throws IgniteCheckedException If failed.
+     */
+    protected List<Integer> primaryKeysForCache(GridCacheProjection<Integer, 
Integer> cache, int cnt, int startFrom)
+            throws IgniteCheckedException {
+        List<Integer> found = new ArrayList<>(cnt);
+
+        for (int i = startFrom; i < startFrom + 100_000; i++) {
+            if (cache.entry(i).primary()) {
+                found.add(i);
+
+                if (found.size() == cnt)
+                    return found;
+            }
+        }
+
+        throw new IgniteCheckedException("Unable to find " + cnt + " keys as 
primary for cache.");
     }
 }

Reply via email to