Author: davide
Date: Thu Sep 25 11:08:26 2014
New Revision: 1627511

URL: http://svn.apache.org/r1627511
Log:
OAK-2057 Add timing to OrderedIndex

Merging r1627503 into 1.0 branch resolving a tree conflict for
oak-core/src/main/java/org/apache/jackrabbit/oak/stats/StopwatchLogger.java 



Added:
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/stats/StopwatchLogger.java
Modified:
    jackrabbit/oak/branches/1.0/   (props changed)
    
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexEditor.java
    
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAggregationTest.java

Propchange: jackrabbit/oak/branches/1.0/
------------------------------------------------------------------------------
  Merged /jackrabbit/oak/trunk:r1627503

Modified: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexEditor.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexEditor.java?rev=1627511&r1=1627510&r2=1627511&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexEditor.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/OrderedPropertyIndexEditor.java
 Thu Sep 25 11:08:26 2014
@@ -22,6 +22,7 @@ import java.util.Set;
 
 import javax.annotation.Nonnull;
 
+import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
@@ -31,6 +32,7 @@ import org.apache.jackrabbit.oak.plugins
 import 
org.apache.jackrabbit.oak.plugins.index.property.strategy.OrderedContentMirrorStoreStrategy;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.stats.StopwatchLogger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -57,6 +59,8 @@ public class OrderedPropertyIndexEditor 
     private boolean properlyConfigured;
 
     private OrderDirection direction = OrderedIndex.DEFAULT_DIRECTION;
+    
+    private StopwatchLogger swl;
 
     public OrderedPropertyIndexEditor(NodeBuilder definition, NodeState root,
                                       IndexUpdateCallback callback) {
@@ -92,12 +96,16 @@ public class OrderedPropertyIndexEditor 
                 this.direction = dir;
             }
         }
+        
+        // initialising the stopwatch.
+        swl = new StopwatchLogger(OrderedPropertyIndexEditor.class);
     }
 
     OrderedPropertyIndexEditor(OrderedPropertyIndexEditor parent, String name) 
{
         super(parent, name);
         this.propertyNames = parent.getPropertyNames();
         this.direction = parent.getDirection();
+        this.swl = parent.swl;
     }
 
     /**
@@ -136,4 +144,41 @@ public class OrderedPropertyIndexEditor 
     public OrderDirection getDirection() {
         return direction;
     }
+
+    @Override
+    public void enter(NodeState before, NodeState after) {
+        super.enter(before, after);
+    }
+
+    private boolean isToProcess(NodeState state, Set<String> propertyNames) {
+        if (state == null || propertyNames == null) {
+            return false;
+        } else {
+            for (String p : propertyNames) {
+                if (state.getProperty(p) != null) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+    
+    @Override
+    public void leave(NodeState before, NodeState after) throws 
CommitFailedException {
+        if (swl.isEnabled() && !swl.isStarted()) {
+            // perform extra operations for starting correctly the clock.
+            Set<String> pn = getPropertyNames();
+            if (isToProcess(before, pn) || isToProcess(after, pn)) {
+                swl.start();
+            }
+        }
+        
+        super.leave(before, after);
+        
+        if (swl.isStarted()) {
+            // if not started we will probably won't have processed anything
+            // tracking down the time spent for the overall process
+            swl.stop(String.format("item added to the index - %s", 
getPropertyNames()));
+        }        
+    }
 }

Added: 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/stats/StopwatchLogger.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/stats/StopwatchLogger.java?rev=1627511&view=auto
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/stats/StopwatchLogger.java
 (added)
+++ 
jackrabbit/oak/branches/1.0/oak-core/src/main/java/org/apache/jackrabbit/oak/stats/StopwatchLogger.java
 Thu Sep 25 11:08:26 2014
@@ -0,0 +1,171 @@
+/*
+ * 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.jackrabbit.oak.stats;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.ScheduledExecutorService;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class to be used for tracking of timing within methods. It makes 
use of the
+ * {@link Clock.Fast} for speeding up the operation.
+ */
+public class StopwatchLogger implements Closeable {
+    private static final Logger LOG = 
LoggerFactory.getLogger(StopwatchLogger.class);
+
+    private final ScheduledExecutorService executor = 
newSingleThreadScheduledExecutor();
+    private final String clazz;
+    
+    private Clock clock;
+    private Logger customLog;
+    
+    private long start;
+    
+    /**
+     * Create a class with the provided class.
+     * 
+     * @param claz
+     */
+    public StopwatchLogger(@Nonnull final String clazz) {
+        this(null, checkNotNull(clazz));
+    }
+
+    /**
+     * instantiate a class with the provided class
+     * 
+     * @param clazz
+     */
+    public StopwatchLogger(@Nonnull final Class<?> clazz) {
+        this(checkNotNull(clazz).getName().toString());
+    }
+
+    /**
+     * Instantiate a class with the provided class and custom logger. The 
provided logger, if not
+     * null, will be then used for tracking down times
+     * 
+     * @param customLog
+     * @param clazz
+     */
+    public StopwatchLogger(@Nullable final Logger customLog, @Nonnull final 
Class<?> clazz) {
+        this(customLog, checkNotNull(clazz).getName().toString());
+    }
+
+    /**
+     * Instantiate a class with the provided class and custom logger. The 
provided logger, if not
+     * null, will be then used for tracking down times
+     *
+     * @param customLog
+     * @param clazz
+     */
+    public StopwatchLogger(@Nullable final Logger customLog, @Nonnull final 
String clazz) {
+        this.clazz = checkNotNull(clazz);
+        this.customLog = customLog;
+    }
+
+    /**
+     * starts the clock
+     */
+    public void start() {
+        clock = new Clock.Fast(executor);
+        start = clock.getTimeMonotonic();
+    }
+    
+    /**
+     * track of an intermediate time without stopping the ticking.
+     * 
+     * @param message
+     */
+    public void split(@Nullable final String message) {
+        track(this, message);
+    }
+    
+    /**
+     * track the time and stop the clock.
+     * 
+     * @param message
+     */
+    public void stop(@Nullable final String message) {
+        track(this, message);
+        clock = null;
+    }
+
+    /**
+     * convenience method for tracking the messages
+     * 
+     * @param customLog a potential custom logger. If null the static instance 
will be used
+     * @param clock the clock used for tracking.
+     * @param clazz the class to be used during the tracking of times
+     * @param message a custom message for the tracking.
+     */
+    private static void track(@Nonnull final StopwatchLogger swl,
+                              @Nullable final String message) {
+
+        checkNotNull(swl);
+        
+        if (swl.isEnabled()) {
+            Logger l = swl.getLogger();
+            
+            if (swl.clock == null) {
+                l.debug("{} - clock has not been started yet.", swl.clazz);
+            } else {
+                Clock c = swl.clock;
+                
+                l.debug(
+                    "{} - {} {}ms",
+                    new Object[] { checkNotNull(swl.clazz), message == null ? 
"" : message,
+                                  c.getTimeMonotonic() - swl.start});
+            }
+        }
+    }
+
+    @Override
+    public void close() throws IOException {
+        try {
+            executor.shutdownNow();            
+        } catch (Throwable t) {
+            LOG.error("Error while shutting down the scheduler.", t);
+        }
+    }
+    
+    /**
+     * @return true if the clock has been started. False otherwise.
+     */
+    public boolean isStarted() {
+        return clock != null;
+    }
+    
+    private Logger getLogger() {
+        return (customLog == null) ? LOG :  customLog;
+    }
+    
+    /**
+     * @return true whether the provided appender has DEBUG enabled and 
therefore asked to track
+     *         times.
+     */
+    public boolean isEnabled() {
+        return getLogger().isDebugEnabled();
+    }
+}

