Index: modules/core/src/main/java/org/gridgain/grid/cache/GridCacheMetrics.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/main/java/org/gridgain/grid/cache/GridCacheMetrics.java (date 1421060738000) +++ modules/core/src/main/java/org/gridgain/grid/cache/GridCacheMetrics.java (date 1419411634000) @@ -9,13 +9,14 @@ package org.gridgain.grid.cache; +import javax.cache.management.*; import java.io.*; /** * Cache metrics used to obtain statistics on cache itself. * Use {@link GridCache#metrics()} to obtain metrics for a cache. */ -public interface GridCacheMetrics extends Serializable { +public interface GridCacheMetrics extends CacheStatisticsMXBean, Serializable { /** * Gets create time of the owning entity (either cache or entry). * Index: modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java (date 1419587931000) +++ modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java (date 1419869244000) @@ -339,14 +339,24 @@ /** {@inheritDoc} */ @Override public V get(K key) { try { + boolean statisticsEnabled = ctx.config().isStatisticsEnabled(); + long start = statisticsEnabled ? System.nanoTime() : 0L; + GridCacheProjectionImpl prev = gate.enter(prj); + V res; + try { - return delegate.get(key); + res = delegate.get(key); } finally { gate.leave(prev); } + + if (statisticsEnabled) + ctx.cache().metrics0().addGetTimeNanos(System.nanoTime() - start); + + return res; } catch (IgniteCheckedException e) { throw cacheException(e); @@ -356,14 +366,24 @@ /** {@inheritDoc} */ @Override public Map getAll(Set keys) { try { + boolean statisticsEnabled = ctx.config().isStatisticsEnabled(); + long start = statisticsEnabled ? System.nanoTime() : 0L; + GridCacheProjectionImpl prev = gate.enter(prj); + Map res; + try { - return delegate.getAll(keys); + res = delegate.getAll(keys); } finally { gate.leave(prev); } + + if (statisticsEnabled) + ctx.cache().metrics0().addGetTimeNanos(System.nanoTime() - start); + + return res; } catch (IgniteCheckedException e) { throw cacheException(e); @@ -441,6 +461,9 @@ /** {@inheritDoc} */ @Override public void put(K key, V val) { try { + boolean statisticsEnabled = ctx.config().isStatisticsEnabled(); + long start = statisticsEnabled ? System.nanoTime() : 0L; + GridCacheProjectionImpl prev = gate.enter(prj); try { @@ -449,6 +472,9 @@ finally { gate.leave(prev); } + + if (statisticsEnabled) + ctx.cache().metrics0().addPutTimeNanos(System.nanoTime() - start); } catch (IgniteCheckedException e) { throw cacheException(e); @@ -458,15 +484,27 @@ /** {@inheritDoc} */ @Override public V getAndPut(K key, V val) { try { + boolean statisticsEnabled = ctx.config().isStatisticsEnabled(); + long start = statisticsEnabled ? System.nanoTime() : 0L; + GridCacheProjectionImpl prev = gate.enter(prj); + V ret; + try { - return delegate.put(key, val); + ret = delegate.put(key, val); } finally { gate.leave(prev); } + + if (statisticsEnabled) { + ctx.cache().metrics0().addPutTimeNanos(System.nanoTime() - start); + ctx.cache().metrics0().addGetTimeNanos(System.nanoTime() - start); - } + } + + return ret; + } catch (IgniteCheckedException e) { throw cacheException(e); } @@ -475,6 +513,9 @@ /** {@inheritDoc} */ @Override public void putAll(Map map) { try { + boolean statisticsEnabled = ctx.config().isStatisticsEnabled(); + long start = statisticsEnabled ? System.nanoTime() : 0L; + GridCacheProjectionImpl prev = gate.enter(prj); try { @@ -483,6 +524,9 @@ finally { gate.leave(prev); } + + if (statisticsEnabled) + ctx.cache().metrics0().addPutTimeNanos(System.nanoTime() - start); } catch (IgniteCheckedException e) { throw cacheException(e); @@ -492,14 +536,24 @@ /** {@inheritDoc} */ @Override public boolean putIfAbsent(K key, V val) { try { + boolean statisticsEnabled = ctx.config().isStatisticsEnabled(); + long start = statisticsEnabled ? System.nanoTime() : 0L; + GridCacheProjectionImpl prev = gate.enter(prj); + boolean stored; + try { - return delegate.putxIfAbsent(key, val); + stored = delegate.putxIfAbsent(key, val); } finally { gate.leave(prev); } + + if (statisticsEnabled && stored) + ctx.cache().metrics0().addPutTimeNanos(System.nanoTime() - start); + + return stored; } catch (IgniteCheckedException e) { throw cacheException(e); @@ -509,14 +563,24 @@ /** {@inheritDoc} */ @Override public boolean remove(K key) { try { + boolean statisticsEnabled = ctx.config().isStatisticsEnabled(); + long start = statisticsEnabled ? System.nanoTime() : 0L; + GridCacheProjectionImpl prev = gate.enter(prj); + boolean removed; + try { - return delegate.removex(key); + removed = delegate.removex(key); } finally { gate.leave(prev); } + + if (statisticsEnabled) + ctx.cache().metrics0().addRemoveTimeNanos(System.nanoTime() - start); + + return removed; } catch (IgniteCheckedException e) { throw cacheException(e); @@ -526,14 +590,24 @@ /** {@inheritDoc} */ @Override public boolean remove(K key, V oldVal) { try { + boolean statisticsEnabled = ctx.config().isStatisticsEnabled(); + long start = statisticsEnabled ? System.nanoTime() : 0L; + GridCacheProjectionImpl prev = gate.enter(prj); + boolean removed; + try { - return delegate.remove(key, oldVal); + removed = delegate.remove(key, oldVal); } finally { gate.leave(prev); } + + if (statisticsEnabled && removed) + ctx.cache().metrics0().addRemoveTimeNanos(System.nanoTime() - start); + + return removed; } catch (IgniteCheckedException e) { throw cacheException(e); @@ -543,14 +617,24 @@ /** {@inheritDoc} */ @Override public V getAndRemove(K key) { try { + boolean statisticsEnabled = ctx.config().isStatisticsEnabled(); + long start = statisticsEnabled ? System.nanoTime() : 0L; + GridCacheProjectionImpl prev = gate.enter(prj); + V removed; + try { - return delegate.remove(key); + removed = delegate.remove(key); } finally { gate.leave(prev); } + + if (statisticsEnabled) + ctx.cache().metrics0().addRemoveTimeNanos(System.nanoTime() - start); + + return removed; } catch (IgniteCheckedException e) { throw cacheException(e); @@ -611,6 +695,9 @@ /** {@inheritDoc} */ @Override public void removeAll(Set keys) { try { + boolean statisticsEnabled = ctx.config().isStatisticsEnabled(); + long start = statisticsEnabled ? System.nanoTime() : 0L; + GridCacheProjectionImpl prev = gate.enter(prj); try { @@ -619,6 +706,9 @@ finally { gate.leave(prev); } + + if (statisticsEnabled) + ctx.cache().metrics0().addRemoveTimeNanos(System.nanoTime() - start); } catch (IgniteCheckedException e) { throw cacheException(e); Index: modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridCachePartitionedMetricsSelfTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridCachePartitionedMetricsSelfTest.java (date 1419587931000) +++ modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridCachePartitionedMetricsSelfTest.java (date 1419869244000) @@ -49,4 +49,14 @@ @Override protected int gridCount() { return GRID_CNT; } + + /** {@inheritDoc} */ + @Override public void testGetAllAvgTime() throws Exception { + //TODO: GG-7578 + } + + /** {@inheritDoc} */ + @Override public void testGetAvgTime() throws Exception { + //TODO: GG-7578 + } } Index: modules/core/src/main/java/org/apache/ignite/IgniteCacheManager.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/main/java/org/apache/ignite/IgniteCacheManager.java (date 1421053506000) +++ modules/core/src/main/java/org/apache/ignite/IgniteCacheManager.java (date 1421053506000) @@ -0,0 +1,269 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite; + +import org.apache.ignite.cache.*; +import org.gridgain.grid.cache.*; + +import javax.cache.*; +import javax.cache.configuration.*; +import javax.cache.spi.*; +import javax.management.*; +import java.net.*; +import java.util.*; + +/** + * + */ +public class IgniteCacheManager implements CacheManager { + /** */ + private final URI uri; + + /** + * @param uri Uri. + */ + public IgniteCacheManager(URI uri) { + this.uri = uri; + } + + /** {@inheritDoc} */ + @Override public void enableManagement(String cacheName, boolean enabled) { + Ignite ignite = findIgnite(cacheName); + + IgniteCache jcache = ignite.jcache(cacheName); + + MBeanServer mBeanSrv = ignite.configuration().getMBeanServer(); + + GridCacheConfiguration configuration = + (GridCacheConfiguration) jcache.getConfiguration(GridCacheConfiguration.class); + + if (cacheName == null) + cacheName = "null"; + + if (enabled) { + CacheConfigurationMXBean mxBean = new CacheConfigurationMXBean(configuration); + + registerCacheObject(mBeanSrv, mxBean, uri.toString(), cacheName, false); + + configuration.setManagementEnabled(true); + } + else { + unregisterCacheObject(mBeanSrv, uri.toString(), cacheName, false); + + configuration.setManagementEnabled(false); + } + } + + /** {@inheritDoc} */ + @Override public void enableStatistics(String cacheName, boolean enabled) { + Ignite ignite = findIgnite(cacheName); + + GridCache cache = ignite.cache(cacheName); + + GridCacheConfiguration configuration = ignite.jcache(cacheName).getConfiguration(GridCacheConfiguration.class); + + MBeanServer mBeanSrv = ignite.configuration().getMBeanServer(); + + if (cacheName == null) + cacheName = "null"; + + if (enabled) { + CacheMetricsMXBean mxBean = new CacheMetricsMXBean(cache); + + registerCacheObject(mBeanSrv, mxBean, uri.toString(), cacheName, true); + + configuration.setStatisticsEnabled(true); + } + else { + unregisterCacheObject(mBeanSrv, uri.toString(), cacheName, true); + + configuration.setStatisticsEnabled(false); + } + } + + /** + * Finds node which has the cache. + * + * @param cacheName Cache name. + * @return Ignite node. + */ + private Ignite findIgnite(String cacheName) { + for (Ignite ignite : Ignition.allGrids()) + if (ignite.jcache(cacheName) != null) + return ignite; + + return null; + } + + /** + * @param mxbean MXBean. + * @param cacheManagerName name generated by URI and classloader. + * @param name cache name. + */ + public static void registerCacheObject(MBeanServer mBeanServer, Object mxbean, String cacheManagerName, String name, + boolean stats) { + ObjectName registeredObjectName = calculateObjectName(cacheManagerName, name, stats); + + try { + if (!isRegistered(mBeanServer, registeredObjectName)) { + mBeanServer.registerMBean(mxbean, registeredObjectName); + + System.out.println("Registered mbean with name " + registeredObjectName.toString()); + } + } + catch (Exception e) { + throw new CacheException("Error registering cache MXBeans for CacheManager " + registeredObjectName + + " . Error was " + e.getMessage(), e); + } + } + + /** + * @return {@code True} if MBean registered. + */ + private static boolean isRegistered(MBeanServer mBeanServer, ObjectName objectName) { + return !mBeanServer.queryNames(objectName, null).isEmpty(); + } + + /** + * UnRegisters the mxbean if registered already. + * + * @param mBeanSrv MBean server + * @param cacheManagerName name generated by URI and classloader. + * @param name cache name. + * @param stats is mxbean, a statistics mxbean. + */ + public static void unregisterCacheObject(MBeanServer mBeanSrv, String cacheManagerName, String name, boolean stats) { + Set registeredObjectNames = null; + + ObjectName objectName = calculateObjectName(cacheManagerName, name, stats); + registeredObjectNames = mBeanSrv.queryNames(objectName, null); + + System.out.println("Try UnRegistered mbean with name " + objectName.toString()); + + //should just be one + for (ObjectName registeredObjectName : registeredObjectNames) { + try { + mBeanSrv.unregisterMBean(registeredObjectName); + } catch (Exception e) { + throw new CacheException("Error unregistering object instance " + registeredObjectName + + " . Error was " + e.getMessage(), e); + } + } + } + + /** + * Creates an object name. + */ + private static ObjectName calculateObjectName(String cacheManagerName, String name, boolean stats) { + String cacheManagerNameSafe = mbeanSafe(cacheManagerName); + String cacheName = mbeanSafe(name); + + try { + String objectNameType = stats ? "Statistics" : "Configuration"; + return new ObjectName( + "javax.cache:type=Cache" + objectNameType + ",CacheManager=" + cacheManagerNameSafe + ",Cache=" + cacheName); + } catch (MalformedObjectNameException e) { + throw new CacheException( + "Illegal ObjectName for Management Bean. " + "CacheManager=[" + cacheManagerNameSafe + "], Cache=[" + + cacheName + "]", e); + } + } + + /** + * + */ + private static String mbeanSafe(String string) { + return string == null ? "" : string.replaceAll(",|:|=|\n", "."); + } + + /** + * @param cacheName Cache name. + */ + private ObjectName getObjectName(String cacheName) { + String mBeanName = "javax.cache:type=CacheConfiguration,CacheManager=" + + uri.toString().replaceAll(",|:|=|\n", ".") + + ",Cache=" + cacheName.replaceAll(",|:|=|\n", "."); + + try { + return new ObjectName(mBeanName); + } + catch (MalformedObjectNameException e) { + throw new CacheException("Failed to create MBean name: " + mBeanName, e); + } + } + + /** {@inheritDoc} */ + @Override public CachingProvider getCachingProvider() { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public URI getURI() { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public ClassLoader getClassLoader() { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public Properties getProperties() { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public > Cache createCache(String cacheName, C cacheCfg) + throws IllegalArgumentException { + throw new UnsupportedOperationException(); + } + + /** + * @param cacheName Cache name. + */ + private IgniteCache findCache(String cacheName) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public Cache getCache(String cacheName, Class keyType, Class valType) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public Cache getCache(String cacheName) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public Iterable getCacheNames() { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public void destroyCache(String cacheName) { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public void close() { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public boolean isClosed() { + throw new UnsupportedOperationException(); + } + + /** {@inheritDoc} */ + @Override public T unwrap(Class clazz) { + throw new UnsupportedOperationException(); + } +} Index: modules/core/src/main/java/org/apache/ignite/cache/CacheConfigurationMXBean.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/main/java/org/apache/ignite/cache/CacheConfigurationMXBean.java (date 1421053506000) +++ modules/core/src/main/java/org/apache/ignite/cache/CacheConfigurationMXBean.java (date 1421053506000) @@ -0,0 +1,71 @@ +// @java.file.header + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite.cache; + +import org.gridgain.grid.cache.GridCacheConfiguration; + +import javax.cache.management.*; + +/** + * Implementation of {@link CacheMXBean}. + * + * It's a simple wrapper around {@link GridCacheConfiguration} for readonly + * access to cache configuration. + */ +public class CacheConfigurationMXBean implements CacheMXBean { + /** + * + */ + private final GridCacheConfiguration cacheCfg; + + /** + * Constructor. + * + * @param cacheCfg The cache configuration. + */ + public CacheConfigurationMXBean(GridCacheConfiguration cacheCfg) { + this.cacheCfg = cacheCfg; + } + + /** {@inheritDoc} */ + @Override public String getKeyType() { + return cacheCfg.getKeyType().getName(); + } + + /** {@inheritDoc} */ + @Override public String getValueType() { + return cacheCfg.getValueType().getName(); + } + + /** {@inheritDoc} */ + @Override public boolean isReadThrough() { + return cacheCfg.isReadThrough(); + } + + /** {@inheritDoc} */ + @Override public boolean isWriteThrough() { + return cacheCfg.isWriteThrough(); + } + + /** {@inheritDoc} */ + @Override public boolean isStoreByValue() { + return cacheCfg.isStoreByValue(); + } + + /** {@inheritDoc} */ + @Override public boolean isStatisticsEnabled() { + return cacheCfg.isStatisticsEnabled(); + } + + /** {@inheritDoc} */ + @Override public boolean isManagementEnabled() { + return cacheCfg.isManagementEnabled(); + } +} Index: modules/core/src/main/java/org/apache/ignite/cache/CacheMetricsMXBean.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/main/java/org/apache/ignite/cache/CacheMetricsMXBean.java (date 1421053506000) +++ modules/core/src/main/java/org/apache/ignite/cache/CacheMetricsMXBean.java (date 1421053506000) @@ -0,0 +1,94 @@ +/* @java.file.header */ + +/* _________ _____ __________________ _____ + * __ ____/___________(_)______ /__ ____/______ ____(_)_______ + * _ / __ __ ___/__ / _ __ / _ / __ _ __ `/__ / __ __ \ + * / /_/ / _ / _ / / /_/ / / /_/ / / /_/ / _ / _ / / / + * \____/ /_/ /_/ \_,__/ \____/ \__,_/ /_/ /_/ /_/ + */ + +package org.apache.ignite.cache; + +import org.gridgain.grid.cache.GridCache; + +import javax.cache.management.*; + +/** + * Implementation of {@link CacheStatisticsMXBean}. + */ +public class CacheMetricsMXBean implements CacheStatisticsMXBean { + + /** + * Grid cache. + */ + private final GridCache cache; + + /** + * Constructor. + * + * @param cache GridCache + */ + public CacheMetricsMXBean(GridCache cache) { + this.cache = cache; + } + + /** {@inheritDoc} */ + @Override public void clear() { + cache.resetMetrics(); + } + + /** {@inheritDoc} */ + @Override public long getCacheHits() { + return cache.metrics().hits(); + } + + /** {@inheritDoc} */ + @Override public float getCacheHitPercentage() { + return cache.metrics().getCacheHitPercentage(); + } + + /** {@inheritDoc} */ + @Override public long getCacheMisses() { + return cache.metrics().getCacheMisses(); + } + + /** {@inheritDoc} */ + @Override public float getCacheMissPercentage() { + return cache.metrics().getCacheMissPercentage(); + } + + /** {@inheritDoc} */ + @Override public long getCacheGets() { + return cache.metrics().getCacheGets(); + } + + /** {@inheritDoc} */ + @Override public long getCachePuts() { + return cache.metrics().getCachePuts(); + } + + /** {@inheritDoc} */ + @Override public long getCacheRemovals() { + return cache.metrics().getCacheRemovals(); + } + + /** {@inheritDoc} */ + @Override public long getCacheEvictions() { + return cache.metrics().getCacheEvictions(); + } + + /** {@inheritDoc} */ + @Override public float getAverageGetTime() { + return cache.metrics().getAverageGetTime(); + } + + /** {@inheritDoc} */ + @Override public float getAveragePutTime() { + return cache.metrics().getAveragePutTime(); + } + + /** {@inheritDoc} */ + @Override public float getAverageRemoveTime() { + return cache.metrics().getAverageRemoveTime(); + } +} Index: modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMetricsAdapter.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMetricsAdapter.java (date 1421060738000) +++ modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMetricsAdapter.java (date 1421053506000) @@ -21,6 +21,9 @@ */ public class GridCacheMetricsAdapter implements GridCacheMetrics, Externalizable { /** */ + private static final long NANOS_IN_MICROSECOND = 1000L; + + /** */ private static final long serialVersionUID = 0L; /** Create time. */ @@ -56,6 +59,21 @@ /** Number of transaction rollbacks. */ private volatile int txRollbacks; + /** Number of evictions. */ + private volatile long evictCnt; + + /** Number of removed entries. */ + private volatile long rmCnt; + + /** Put time taken nanos. */ + private volatile long putTimeNanos; + + /** Get time taken nanos. */ + private volatile long getTimeNanos; + + /** Remove time taken nanos. */ + private volatile long removeTimeNanos; + /** Cache metrics. */ @GridToStringExclude private transient GridCacheMetricsAdapter delegate; @@ -70,7 +88,7 @@ /** * @param m Metrics to copy from. */ - public GridCacheMetricsAdapter(GridCacheMetrics m) { + public GridCacheMetricsAdapter(GridCacheMetricsAdapter m) { createTime = m.createTime(); readTime = m.readTime(); writeTime = m.writeTime(); @@ -82,6 +100,11 @@ misses = m.misses(); txCommits = m.txCommits(); txRollbacks = m.txRollbacks(); + rmCnt = m.getCacheRemovals(); + evictCnt = m.getCacheEvictions(); + getTimeNanos = m.getTimeNanos(); + putTimeNanos = m.putTimeNanos(); + removeTimeNanos = m.removeTimeNanos(); } /** @@ -123,7 +146,7 @@ /** {@inheritDoc} */ @Override public int writes() { - return writes; + return (int)(writes + rmCnt); } /** {@inheritDoc} */ @@ -146,7 +169,132 @@ return txRollbacks; } + /** {@inheritDoc} */ + @Override public void clear() { + createTime = U.currentTimeMillis(); + readTime = createTime; + writeTime = createTime; + commitTime = createTime; + rollbackTime = createTime; + reads = 0; + writes = 0; + hits = 0; + misses = 0; + txCommits = 0; + txRollbacks = 0; + } + + /** {@inheritDoc} */ + @Override public long getCacheHits() { + return hits; + } + + /** {@inheritDoc} */ + @Override public float getCacheHitPercentage() { + long hits0 = hits; + + if (hits0 == 0) + return 0; + + return (float) hits0 / getCacheGets() * 100.0f; + } + + /** {@inheritDoc} */ + @Override public long getCacheMisses() { + return misses; + } + + /** {@inheritDoc} */ + @Override public float getCacheMissPercentage() { + long misses0 = misses; + + if (misses0 == 0) + return 0; + + return (float) misses0 / getCacheGets() * 100.0f; + } + + /** {@inheritDoc} */ + @Override public long getCacheGets() { + return reads; + } + + /** {@inheritDoc} */ + @Override public long getCachePuts() { + return writes; + } + + /** {@inheritDoc} */ + @Override public long getCacheRemovals() { + return rmCnt; + } + + /** {@inheritDoc} */ + @Override public long getCacheEvictions() { + return evictCnt; + } + /** + * Increments the get time accumulator. + * + * @param duration the time taken in nanoseconds. + */ + public void addGetTimeNanos(long duration) { + getTimeNanos += duration; + } + + /** + * Increments the put time accumulator. + * + * @param duration the time taken in nanoseconds. + */ + public void addPutTimeNanos(long duration) { + putTimeNanos += duration; + } + + /** + * Increments the remove time accumulator. + * + * @param duration the time taken in nanoseconds. + */ + public void addRemoveTimeNanos(long duration) { + removeTimeNanos += duration; + } + + @Override + public float getAverageGetTime() { + long timeNanos = getTimeNanos; + long readsCnt = reads; + + if (timeNanos == 0 || readsCnt == 0) + return 0; + + return ((1f * timeNanos) / readsCnt) / NANOS_IN_MICROSECOND; + } + + @Override + public float getAveragePutTime() { + long timeNanos = putTimeNanos; + long putsCnt = writes; + + if (timeNanos == 0 || putsCnt == 0) + return 0; + + return ((1f * timeNanos) / putsCnt) / NANOS_IN_MICROSECOND; + } + + @Override + public float getAverageRemoveTime() { + long timeNanos = removeTimeNanos; + long removesCnt = rmCnt; + + if (timeNanos == 0 || removesCnt == 0) + return 0; + + return ((1f * timeNanos) / removesCnt) / NANOS_IN_MICROSECOND; + } + + /** * Cache read callback. * @param isHit Hit or miss flag. */ @@ -177,6 +325,28 @@ } /** + * Cache remove callback. + */ + public void onRemove(){ + writeTime = U.currentTimeMillis(); + + rmCnt++; + + if (delegate != null) + delegate.onRemove(); + } + + /** + * Cache remove callback. + */ + public void onEvict() { + evictCnt++; + + if (delegate != null) + delegate.onEvict(); + } + + /** * Transaction commit callback. */ public void onTxCommit() { @@ -201,12 +371,39 @@ } /** + * Gets remove time. + * + * @return Remove time taken nanos. + */ + public long removeTimeNanos() { + return removeTimeNanos; + } + + /** + * Gets get time. + * + * @return Get time taken nanos. + */ + public long getTimeNanos() { + return getTimeNanos; + } + + /** + * Gets put time. + * + * @return Get time taken nanos. + */ + public long putTimeNanos() { + return putTimeNanos; + } + + /** * Create a copy of given metrics object. * * @param m Metrics to copy from. * @return Copy of given metrics. */ - @Nullable public static GridCacheMetricsAdapter copyOf(@Nullable GridCacheMetrics m) { + @Nullable public static GridCacheMetricsAdapter copyOf(@Nullable GridCacheMetricsAdapter m) { if (m == null) return null; @@ -227,6 +424,8 @@ out.writeInt(misses); out.writeInt(txCommits); out.writeInt(txRollbacks); + out.writeLong(rmCnt); + out.writeLong(evictCnt); } /** {@inheritDoc} */ @@ -243,6 +442,8 @@ misses = in.readInt(); txCommits = in.readInt(); txRollbacks = in.readInt(); + rmCnt = in.readLong(); + evictCnt = in.readLong(); } /** {@inheritDoc} */ Index: modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractMetricsSelfTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractMetricsSelfTest.java (date 1421060738000) +++ modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractMetricsSelfTest.java (date 1421053506000) @@ -10,8 +10,19 @@ 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 javax.management.*; +import java.net.*; +import java.util.*; + +import static java.util.concurrent.TimeUnit.*; + /** * Cache metrics test. */ @@ -68,9 +79,264 @@ } } + /** {@inheritDoc} */ + @Override protected void beforeTest() throws Exception { + super.beforeTest(); + + for (int i = 0; i < gridCount(); i++) { + Ignite g = grid(i); + + g.cache(null).configuration().setStatisticsEnabled(true); + } + } + /** * @throws Exception If failed. */ + public void testRemoveAvgTime() throws Exception { + IgniteCache jcache = grid(0).jcache(null); + GridCache cache = grid(0).cache(null); + + jcache.put(1, 1); + jcache.put(2, 2); + + assertEquals(cache.metrics().getAverageRemoveTime(), 0.0, 0.0); + + long start = System.nanoTime(); + + jcache.remove(1); + + float times = (System.nanoTime() - start) * 1.f / 1000; + + float avgRmvTime = cache.metrics().getAverageRemoveTime(); + + assert avgRmvTime > 0; + + assertEquals(times, avgRmvTime, times / 10); + + jcache.remove(2); + + assert cache.metrics().getAverageRemoveTime() > 0; + } + + /** + * @throws Exception If failed. + */ + public void testRemoveAllAvgTime() throws Exception { + IgniteCache jcache = grid(0).jcache(null); + GridCache cache = grid(0).cache(null); + + jcache.put(1, 1); + jcache.put(2, 2); + jcache.put(3, 3); + + assertEquals(cache.metrics().getAverageRemoveTime(), 0.0, 0.0); + + long start = System.nanoTime(); + + Set keys = new HashSet<>(4, 1); + keys.add(1); + keys.add(2); + keys.add(3); + + jcache.removeAll(keys); + + float times = (System.nanoTime() - start) * 1.f / 3 / 1000; + + float averageRemoveTime = cache.metrics().getAverageRemoveTime(); + + assert averageRemoveTime > 0; + assertEquals(times, averageRemoveTime, times / 10); + } + + /** + * @throws Exception If failed. + */ + public void testGetAvgTime() throws Exception { + IgniteCache jcache = grid(0).jcache(null); + GridCache cache = grid(0).cache(null); + + jcache.put(1, 1); + + assertEquals(0.0, cache.metrics().getAverageGetTime(), 0.0); + assertEquals(0, cache.metrics().reads()); + + long start = System.nanoTime(); + + jcache.get(1); + + float times = (System.nanoTime() - start) * 1.f / 1000; + + float averageGetTime = cache.metrics().getAverageGetTime(); + + assert averageGetTime > 0; + + assertEquals(1, cache.metrics().reads()); + assertEquals(times, averageGetTime, times / 3); + + jcache.get(2); + + assert cache.metrics().getAverageGetTime() > 0; + } + + /** + * @throws Exception If failed. + */ + public void testStatisticMXBean() throws Exception { + IgniteCache jcache = grid(0).jcache(null); + + URI uri = URI.create("ignite://default"); + + IgniteCacheManager cacheManager = new IgniteCacheManager(uri); + + cacheManager.enableStatistics(null, true); + + ObjectName objectName = + new ObjectName("javax.cache:type=CacheStatistics,CacheManager=ignite.//default,Cache=null"); + + long cachePuts = (long)getConfiguration().getMBeanServer().getAttribute(objectName, "CachePuts"); + + assertEquals(0L, cachePuts); + + jcache.put(1, 1); + + cachePuts = (long)getConfiguration().getMBeanServer().getAttribute(objectName, "CachePuts"); + + assertEquals(1, cachePuts); + + cacheManager.enableStatistics(null, false); + } + + /** + * @throws Exception If failed. + */ + public void testCacheMxBean() throws Exception { + URI uri = URI.create("ignite://default"); + + IgniteCacheManager cacheManager = new IgniteCacheManager(uri); + + cacheManager.enableManagement(null, true); + + ObjectName objectName = + new ObjectName("javax.cache:type=CacheConfiguration,CacheManager=ignite.//default,Cache=null"); + + String keyType = (String)getConfiguration().getMBeanServer().getAttribute(objectName, "KeyType"); + assertEquals("java.lang.Object", keyType); + + String valueType = (String)getConfiguration().getMBeanServer().getAttribute(objectName, "ValueType"); + assertEquals("java.lang.Object", valueType); + + boolean readThrough = (boolean)getConfiguration().getMBeanServer().getAttribute(objectName, "ReadThrough"); + assertEquals(false, readThrough); + + boolean writeThrough = (boolean)getConfiguration().getMBeanServer().getAttribute(objectName, "WriteThrough"); + assertEquals(false, writeThrough); + + boolean storeByValue = (boolean)getConfiguration().getMBeanServer().getAttribute(objectName, "StoreByValue"); + assertEquals(true, storeByValue); + + boolean isStat = (boolean)getConfiguration().getMBeanServer().getAttribute(objectName, "StatisticsEnabled"); + assertEquals(true, isStat); + + boolean isMng = (boolean)getConfiguration().getMBeanServer().getAttribute(objectName, "ManagementEnabled"); + assertEquals(true, isMng); + + cacheManager.enableManagement(null, false); + } + + /** + * @throws Exception If failed. + */ + public void testGetAllAvgTime() throws Exception { + IgniteCache jcache = grid(0).jcache(null); + GridCache cache = grid(0).cache(null); + + jcache.put(1, 1); + jcache.put(2, 2); + jcache.put(3, 3); + + assertEquals(0.0, cache.metrics().getAverageGetTime(), 0.0); + assertEquals(0, cache.metrics().reads()); + + long start = System.nanoTime(); + + Set keys = new HashSet<>(); + keys.add(1); + keys.add(2); + keys.add(3); + + jcache.getAll(keys); + + float times = (System.nanoTime() - start) * 1.f / 3 / 1000; + + float averageGetTime = cache.metrics().getAverageGetTime(); + + assert averageGetTime > 0; + assertEquals(3, cache.metrics().reads()); + assertEquals(times, averageGetTime, times / 3); + } + + /** + * @throws Exception If failed. + */ + public void testPutAvgTime() throws Exception { + IgniteCache jcache = grid(0).jcache(null); + GridCache cache = grid(0).cache(null); + + assertEquals(0.0, cache.metrics().getAveragePutTime(), 0.0); + assertEquals(0, cache.metrics().writes()); + + long start = System.nanoTime(); + + jcache.put(1, 1); + + float times = (System.nanoTime() - start) * 1.f / 1000; + + float avgPutTime = cache.metrics().getAveragePutTime(); + + assert avgPutTime > 0; + + assertEquals(1, cache.metrics().writes()); + assertEquals(times, avgPutTime, times / 3); + + jcache.put(2, 2); + + assert cache.metrics().getAveragePutTime() > 0; + } + + /** + * @throws Exception If failed. + */ + public void testPutAllAvgTime() throws Exception { + IgniteCache jcache = grid(0).jcache(null); + GridCache cache = grid(0).cache(null); + + assertEquals(0.0, cache.metrics().getAveragePutTime(), 0.0); + assertEquals(0, cache.metrics().writes()); + + Map values = new HashMap<>(); + + values.put(1, 1); + values.put(2, 2); + values.put(3, 3); + + long start = System.nanoTime(); + + jcache.putAll(values); + + float times = (System.nanoTime() - start) * 1.f / 1000 / values.size(); + + float averagePutTime = cache.metrics().getAveragePutTime(); + + assert averagePutTime > 0; + + assertEquals(values.size(), cache.metrics().writes()); + assertEquals(times, averagePutTime, times / 3); + } + + /** + * @throws Exception If failed. + */ public void testWritesReads() throws Exception { GridCache cache0 = grid(0).cache(null); @@ -129,6 +395,40 @@ /** * @throws Exception If failed. */ + public void testMissHitPercentage() throws Exception { + GridCache 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 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. + */ public void testMisses() throws Exception { GridCache cache = grid(0).cache(null); @@ -206,5 +506,279 @@ assertEquals("Expected 3 reads", 3, cache.metrics().reads()); assertEquals("Expected 2 misses", 2, cache.metrics().misses()); assertEquals("Expected 1 hit", 1, cache.metrics().hits()); + } + + /** + * @throws Exception If failed. + */ + public void testRemoves() throws Exception { + GridCache cache = grid(0).cache(null); + + cache.put(1, 1); + + // +1 remove + cache.remove(1); + + assertEquals(1L, cache.metrics().getCacheRemovals()); + } + + /** + * @throws Exception If failed. + */ + public void testManualEvictions() throws Exception { + GridCache 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 c = grid(0).cache(null); + + final Integer key = primaryKeysForCache(c, 1, 0).get(0); + + c.put(key, 1); + + GridCacheEntry 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 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 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 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 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 primaryKeysForCache(GridCacheProjection cache, int cnt, int startFrom) + throws IgniteCheckedException { + List 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."); } } Index: modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEvictionManager.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEvictionManager.java (date 1419411634000) +++ modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheEvictionManager.java (date 1421072779000) @@ -660,6 +660,9 @@ cache.removeEntry(entry); + if (cache.configuration().isStatisticsEnabled()) + 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); Index: modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMapEntry.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMapEntry.java (date 1421060738000) +++ modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheMapEntry.java (date 1421072779000) @@ -764,11 +764,11 @@ } if (old == null && !hasOldBytes) { - if (updateMetrics) + if (updateMetrics && cctx.cache().configuration().isStatisticsEnabled()) cctx.cache().metrics0().onRead(false); } else { - if (updateMetrics) + if (updateMetrics && cctx.cache().configuration().isStatisticsEnabled()) cctx.cache().metrics0().onRead(true); // Set retVal here for event notification. @@ -1132,7 +1132,7 @@ recordNodeId(affNodeId); - if (metrics) + if (metrics && cctx.cache().configuration().isStatisticsEnabled()) cctx.cache().metrics0().onWrite(); if (evt && newVer != null && cctx.events().isRecordable(EVT_CACHE_OBJECT_PUT)) { @@ -1284,8 +1284,8 @@ drReplicate(drType, null, null, newVer); - if (metrics) - cctx.cache().metrics0().onWrite(); + if (metrics && cctx.cache().configuration().isStatisticsEnabled()) + cctx.cache().metrics0().onRemove(); if (tx == null) obsoleteVer = newVer; @@ -1436,7 +1436,7 @@ } // Apply metrics. - if (metrics && needVal) + if (metrics && cctx.cache().configuration().isStatisticsEnabled() && needVal) cctx.cache().metrics0().onRead(old != null); String transformCloClsName = null; @@ -1577,8 +1577,7 @@ res = hadVal; } - if (metrics) - cctx.cache().metrics0().onWrite(); + updateMetrics(op, metrics); cctx.continuousQueries().onEntryUpdate(this, key, val, valueBytesUnlocked(), old, oldBytes); @@ -1790,7 +1789,7 @@ } // Apply metrics. - if (metrics && needVal) + if (metrics && cctx.cache().configuration().isStatisticsEnabled() && needVal) cctx.cache().metrics0().onRead(old != null); // Calculate new value. @@ -2034,8 +2033,7 @@ newDrExpireTime = -1L; } - if (metrics) - cctx.cache().metrics0().onWrite(); + updateMetrics(op, metrics); if (primary || cctx.isReplicated()) cctx.continuousQueries().onEntryUpdate(this, key, val, valueBytesUnlocked(), old, oldBytes); @@ -4104,6 +4102,21 @@ protected void obsoleteVersionExtras(@Nullable GridCacheVersion obsoleteVer) { extras = (extras != null) ? extras.obsoleteVersion(obsoleteVer) : obsoleteVer != null ? new GridCacheObsoleteEntryExtras(obsoleteVer) : null; + } + + /** + * Updates metrics. + * + * @param op Operation. + * @param metrics Update merics flag. + */ + private void updateMetrics(GridCacheOperation op, boolean metrics) { + if (metrics && cctx.cache().configuration().isStatisticsEnabled()) { + if (op == DELETE) + cctx.cache().metrics0().onRemove(); + else + cctx.cache().metrics0().onWrite(); + } } /** Index: modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheTtlManager.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheTtlManager.java (date 1419411634000) +++ modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/GridCacheTtlManager.java (date 1421072779000) @@ -119,6 +119,9 @@ if (wrapper.entry.onTtlExpired(obsoleteVer)) wrapper.entry.context().cache().removeEntry(wrapper.entry); + if (wrapper.entry.context().cache().configuration().isStatisticsEnabled()) + wrapper.entry.context().cache().metrics0().onEvict(); + it.remove(); } else Index: modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearCacheEntry.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearCacheEntry.java (date 1421053506000) +++ modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearCacheEntry.java (date 1421072779000) @@ -352,7 +352,8 @@ synchronized (this) { checkObsolete(); + if (cctx.cache().configuration().isStatisticsEnabled()) - cctx.cache().metrics0().onRead(false); + cctx.cache().metrics0().onRead(false); boolean ret = false; Index: modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearGetFuture.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearGetFuture.java (date 1421053506000) +++ modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearGetFuture.java (date 1421072779000) @@ -457,12 +457,14 @@ dht.removeIfObsolete(key); } - if (v != null) + if (v != null) { + if (cctx.cache().configuration().isStatisticsEnabled()) - near.metrics0().onRead(true); + near.metrics0().onRead(true); + } else { primary = cctx.affinity().primary(key, topVer); - if (!primary.isLocal()) + if (!primary.isLocal() && cctx.cache().configuration().isStatisticsEnabled()) near.metrics0().onRead(false); } } Index: modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearLockFuture.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearLockFuture.java (date 1421053506000) +++ modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/distributed/near/GridNearLockFuture.java (date 1421072779000) @@ -1055,7 +1055,8 @@ null, inTx() ? tx.resolveTaskName() : null); + if (cctx.cache().configuration().isStatisticsEnabled()) - cctx.cache().metrics0().onRead(oldVal != null); + cctx.cache().metrics0().onRead(oldVal != null); } if (log.isDebugEnabled()) @@ -1416,7 +1417,8 @@ null, inTx() ? tx.resolveTaskName() : null); + if (cctx.cache().configuration().isStatisticsEnabled()) - cctx.cache().metrics0().onRead(false); + cctx.cache().metrics0().onRead(false); } if (log.isDebugEnabled()) Index: modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/local/atomic/GridLocalAtomicCache.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/local/atomic/GridLocalAtomicCache.java (date 1421053506000) +++ modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/local/atomic/GridLocalAtomicCache.java (date 1421072779000) @@ -594,7 +594,7 @@ success = false; } else { - if (!storeEnabled) + if (!storeEnabled && configuration().isStatisticsEnabled()) metrics0().onRead(false); success = false; Index: modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxManager.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxManager.java (date 1421053506000) +++ modules/core/src/main/java/org/gridgain/grid/kernal/processors/cache/transactions/IgniteTxManager.java (date 1421072779000) @@ -1248,7 +1248,8 @@ for (int cacheId : tx.activeCacheIds()) { GridCacheContext cacheCtx = cctx.cacheContext(cacheId); + if (cacheCtx.cache().configuration().isStatisticsEnabled()) - cacheCtx.cache().metrics0().onTxCommit(); + cacheCtx.cache().metrics0().onTxCommit(); } } @@ -1321,7 +1322,8 @@ for (int cacheId : tx.activeCacheIds()) { GridCacheContext cacheCtx = cctx.cacheContext(cacheId); + if (cacheCtx.cache().configuration().isStatisticsEnabled()) - cacheCtx.cache().metrics0().onTxRollback(); + cacheCtx.cache().metrics0().onTxRollback(); } }