Author: chetanm
Date: Tue Apr  7 10:18:36 2015
New Revision: 1671787

URL: http://svn.apache.org/r1671787
Log:
OAK-2720 - Misleading traversal warning message while performing query

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java?rev=1671787&r1=1671786&r2=1671787&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java
 Tue Apr  7 10:18:36 2015
@@ -78,7 +78,7 @@ public class ContentMirrorStoreStrategy
     /**
      * logging a warning every {@code oak.traversing.warn} traversed nodes. 
Default {@code 10000}
      */
-    static final int TRAVERSING_WARN = 
Integer.getInteger("oak.traversing.warn", 10000);
+    public static final int TRAVERSING_WARN = 
Integer.getInteger("oak.traversing.warn", 10000);
 
     @Override
     public void update(
@@ -307,6 +307,7 @@ public class ContentMirrorStoreStrategy
         private final Deque<Iterator<? extends ChildNodeEntry>> nodeIterators =
                 Queues.newArrayDeque();
         private int readCount;
+        private int intermediateNodeReadCount;
         private boolean init;
         private boolean closed;
         private String filterPath;
@@ -385,12 +386,6 @@ public class ContentMirrorStoreStrategy
                 if (iterator.hasNext()) {
                     ChildNodeEntry entry = iterator.next();
 
-                    readCount++;
-                    if (readCount % TRAVERSING_WARN == 0) {
-                        FilterIterators.checkReadLimit(readCount, settings);
-                        LOG.warn("Traversed " + readCount + " nodes using 
index " + indexName + " with filter " + filter);
-                    }
-
                     NodeState node = entry.getNodeState();
 
                     String name = entry.getName();
@@ -422,7 +417,14 @@ public class ContentMirrorStoreStrategy
                     parentPath = currentPath;
 
                     if (node.getBoolean("match")) {
+                        readCount++;
+                        if (readCount % TRAVERSING_WARN == 0) {
+                            FilterIterators.checkReadLimit(readCount, 
settings);
+                            LOG.warn("Traversed {} nodes ({} index entries) 
using index {} with filter {}", readCount, intermediateNodeReadCount, 
indexName, filter);
+                        }
                         return;
+                    } else {
+                        intermediateNodeReadCount++;
                     }
 
                 } else {

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexTest.java?rev=1671787&r1=1671786&r2=1671787&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexTest.java
 Tue Apr  7 10:18:36 2015
@@ -28,15 +28,24 @@ import static org.apache.jackrabbit.oak.
 import static 
org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_NODE_TYPES;
 import static 
org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent.INITIAL_CONTENT;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import java.util.Arrays;
 import java.util.Set;
 
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.read.ListAppender;
+import ch.qos.logback.core.spi.FilterReply;
+import com.google.common.collect.Iterables;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
+import 
org.apache.jackrabbit.oak.plugins.index.property.strategy.ContentMirrorStoreStrategy;
 import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
 import org.apache.jackrabbit.oak.query.QueryEngineSettings;
 import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
@@ -52,6 +61,7 @@ import org.junit.Test;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
+import org.slf4j.LoggerFactory;
 
 /**
  * Test the Property2 index mechanism.
@@ -510,4 +520,93 @@ public class PropertyIndexTest {
         HOOK.processCommit(before, after, CommitInfo.EMPTY); // should not 
throw
     }
 
+    @Test
+    public void traversalWarning() throws Exception {
+        ListAppender appender = createAndRegisterAppender();
+
+        int testDataSize = ContentMirrorStoreStrategy.TRAVERSING_WARN;
+        NodeState indexed = createTestData(testDataSize);
+        assertEquals(testDataSize, getResultSize(indexed, "foo", "bar"));
+        assertFalse(appender.list.isEmpty());
+
+        appender.list.clear();
+
+        testDataSize = 100;
+        indexed = createTestData(100);
+        assertEquals(testDataSize, getResultSize(indexed, "foo", "bar"));
+        assertTrue("Warning should not be logged for traversing " + 
testDataSize,
+                appender.list.isEmpty());
+        deregisterAppender(appender);
+    }
+
+    private int getResultSize(NodeState indexed, String name, String value){
+        FilterImpl f = createFilter(indexed, NT_BASE);
+
+        // Query the index
+        PropertyIndexLookup lookup = new PropertyIndexLookup(indexed);
+        Iterable<String> result = lookup.query(f, name, 
PropertyValues.newString(value));
+        return Iterables.size(result);
+    }
+
+    private NodeState createTestData(int entryCount) throws 
CommitFailedException {
+        NodeState root = INITIAL_CONTENT;
+
+        // Add index definition
+        NodeBuilder builder = root.builder();
+        NodeBuilder index = 
createIndexDefinition(builder.child(INDEX_DEFINITIONS_NAME), "foo",
+                true, false, ImmutableSet.of("foo"), null);
+        // disable the estimation
+        index.setProperty("entryCount", -1);
+        NodeState before = builder.getNodeState();
+
+        // Add some content and process it through the property index hook
+        int depth = ContentMirrorStoreStrategy.TRAVERSING_WARN / entryCount + 
10;
+        for (int i = 0; i < entryCount; i++) {
+            NodeBuilder parentNode = builder.child("n" + i);
+            for (int j = 0; j < depth ; j++) {
+                parentNode = parentNode.child("c" + j);
+            }
+            parentNode.setProperty("foo", "bar");
+        }
+        NodeState after = builder.getNodeState();
+
+        return HOOK.processCommit(before, after, CommitInfo.EMPTY);
+    }
+
+    private ListAppender createAndRegisterAppender() {
+        TraversingWarningFilter filter = new TraversingWarningFilter();
+        filter.start();
+        ListAppender appender = new ListAppender<ILoggingEvent>();
+        appender.setContext(getContext());
+        appender.setName("TestLogCollector");
+        appender.addFilter(filter);
+        appender.start();
+        rootLogger().addAppender(appender);
+        return appender;
+    }
+
+    private void deregisterAppender(Appender<ILoggingEvent> appender){
+        rootLogger().detachAppender(appender);
+    }
+
+    private static LoggerContext getContext(){
+        return (LoggerContext) LoggerFactory.getILoggerFactory();
+    }
+
+    private static ch.qos.logback.classic.Logger rootLogger() {
+        return 
getContext().getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
+    }
+
+    private static class TraversingWarningFilter extends 
ch.qos.logback.core.filter.Filter<ILoggingEvent> {
+
+        @Override
+        public FilterReply decide(ILoggingEvent event) {
+            if (event.getLevel().isGreaterOrEqual(Level.WARN)
+                    && event.getMessage().contains("Traversed")) {
+                return FilterReply.ACCEPT;
+            } else {
+                return FilterReply.DENY;
+            }
+        }
+    }
 }


Reply via email to