Modified: 
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAggregationTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAggregationTest.java?rev=1627511&r1=1627510&r2=1627511&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAggregationTest.java
 (original)
+++ 
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAggregationTest.java
 Thu Sep 25 11:08:26 2014
@@ -16,6 +16,11 @@
  */
 package org.apache.jackrabbit.oak.plugins.index.lucene;
 
+import static org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import static org.apache.jackrabbit.oak.api.Type.NAME;
+import static org.apache.jackrabbit.oak.api.Type.STRING;
+
 import static com.google.common.collect.Lists.newArrayList;
 import static org.apache.jackrabbit.JcrConstants.JCR_CONTENT;
 import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
@@ -400,4 +405,29 @@ public class LuceneIndexAggregationTest 
                     "xpath", ImmutableList.of("/myFolder", "/myFolder/myFile", 
"/myFolder/myFile/jcr:content"));
     }
 
+    @Test
+        public void testUnique() throws CommitFailedException {
+        //        setTraversalEnabled(false);
+        final String statement = "//*[@list "
+                                 + "and (jcr:contains(., 'community') "
+                                 + "or jcr:contains(metadata, 'community')) "
+                                 + "and @resourceType = 'open/community' "
+                                 + "and @jcr:primaryType != 'nt:frozenNode'] "
+            + "order by @jcr:created descending";
+        
+        Tree t = root.getTree("/").addChild("content");
+        t.setProperty(JCR_PRIMARYTYPE, NT_FOLDER, NAME);
+        t = t.addChild("node");
+        t.setProperty(JCR_PRIMARYTYPE, NT_FOLDER, NAME);
+        t = t.addChild(JCR_CONTENT);
+        t.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, NAME);
+        t.setProperty("name", "Open Community", STRING);
+        t.setProperty("jcr:title", "Open Community", STRING);
+        t.setProperty("list", "opencommunity", STRING);
+        t.setProperty("resourceType", "open/community", STRING);
+        root.commit();
+
+        assertQuery(statement, "xpath", 
ImmutableList.of("/content/node/jcr:content"));
+        //setTraversalEnabled(true);
+    }
 }


Reply via email to