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); + } }