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

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


The following commit(s) were added to refs/heads/master by this push:
     new 29c4b6e0f2d IGNITE-19553 Add metrics for operations on secondary 
indexes - Fixes #10731.
29c4b6e0f2d is described below

commit 29c4b6e0f2d60548334800cd718290d5f6636dbe
Author: Aleksey Plekhanov <[email protected]>
AuthorDate: Mon Sep 25 17:43:52 2023 +0300

    IGNITE-19553 Add metrics for operations on secondary indexes - Fixes #10731.
    
    Signed-off-by: Aleksey Plekhanov <[email protected]>
---
 docs/_docs/monitoring-metrics/new-metrics.adoc     |  17 +-
 .../org/apache/ignite/IgniteSystemProperties.java  |   6 +
 .../query/index/sorted/inline/InlineIndexImpl.java |   5 +
 .../query/index/sorted/inline/InlineIndexTree.java |  76 ++++++-
 .../cache/persistence/tree/BPlusTree.java          |  46 +++--
 .../cache/index/BPlusTreeMetricsTest.java          | 228 +++++++++++++++++++++
 .../IgniteBinaryCacheQueryTestSuite.java           |   2 +
 7 files changed, 356 insertions(+), 24 deletions(-)

diff --git a/docs/_docs/monitoring-metrics/new-metrics.adoc 
b/docs/_docs/monitoring-metrics/new-metrics.adoc
index 1b260d435e0..5f3aaeabc00 100644
--- a/docs/_docs/monitoring-metrics/new-metrics.adoc
+++ b/docs/_docs/monitoring-metrics/new-metrics.adoc
@@ -241,7 +241,7 @@ Register name: `io.statistics.cacheGroups.{group_name}`
 |===
 
 
-== Sorted Indexes
+== Sorted Indexes I/O statistics
 
 Register name: `io.statistics.sortedIndexes.{cache_name}.{index_name}`
 
@@ -257,8 +257,21 @@ Register name: 
`io.statistics.sortedIndexes.{cache_name}.{index_name}`
 |startTime|   long|    Statistics collection start time
 |===
 
+== Sorted Indexes operations
 
-== Hash Indexes
+Contains metrics about low-level operations (such as `Insert`, `Search`, etc.) 
on pages of sorted secondary indexes.
+
+Register name: `index.{schema_name}.{table_name}.{index_name}`
+
+[cols="2,1,3",opts="header"]
+|===
+|Name |    Type |    Description
+|{opType}Count|   long|   Count of {opType} operations on index.
+|{opType}Time|   long|   Total duration (nanoseconds) of {opType} operations 
on index.
+|===
+
+
+== Hash Indexes I/O statistics
 
 Register name: `io.statistics.hashIndexes.{cache_name}.{index_name}`
 
diff --git 
a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java 
b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
index b0682d54a36..32056ed6304 100644
--- a/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
+++ b/modules/core/src/main/java/org/apache/ignite/IgniteSystemProperties.java
@@ -1436,6 +1436,12 @@ public final class IgniteSystemProperties {
         defaults = "" + IGNITE_BPLUS_TREE_LOCK_RETRIES_DEFAULT)
     public static final String IGNITE_BPLUS_TREE_LOCK_RETRIES = 
"IGNITE_BPLUS_TREE_LOCK_RETRIES";
 
+    /**
+     * Disables secondary indexes B+Tree metrics.
+     */
+    @SystemProperty(value = "Disables secondary indexes B+Tree metrics", 
defaults = "false")
+    public static final String IGNITE_BPLUS_TREE_DISABLE_METRICS = 
"IGNITE_BPLUS_TREE_DISABLE_METRICS";
+
     /**
      * Amount of memory reserved in the heap at node start, which can be 
dropped to increase the chances of success when
      * handling OutOfMemoryError.
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexImpl.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexImpl.java
index d57c76d9cc0..adab519a499 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexImpl.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexImpl.java
@@ -54,11 +54,15 @@ import org.jetbrains.annotations.Nullable;
 
 import static org.apache.ignite.cluster.ClusterState.INACTIVE;
 import static org.apache.ignite.failure.FailureType.CRITICAL_ERROR;
+import static 
org.apache.ignite.internal.processors.metric.impl.MetricUtils.metricName;
 
 /**
  * Sorted index implementation.
  */
 public class InlineIndexImpl extends AbstractIndex implements InlineIndex {
+    /** */
+    public static final String INDEX_METRIC_PREFIX = "index";
+
     /** Unique ID. */
     private final UUID id = UUID.randomUUID();
 
@@ -553,6 +557,7 @@ public class InlineIndexImpl extends AbstractIndex 
implements InlineIndex {
                 }
 
                 
cctx.kernalContext().metric().remove(stats.metricRegistryName());
+                
cctx.kernalContext().metric().remove(metricName(INDEX_METRIC_PREFIX, 
def.idxName().fullName()));
 
                 if (cctx.group().persistenceEnabled() ||
                     
cctx.shared().kernalContext().state().clusterState().state() != INACTIVE) {
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexTree.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexTree.java
index 79e863c9dd4..5a7ba04481d 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexTree.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/cache/query/index/sorted/inline/InlineIndexTree.java
@@ -43,6 +43,7 @@ import org.apache.ignite.internal.pagemem.PageIdAllocator;
 import org.apache.ignite.internal.pagemem.PageIdUtils;
 import org.apache.ignite.internal.pagemem.PageMemory;
 import org.apache.ignite.internal.processors.cache.CacheGroupContext;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
 import org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManager;
 import org.apache.ignite.internal.processors.cache.mvcc.MvccUtils;
 import 
org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter;
@@ -53,7 +54,11 @@ import 
org.apache.ignite.internal.processors.cache.persistence.tree.io.BPlusMeta
 import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
 import 
org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIoResolver;
 import 
org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList;
+import 
org.apache.ignite.internal.processors.cache.persistence.tree.util.PageHandler;
+import 
org.apache.ignite.internal.processors.cache.persistence.tree.util.PageHandlerWrapper;
 import org.apache.ignite.internal.processors.cache.tree.mvcc.data.MvccDataRow;
+import org.apache.ignite.internal.processors.metric.MetricRegistry;
+import org.apache.ignite.internal.processors.metric.impl.LongAdderMetric;
 import org.apache.ignite.internal.util.typedef.F;
 import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.S;
@@ -61,10 +66,13 @@ import org.apache.ignite.internal.util.typedef.internal.U;
 import org.apache.ignite.maintenance.MaintenanceTask;
 import org.jetbrains.annotations.Nullable;
 
+import static 
org.apache.ignite.IgniteSystemProperties.IGNITE_BPLUS_TREE_DISABLE_METRICS;
+import static 
org.apache.ignite.internal.cache.query.index.sorted.inline.InlineIndexImpl.INDEX_METRIC_PREFIX;
 import static 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.NullableInlineIndexKeyType.CANT_BE_COMPARE;
 import static 
org.apache.ignite.internal.cache.query.index.sorted.inline.types.NullableInlineIndexKeyType.COMPARE_UNSUPPORTED;
 import static 
org.apache.ignite.internal.cache.query.index.sorted.maintenance.MaintenanceRebuildIndexUtils.mergeTasks;
 import static 
org.apache.ignite.internal.cache.query.index.sorted.maintenance.MaintenanceRebuildIndexUtils.toMaintenanceTask;
+import static 
org.apache.ignite.internal.processors.metric.impl.MetricUtils.metricName;
 
 /**
  * BPlusTree where nodes stores inlined index keys.
@@ -139,7 +147,8 @@ public class InlineIndexTree extends BPlusTree<IndexRow, 
IndexRow> {
             PageIdAllocator.FLAG_IDX,
             grpCtx.shared().kernalContext().failure(),
             grpCtx.shared().diagnostic().pageLockTracker(),
-            pageIoResolver
+            pageIoResolver,
+            wrapper(def)
         );
 
         this.grpCtx = grpCtx;
@@ -667,4 +676,69 @@ public class InlineIndexTree extends BPlusTree<IndexRow, 
IndexRow> {
             ", schemaName=" + idxName.schemaName() + ", tblName=" + 
idxName.tableName() + ", idxName=" +
             idxName.idxName() + ']';
     }
+
+    /** */
+    private static PageHandlerWrapper<Result> wrapper(SortedIndexDefinition 
def) {
+        if (def == null || def.cacheInfo().cacheContext() == null)
+            return null;
+
+        if 
(IgniteSystemProperties.getBoolean(IGNITE_BPLUS_TREE_DISABLE_METRICS))
+            return null;
+
+        return new PageHandlerWrapper<Result>() {
+            @Override public PageHandler<?, Result> wrap(BPlusTree<?, ?> tree, 
PageHandler<?, Result> hnd) {
+                GridCacheContext<?, ?> cctx = def.cacheInfo().cacheContext();
+
+                MetricRegistry mreg = 
cctx.shared().kernalContext().metric().registry(
+                    metricName(INDEX_METRIC_PREFIX, def.idxName().fullName()));
+
+                LongAdderMetric cnt = 
mreg.longAdderMetric(hnd.getClass().getSimpleName() + "Count",
+                    "Count of " + hnd.getClass().getSimpleName() + " 
operations");
+                LongAdderMetric time = 
mreg.longAdderMetric(hnd.getClass().getSimpleName() + "Time",
+                    "Total time of " + hnd.getClass().getSimpleName() + " 
operations (nanoseconds)");
+
+                return new PageHandler<Object, Result>() {
+                    @Override public Result run(
+                        int cacheId,
+                        long pageId,
+                        long page,
+                        long pageAddr,
+                        PageIO io,
+                        Boolean walPlc,
+                        Object arg,
+                        int intArg,
+                        IoStatisticsHolder statHolder
+                    ) throws IgniteCheckedException {
+                        if (!cctx.statisticsEnabled()) {
+                            return ((PageHandler<Object, 
Result>)hnd).run(cacheId, pageId, page, pageAddr, io, walPlc,
+                                arg, intArg, statHolder);
+                        }
+
+                        long ts = System.nanoTime();
+
+                        try {
+                            return ((PageHandler<Object, 
Result>)hnd).run(cacheId, pageId, page, pageAddr, io, walPlc,
+                                arg, intArg, statHolder);
+                        }
+                        finally {
+                            cnt.increment();
+                            time.add(System.nanoTime() - ts);
+                        }
+                    }
+
+                    @Override public boolean releaseAfterWrite(
+                        int cacheId,
+                        long pageId,
+                        long page,
+                        long pageAddr,
+                        Object arg,
+                        int intArg
+                    ) {
+                        return ((PageHandler<Object, 
Result>)hnd).releaseAfterWrite(cacheId, pageId, page, pageAddr,
+                            arg, intArg);
+                    }
+                };
+            }
+        };
+    }
 }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
index e4b1bfdb2c2..055138e9172 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java
@@ -987,7 +987,8 @@ public abstract class BPlusTree<L, T extends L> extends 
DataStructure implements
             pageFlag,
             failureProcessor,
             pageLockTrackerManager,
-            DEFAULT_PAGE_IO_RESOLVER
+            DEFAULT_PAGE_IO_RESOLVER,
+            null
         );
 
         setIos(innerIos, leafIos);
@@ -1018,7 +1019,8 @@ public abstract class BPlusTree<L, T extends L> extends 
DataStructure implements
         byte pageFlag,
         @Nullable FailureProcessor failureProcessor,
         PageLockTrackerManager pageLockTrackerManager,
-        PageIoResolver pageIoRslvr
+        PageIoResolver pageIoRslvr,
+        @Nullable PageHandlerWrapper<Result> hndWrapper
     ) {
         super(name, cacheGrpId, grpName, pageMem, wal, pageLockTrackerManager, 
pageIoRslvr, pageFlag);
 
@@ -1034,31 +1036,33 @@ public abstract class BPlusTree<L, T extends L> extends 
DataStructure implements
         this.failureProcessor = failureProcessor;
 
         // Initialize page handlers.
-        askNeighbor = (PageHandler<Get, Result>)wrap(this, new AskNeighbor());
-        search = (PageHandler<Get, Result>)wrap(this, new Search());
-        lockTailExact = (PageHandler<Update, Result>)wrap(this, new 
LockTailExact());
-        lockTail = (PageHandler<Remove, Result>)wrap(this, new LockTail());
-        lockTailForward = (PageHandler<Remove, Result>)wrap(this, new 
LockTailForward());
-        lockBackAndTail = (PageHandler<Remove, Result>)wrap(this, new 
LockBackAndTail());
-        lockBackAndRmvFromLeaf = (PageHandler<Remove, Result>)wrap(this, new 
LockBackAndRmvFromLeaf());
-        rmvFromLeaf = (PageHandler<Remove, Result>)wrap(this, new 
RemoveFromLeaf());
-        insert = (PageHandler<Put, Result>)wrap(this, new Insert());
-        replace = (PageHandler<Put, Result>)wrap(this, new Replace());
-        rmvRangeFromLeaf = (PageHandler<Remove, Result>)wrap(this, new 
RemoveRangeFromLeaf());
+        askNeighbor = wrap(hndWrapper, new AskNeighbor());
+        search = wrap(hndWrapper, new Search());
+        lockTailExact = wrap(hndWrapper, new LockTailExact());
+        lockTail = wrap(hndWrapper, new LockTail());
+        lockTailForward = wrap(hndWrapper, new LockTailForward());
+        lockBackAndTail = wrap(hndWrapper, new LockBackAndTail());
+        lockBackAndRmvFromLeaf = wrap(hndWrapper, new 
LockBackAndRmvFromLeaf());
+        rmvFromLeaf = wrap(hndWrapper, new RemoveFromLeaf<>());
+        insert = wrap(hndWrapper, new Insert());
+        replace = wrap(hndWrapper, new Replace());
+        rmvRangeFromLeaf = wrap(hndWrapper, new RemoveRangeFromLeaf());
     }
 
     /**
-     * Returns a wrapper for page handler. By default, there is no wrapper.
+     * Returns a wrapped page handler. By default, there is no wrapper.
      *
-     * @param tree B-plus tree.
+     * @param hndWrapper Page handler wrapper for this tree.
      * @param hnd Page handler.
-     * @return Page handler wrapper.
+     * @return Wrapped page handler.
      */
-    private PageHandler<?, Result> wrap(BPlusTree<?, ?> tree, PageHandler<?, 
Result> hnd) {
-        if (testHndWrapper == null)
-            return hnd;
-        else
-            return testHndWrapper.wrap(tree, hnd);
+    private <X> PageHandler<X, Result> wrap(PageHandlerWrapper<Result> 
hndWrapper, PageHandler<?, Result> hnd) {
+        // Wrap handler using test wrapper.
+        if (testHndWrapper != null)
+            hnd = testHndWrapper.wrap(this, hnd);
+
+        // Additionally wrap using tree page handler wrapper, if it's 
specified.
+        return (PageHandler<X, Result>)(hndWrapper == null ? hnd : 
hndWrapper.wrap(this, hnd));
     }
 
     /**
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/BPlusTreeMetricsTest.java
 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/BPlusTreeMetricsTest.java
new file mode 100644
index 00000000000..d977fba73ba
--- /dev/null
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/BPlusTreeMetricsTest.java
@@ -0,0 +1,228 @@
+/*
+ * 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.index;
+
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.IgniteSystemProperties;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import 
org.apache.ignite.internal.cache.query.index.sorted.inline.InlineIndexImpl;
+import org.apache.ignite.spi.metric.LongMetric;
+import org.apache.ignite.spi.metric.ReadOnlyMetricRegistry;
+import org.apache.ignite.testframework.junits.WithSystemProperty;
+import org.junit.Test;
+
+/**
+ * Tests BPlusTree metrics.
+ */
+public class BPlusTreeMetricsTest extends AbstractIndexingCommonTest {
+    /** */
+    private static final String INSERT_CNT = "InsertCount";
+
+    /** */
+    private static final String REMOVE_CNT = "RemoveFromLeafCount";
+
+    /** */
+    private static final String SEARCH_CNT = "SearchCount";
+
+    /** */
+    private static final String INSERT_TIME = "InsertTime";
+
+    /** */
+    private static final String REMOVE_TIME = "RemoveFromLeafTime";
+
+    /** */
+    private static final String SEARCH_TIME = "SearchTime";
+
+    /**
+     * @return Default cache configuration.
+     */
+    private CacheConfiguration<Integer, TestClass> cacheConfiguration(String 
cacheName) {
+        CacheConfiguration<Integer, TestClass> ccfg = new 
CacheConfiguration<>(cacheName);
+
+        ccfg.setIndexedTypes(Integer.class, TestClass.class);
+        ccfg.setStatisticsEnabled(true);
+
+        return ccfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        stopAllGrids();
+
+        super.afterTest();
+    }
+
+    /**
+     * Test metrics exposed by index BPlusTree.
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testValues() throws Exception {
+        IgniteEx ignite = startGrid(0);
+
+        IgniteCache<Integer, TestClass> cache = 
ignite.getOrCreateCache(cacheConfiguration(DEFAULT_CACHE_NAME));
+
+        ReadOnlyMetricRegistry intFieldReg = findRegistry(ignite, "intField");
+        ReadOnlyMetricRegistry strFieldReg = findRegistry(ignite, "strField");
+
+        assertEquals(0, metric(intFieldReg, INSERT_CNT));
+        assertEquals(0, metric(strFieldReg, INSERT_CNT));
+        assertEquals(0, metric(intFieldReg, INSERT_TIME));
+        assertEquals(0, metric(strFieldReg, INSERT_TIME));
+
+        for (int i = 0; i < 5000; i++)
+            cache.put(i, new TestClass(i));
+
+        // This metric includes insert to inner nodes, so value can exceed 
count of inserted keys.
+        assertTrue(metric(intFieldReg, INSERT_CNT) > 5000);
+        assertTrue(metric(strFieldReg, INSERT_CNT) > 5000);
+        assertTrue(metric(intFieldReg, INSERT_TIME) > 0);
+        assertTrue(metric(strFieldReg, INSERT_TIME) > 0);
+
+        assertEquals(0, metric(intFieldReg, REMOVE_CNT));
+        assertEquals(0, metric(strFieldReg, REMOVE_CNT));
+        assertEquals(0, metric(intFieldReg, REMOVE_TIME));
+        assertEquals(0, metric(strFieldReg, REMOVE_TIME));
+
+        for (int i = 0; i < 1000; i++)
+            cache.remove(i);
+
+        assertEquals(1000, metric(intFieldReg, REMOVE_CNT));
+        assertEquals(1000, metric(strFieldReg, REMOVE_CNT));
+        assertTrue(metric(intFieldReg, REMOVE_TIME) > 0);
+        assertTrue(metric(strFieldReg, REMOVE_TIME) > 0);
+
+        long searchOnIntCnt = metric(intFieldReg, SEARCH_CNT);
+        long searchOnStrCnt = metric(strFieldReg, SEARCH_CNT);
+        long searchOnIntTime = metric(intFieldReg, SEARCH_TIME);
+        long searchOnStrTime = metric(strFieldReg, SEARCH_TIME);
+
+        cache.query(new SqlFieldsQuery("SELECT * FROM TESTCLASS WHERE INTFIELD 
= ?").setArgs(3000)).getAll();
+
+        assertTrue(metric(intFieldReg, SEARCH_CNT) > searchOnIntCnt);
+        assertEquals(searchOnStrCnt, metric(strFieldReg, SEARCH_CNT));
+        assertTrue(metric(intFieldReg, SEARCH_TIME) > searchOnIntTime);
+        assertEquals(searchOnStrTime, metric(strFieldReg, SEARCH_TIME));
+    }
+
+    /**
+     * Test metrics when cache statistics is disabled.
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    public void testDisableStatistics() throws Exception {
+        IgniteEx ignite = startGrid(0);
+
+        IgniteCache<Integer, TestClass> cache = 
ignite.getOrCreateCache(cacheConfiguration(DEFAULT_CACHE_NAME));
+
+        ReadOnlyMetricRegistry intFieldReg = findRegistry(ignite, "intField");
+
+        cache.enableStatistics(false);
+
+        cache.put(0, new TestClass(0));
+
+        assertEquals(0, metric(intFieldReg, INSERT_CNT));
+        assertEquals(0, metric(intFieldReg, INSERT_TIME));
+
+        cache.query(new SqlFieldsQuery("SELECT * FROM TESTCLASS WHERE INTFIELD 
= ?").setArgs(0)).getAll();
+
+        assertEquals(0, metric(intFieldReg, SEARCH_CNT));
+        assertEquals(0, metric(intFieldReg, SEARCH_TIME));
+
+        cache.remove(0);
+
+        assertEquals(0, metric(intFieldReg, REMOVE_CNT));
+        assertEquals(0, metric(intFieldReg, REMOVE_TIME));
+
+        cache.enableStatistics(true);
+
+        cache.put(0, new TestClass(0));
+
+        assertTrue(metric(intFieldReg, INSERT_CNT) > 0);
+        assertTrue(metric(intFieldReg, INSERT_TIME) > 0);
+
+        cache.query(new SqlFieldsQuery("SELECT * FROM TESTCLASS WHERE INTFIELD 
= ?").setArgs(0)).getAll();
+
+        assertTrue(metric(intFieldReg, SEARCH_CNT) > 0);
+        assertTrue(metric(intFieldReg, SEARCH_TIME) > 0);
+
+        cache.remove(0);
+
+        assertTrue(metric(intFieldReg, REMOVE_CNT) > 0);
+        assertTrue(metric(intFieldReg, REMOVE_TIME) > 0);
+    }
+
+    /**
+     * Test disable metrics by system property.
+     *
+     * @throws Exception If failed.
+     */
+    @Test
+    @WithSystemProperty(key = 
IgniteSystemProperties.IGNITE_BPLUS_TREE_DISABLE_METRICS, value = "true")
+    public void testDisableMetrics() throws Exception {
+        IgniteEx ignite = startGrid(0);
+
+        ignite.getOrCreateCache(cacheConfiguration(DEFAULT_CACHE_NAME));
+
+        for (ReadOnlyMetricRegistry reg : ignite.context().metric())
+            
assertFalse(reg.name().startsWith(InlineIndexImpl.INDEX_METRIC_PREFIX));
+    }
+
+    /** */
+    private ReadOnlyMetricRegistry findRegistry(IgniteEx ignite, String 
fieldName) {
+        for (ReadOnlyMetricRegistry reg : ignite.context().metric()) {
+            if (reg.name().startsWith(InlineIndexImpl.INDEX_METRIC_PREFIX)
+                && reg.name().toUpperCase().contains(fieldName.toUpperCase()))
+                return reg;
+        }
+
+        throw new AssertionError("Not found metric registry for index on field 
" + fieldName);
+    }
+
+    /** */
+    private long metric(ReadOnlyMetricRegistry reg, String metric) {
+        LongMetric m = reg.findMetric(metric);
+
+        if (m == null)
+            throw new AssertionError("Not found metric " + metric + " in 
registry " + reg.name());
+
+        return m.value();
+    }
+
+    /** */
+    private static class TestClass {
+        /** */
+        @QuerySqlField(index = true)
+        private final int intField;
+
+        /** */
+        @QuerySqlField(index = true)
+        private final String strField;
+
+        /** */
+        public TestClass(int val) {
+            intField = val;
+            strField = "str" + val;
+        }
+    }
+}
diff --git 
a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java
 
b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java
index a7af46f7736..78bf0750314 100644
--- 
a/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java
+++ 
b/modules/indexing/src/test/java/org/apache/ignite/testsuites/IgniteBinaryCacheQueryTestSuite.java
@@ -72,6 +72,7 @@ import 
org.apache.ignite.internal.processors.cache.distributed.replicated.Ignite
 import 
org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedQueryP2PDisabledSelfTest;
 import 
org.apache.ignite.internal.processors.cache.distributed.replicated.IgniteCacheReplicatedQuerySelfTest;
 import org.apache.ignite.internal.processors.cache.index.ArrayIndexTest;
+import org.apache.ignite.internal.processors.cache.index.BPlusTreeMetricsTest;
 import 
org.apache.ignite.internal.processors.cache.index.BasicIndexMultinodeTest;
 import org.apache.ignite.internal.processors.cache.index.BasicIndexTest;
 import 
org.apache.ignite.internal.processors.cache.index.ComplexPrimaryKeyUnwrapSelfTest;
@@ -203,6 +204,7 @@ import org.junit.runners.Suite;
     ArrayIndexTest.class,
     BasicIndexMultinodeTest.class,
     IndexMetricsTest.class,
+    BPlusTreeMetricsTest.class,
 
     // Misc tests.
     QueryEntityValidationSelfTest.class,

Reply via email to