You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by th...@apache.org on 2017/08/11 16:45:36 UTC
svn commit: r1804821 [1/2] - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/
oak-core/...
Author: thomasm
Date: Fri Aug 11 16:45:35 2017
New Revision: 1804821
URL: http://svn.apache.org/viewvc?rev=1804821&view=rev
Log:
OAK-6526 Slow queries: ability to track them via JMX
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsData.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsMBean.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsMBeanImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsReporter.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryLimits.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/stats/
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/stats/QueryStatsTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/Cursors.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/DiffIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/strategy/ContentMirrorStoreStrategy.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/reference/ReferenceIndex.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/FilterIterators.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryEngineSettings.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/LargeQueryTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/NativeQueryTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryCostOverheadTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2OptimiseQueryTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndex.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java Fri Aug 11 16:45:35 2017
@@ -79,6 +79,7 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.index.property.jmx.PropertyIndexAsyncReindex;
import org.apache.jackrabbit.oak.plugins.index.property.jmx.PropertyIndexAsyncReindexMBean;
import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
+import org.apache.jackrabbit.oak.query.stats.QueryStatsMBean;
import org.apache.jackrabbit.oak.spi.commit.CompositeConflictHandler;
import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
import org.apache.jackrabbit.oak.spi.commit.CommitHook;
@@ -693,6 +694,9 @@ public class Oak {
regs.add(registerMBean(whiteboard, QueryEngineSettingsMBean.class,
queryEngineSettings, QueryEngineSettingsMBean.TYPE, "settings"));
+ regs.add(registerMBean(whiteboard, QueryStatsMBean.class,
+ queryEngineSettings.getQueryStats(), QueryStatsMBean.TYPE, "Oak Query Statistics (Extended)"));
+
// FIXME: OAK-810 move to proper workspace initialization
// initialize default workspace
Iterable<WorkspaceInitializer> workspaceInitializers =
@@ -881,16 +885,8 @@ public class Oak {
settings.setFastQuerySize(fastQuerySize);
}
- public void setFullTextComparisonWithoutIndex(boolean fullTextComparisonWithoutIndex) {
- settings.setFullTextComparisonWithoutIndex(fullTextComparisonWithoutIndex);
- }
-
- public boolean getFullTextComparisonWithoutIndex() {
- return settings.getFullTextComparisonWithoutIndex();
- }
-
- public boolean isSql2Optimisation() {
- return settings.isSql2Optimisation();
+ public QueryStatsMBean getQueryStats() {
+ return settings.getQueryStats();
}
public QueryEngineSettings unwrap() {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/Cursors.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/Cursors.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/Cursors.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/Cursors.java Fri Aug 11 16:45:35 2017
@@ -34,7 +34,7 @@ import org.apache.jackrabbit.oak.spi.que
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.query.Filter.PathRestriction;
import org.apache.jackrabbit.oak.spi.query.IndexRow;
-import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
+import org.apache.jackrabbit.oak.spi.query.QueryLimits;
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
@@ -59,11 +59,11 @@ public class Cursors {
private Cursors() {
}
- public static Cursor newIntersectionCursor(Cursor a, Cursor b, QueryEngineSettings settings) {
+ public static Cursor newIntersectionCursor(Cursor a, Cursor b, QueryLimits settings) {
return new IntersectionCursor(a, b, settings);
}
- public static Cursor newConcatCursor(List<Cursor> cursors, QueryEngineSettings settings) {
+ public static Cursor newConcatCursor(List<Cursor> cursors, QueryLimits settings) {
return new ConcatCursor(cursors, settings);
}
@@ -73,7 +73,7 @@ public class Cursors {
* @param paths the paths to iterate over (must return distinct paths)
* @return the Cursor.
*/
- public static Cursor newPathCursor(Iterable<String> paths, QueryEngineSettings settings) {
+ public static Cursor newPathCursor(Iterable<String> paths, QueryLimits settings) {
return new PathCursor(paths.iterator(), true, settings);
}
@@ -84,7 +84,7 @@ public class Cursors {
* @param paths the paths to iterate over (might contain duplicate entries)
* @return the Cursor.
*/
- public static Cursor newPathCursorDistinct(Iterable<String> paths, QueryEngineSettings settings) {
+ public static Cursor newPathCursorDistinct(Iterable<String> paths, QueryLimits settings) {
return new PathCursor(paths.iterator(), true, settings);
}
@@ -112,7 +112,7 @@ public class Cursors {
* @param level the ancestor level. Must be {@code >= 1}.
* @return cursor over the ancestors of <code>c</code> at <code>level</code>.
*/
- public static Cursor newAncestorCursor(Cursor c, int level, QueryEngineSettings settings) {
+ public static Cursor newAncestorCursor(Cursor c, int level, QueryLimits settings) {
checkNotNull(c);
checkArgument(level >= 1);
return new AncestorCursor(c, level, settings);
@@ -141,7 +141,7 @@ public class Cursors {
*/
private static class AncestorCursor extends PathCursor {
- public AncestorCursor(Cursor cursor, int level, QueryEngineSettings settings) {
+ public AncestorCursor(Cursor cursor, int level, QueryLimits settings) {
super(transform(cursor, level), true, settings);
}
@@ -177,7 +177,7 @@ public class Cursors {
private final Iterator<String> iterator;
- public PathCursor(Iterator<String> paths, boolean distinct, final QueryEngineSettings settings) {
+ public PathCursor(Iterator<String> paths, boolean distinct, final QueryLimits settings) {
Iterator<String> it = paths;
if (distinct) {
it = Iterators.filter(it, new Predicate<String>() {
@@ -232,11 +232,11 @@ public class Cursors {
private boolean closed;
- private final QueryEngineSettings settings;
+ private final QueryLimits settings;
public TraversingCursor(Filter filter, NodeState rootState) {
this.filter = filter;
- this.settings = filter.getQueryEngineSettings();
+ this.settings = filter.getQueryLimits();
String path = filter.getPath();
parentPath = null;
@@ -362,12 +362,12 @@ public class Cursors {
private final HashMap<String, IndexRow> secondSet = new HashMap<String, IndexRow>();
private final HashSet<String> seen = new HashSet<String>();
private final Cursor first, second;
- private final QueryEngineSettings settings;
+ private final QueryLimits settings;
private boolean init;
private boolean closed;
private IndexRow current;
- IntersectionCursor(Cursor first, Cursor second, QueryEngineSettings settings) {
+ IntersectionCursor(Cursor first, Cursor second, QueryLimits settings) {
this.first = first;
this.second = second;
this.settings = settings;
@@ -455,7 +455,7 @@ public class Cursors {
private final HashSet<String> seen = new HashSet<String>();
private final List<Cursor> cursors;
- private final QueryEngineSettings settings;
+ private final QueryLimits settings;
private boolean init;
private boolean closed;
@@ -463,7 +463,7 @@ public class Cursors {
private int cursorListIndex;
private IndexRow current;
- ConcatCursor(List<Cursor> cursors, QueryEngineSettings settings) {
+ ConcatCursor(List<Cursor> cursors, QueryLimits settings) {
this.cursors = cursors;
this.settings = settings;
nextCursor();
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndex.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndex.java Fri Aug 11 16:45:35 2017
@@ -198,7 +198,7 @@ public class AggregateIndex implements A
Cursor newC = flatten(input, plan, filter, state,
path + " and(" + index + ")");
c = Cursors.newIntersectionCursor(c, newC,
- filter.getQueryEngineSettings());
+ filter.getQueryLimits());
}
result.set(c);
return true;
@@ -216,7 +216,7 @@ public class AggregateIndex implements A
}
});
result.set(Cursors.newConcatCursor(cursors,
- filter.getQueryEngineSettings()));
+ filter.getQueryLimits()));
return true;
}
});
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/DiffIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/DiffIndex.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/DiffIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/diffindex/DiffIndex.java Fri Aug 11 16:45:35 2017
@@ -41,7 +41,7 @@ public abstract class DiffIndex implemen
@Override
public Cursor query(Filter filter, NodeState rootState) {
- return Cursors.newPathCursor(collector.getResults(filter), filter.getQueryEngineSettings());
+ return Cursors.newPathCursor(collector.getResults(filter), filter.getQueryLimits());
}
@Override
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndex.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/nodetype/NodeTypeIndex.java Fri Aug 11 16:45:35 2017
@@ -94,7 +94,7 @@ class NodeTypeIndex implements QueryInde
throw new IllegalStateException(
"NodeType index is used even when no index is available for filter " + filter);
}
- return Cursors.newPathCursorDistinct(lookup.query(filter), filter.getQueryEngineSettings());
+ return Cursors.newPathCursorDistinct(lookup.query(filter), filter.getQueryLimits());
}
@Override
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java Fri Aug 11 16:45:35 2017
@@ -41,7 +41,7 @@ import org.apache.jackrabbit.oak.spi.mou
import org.apache.jackrabbit.oak.spi.query.Cursor;
import org.apache.jackrabbit.oak.spi.query.Filter;
import org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction;
-import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
+import org.apache.jackrabbit.oak.spi.query.QueryLimits;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import com.google.common.collect.Iterables;
@@ -266,7 +266,7 @@ public class PropertyIndexPlan {
}
Cursor execute() {
- QueryEngineSettings settings = filter.getQueryEngineSettings();
+ QueryLimits settings = filter.getQueryLimits();
List<Iterable<String>> iterables = Lists.newArrayList();
for (IndexStoreStrategy s : strategies) {
iterables.add(s.query(filter, name, definition, values));
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=1804821&r1=1804820&r2=1804821&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 Fri Aug 11 16:45:35 2017
@@ -17,8 +17,8 @@
package org.apache.jackrabbit.oak.plugins.index.property.strategy;
import static com.google.common.collect.Queues.newArrayDeque;
-import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_CONTENT_NODE_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.ENTRY_COUNT_PROPERTY_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_CONTENT_NODE_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.KEY_COUNT_PROPERTY_NAME;
import java.util.Deque;
@@ -28,24 +28,24 @@ import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import com.google.common.base.Supplier;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.index.counter.ApproximateCounter;
import org.apache.jackrabbit.oak.plugins.index.counter.NodeCounterEditor;
import org.apache.jackrabbit.oak.plugins.index.counter.jmx.NodeCounter;
import org.apache.jackrabbit.oak.plugins.memory.MemoryChildNodeEntry;
import org.apache.jackrabbit.oak.query.FilterIterators;
-import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.QueryLimits;
import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
-import org.apache.jackrabbit.oak.plugins.index.counter.ApproximateCounter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Supplier;
import com.google.common.collect.Iterators;
import com.google.common.collect.Queues;
import com.google.common.collect.Sets;
@@ -335,7 +335,7 @@ public class ContentMirrorStoreStrategy
* Keep the returned path, to avoid returning duplicate entries.
*/
private final Set<String> knownPaths = Sets.newHashSet();
- private final QueryEngineSettings settings;
+ private final QueryLimits settings;
PathIterator(Filter filter, String indexName, String pathPrefix) {
this.filter = filter;
@@ -352,7 +352,7 @@ public class ContentMirrorStoreStrategy
}
parentPath = "";
currentPath = "/";
- this.settings = filter.getQueryEngineSettings();
+ this.settings = filter.getQueryLimits();
}
void enqueue(Iterator<? extends ChildNodeEntry> it) {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/reference/ReferenceIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/reference/ReferenceIndex.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/reference/ReferenceIndex.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/reference/ReferenceIndex.java Fri Aug 11 16:45:35 2017
@@ -121,7 +121,7 @@ class ReferenceIndex implements QueryInd
return lookup(root, uuid, name, WEAK_REF_NAME, filter);
}
}
- return newPathCursor(new ArrayList<String>(), filter.getQueryEngineSettings());
+ return newPathCursor(new ArrayList<String>(), filter.getQueryLimits());
}
private Cursor lookup(NodeState root, String uuid,
@@ -129,7 +129,7 @@ class ReferenceIndex implements QueryInd
NodeState indexRoot = root.getChildNode(INDEX_DEFINITIONS_NAME)
.getChildNode(NAME);
if (!indexRoot.exists()) {
- return newPathCursor(new ArrayList<String>(), filter.getQueryEngineSettings());
+ return newPathCursor(new ArrayList<String>(), filter.getQueryLimits());
}
List<Iterable<String>> iterables = Lists.newArrayList();
for (IndexStoreStrategy s : getStrategies(indexRoot, mountInfoProvider, index)) {
@@ -152,7 +152,7 @@ class ReferenceIndex implements QueryInd
return getParentPath(path);
}
});
- return newPathCursor(paths, filter.getQueryEngineSettings());
+ return newPathCursor(paths, filter.getQueryLimits());
}
private static Set<IndexStoreStrategy> getStrategies(NodeState definition,
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/FilterIterators.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/FilterIterators.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/FilterIterators.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/FilterIterators.java Fri Aug 11 16:45:35 2017
@@ -20,8 +20,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
-import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
-
+import org.apache.jackrabbit.oak.spi.query.QueryLimits;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,7 +42,7 @@ public class FilterIterators {
* @param settings the query engine settings
* @throws UnsupportedOperationException if the limit was exceeded
*/
- public static void checkMemoryLimit(long count, QueryEngineSettings settings) {
+ public static void checkMemoryLimit(long count, QueryLimits settings) {
long maxMemoryEntries = settings.getLimitInMemory();
if (count > maxMemoryEntries) {
String message = "The query read more than " +
@@ -63,7 +62,7 @@ public class FilterIterators {
* @param settings the query engine settings
* @throws UnsupportedOperationException if the limit was exceeded
*/
- public static void checkReadLimit(long count, QueryEngineSettings settings) {
+ public static void checkReadLimit(long count, QueryLimits settings) {
long maxReadEntries = settings.getLimitReads();
if (count > maxReadEntries) {
String message = "The query read or traversed more than " +
@@ -78,7 +77,7 @@ public class FilterIterators {
public static <K> Iterator<K> newCombinedFilter(
Iterator<K> it, boolean distinct, long limit, long offset,
- Comparator<K> orderBy, QueryEngineSettings settings) {
+ Comparator<K> orderBy, QueryLimits settings) {
if (distinct) {
it = FilterIterators.newDistinct(it, settings);
}
@@ -98,7 +97,7 @@ public class FilterIterators {
return it;
}
- public static <K> DistinctIterator<K> newDistinct(Iterator<K> it, QueryEngineSettings settings) {
+ public static <K> DistinctIterator<K> newDistinct(Iterator<K> it, QueryLimits settings) {
return new DistinctIterator<K>(it, settings);
}
@@ -110,7 +109,7 @@ public class FilterIterators {
return new OffsetIterator<K>(it, offset);
}
- public static <K> Iterator<K> newSort(Iterator<K> it, Comparator<K> orderBy, int max, QueryEngineSettings settings) {
+ public static <K> Iterator<K> newSort(Iterator<K> it, Comparator<K> orderBy, int max, QueryLimits settings) {
return new SortIterator<K>(it, orderBy, max, settings);
}
@@ -124,12 +123,12 @@ public class FilterIterators {
static class DistinctIterator<K> implements Iterator<K> {
private final Iterator<K> source;
- private final QueryEngineSettings settings;
+ private final QueryLimits settings;
private final HashSet<K> distinctSet;
private K current;
private boolean end;
- DistinctIterator(Iterator<K> source, QueryEngineSettings settings) {
+ DistinctIterator(Iterator<K> source, QueryLimits settings) {
this.source = source;
this.settings = settings;
distinctSet = new HashSet<K>();
@@ -188,12 +187,12 @@ public class FilterIterators {
static class SortIterator<K> implements Iterator<K> {
private final Iterator<K> source;
- private final QueryEngineSettings settings;
+ private final QueryLimits settings;
private final Comparator<K> orderBy;
private Iterator<K> result;
private final int max;
- SortIterator(Iterator<K> source, Comparator<K> orderBy, int max, QueryEngineSettings settings) {
+ SortIterator(Iterator<K> source, Comparator<K> orderBy, int max, QueryLimits settings) {
this.source = source;
this.orderBy = orderBy;
this.max = max;
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/Query.java Fri Aug 11 16:45:35 2017
@@ -26,6 +26,7 @@ import org.apache.jackrabbit.oak.api.Res
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.query.ast.ColumnImpl;
import org.apache.jackrabbit.oak.query.ast.OrderingImpl;
+import org.apache.jackrabbit.oak.query.stats.QueryStatsData.QueryExecutionStats;
/**
* A "select" or "union" query.
@@ -206,5 +207,7 @@ public interface Query {
* fail in this case
*/
void verifyNotPotentiallySlow();
+
+ QueryExecutionStats getQueryExecutionStats();
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryEngineImpl.java Fri Aug 11 16:45:35 2017
@@ -36,6 +36,7 @@ import org.apache.jackrabbit.oak.namepat
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.namepath.NamePathMapperImpl;
import org.apache.jackrabbit.oak.query.ast.NodeTypeInfoProvider;
+import org.apache.jackrabbit.oak.query.stats.QueryStatsData.QueryExecutionStats;
import org.apache.jackrabbit.oak.query.xpath.XPathToSQL2Converter;
import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
import org.slf4j.Logger;
@@ -158,8 +159,9 @@ public abstract class QueryEngineImpl im
NodeTypeInfoProvider nodeTypes = context.getNodeTypeInfoProvider();
QueryEngineSettings settings = context.getSettings();
+ QueryExecutionStats stats = settings.getQueryStatsReporter().getQueryExecution(statement, language);
- SQL2Parser parser = new SQL2Parser(mapper, nodeTypes, settings);
+ SQL2Parser parser = new SQL2Parser(mapper, nodeTypes, settings, stats);
if (language.endsWith(NO_LITERALS)) {
language = language.substring(0, language.length() - NO_LITERALS.length());
parser.setAllowNumberLiterals(false);
@@ -192,6 +194,11 @@ public abstract class QueryEngineImpl im
} else {
throw new ParseException("Unsupported language: " + language, 0);
}
+ if (q.isInternal()) {
+ stats.setInternal(true);
+ } else {
+ stats.setThreadName(Thread.currentThread().getName());
+ }
queries.add(q);
@@ -267,7 +274,9 @@ public abstract class QueryEngineImpl im
boolean mdc = false;
try {
+ long start = System.nanoTime();
Query query = prepareAndSelect(queries);
+ query.getQueryExecutionStats().execute(System.nanoTime() - start);
mdc = setupMDC(query);
return query.executeQuery();
} finally {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java Fri Aug 11 16:45:35 2017
@@ -36,6 +36,7 @@ import org.apache.jackrabbit.oak.api.Res
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.namepath.JcrPathParser;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyValues;
import org.apache.jackrabbit.oak.query.QueryOptions.Traversal;
import org.apache.jackrabbit.oak.query.ast.AndImpl;
import org.apache.jackrabbit.oak.query.ast.AstVisitorBase;
@@ -79,8 +80,8 @@ import org.apache.jackrabbit.oak.query.i
import org.apache.jackrabbit.oak.query.index.TraversingIndex;
import org.apache.jackrabbit.oak.query.plan.ExecutionPlan;
import org.apache.jackrabbit.oak.query.plan.SelectorExecutionPlan;
+import org.apache.jackrabbit.oak.query.stats.QueryStatsData.QueryExecutionStats;
import org.apache.jackrabbit.oak.spi.query.Filter;
-import org.apache.jackrabbit.oak.plugins.memory.PropertyValues;
import org.apache.jackrabbit.oak.spi.query.QueryConstants;
import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
import org.apache.jackrabbit.oak.spi.query.QueryIndex;
@@ -111,6 +112,8 @@ public class QueryImpl implements Query
private static final Logger LOG = LoggerFactory.getLogger(QueryImpl.class);
+ private final QueryExecutionStats stats;
+
private boolean potentiallySlowTraversalQueryLogged;
private static final Ordering<QueryIndex> MINIMAL_COST_ORDERING = new Ordering<QueryIndex>() {
@@ -176,13 +179,15 @@ public class QueryImpl implements Query
private boolean potentiallySlowTraversalQuery;
QueryImpl(String statement, SourceImpl source, ConstraintImpl constraint,
- ColumnImpl[] columns, NamePathMapper mapper, QueryEngineSettings settings) {
+ ColumnImpl[] columns, NamePathMapper mapper, QueryEngineSettings settings,
+ QueryExecutionStats stats) {
this.statement = statement;
this.source = source;
this.constraint = constraint;
this.columns = columns;
this.namePathMapper = mapper;
this.settings = settings;
+ this.stats = stats;
}
@Override
@@ -801,6 +806,8 @@ public class QueryImpl implements Query
if (end) {
return;
}
+ long nanos = System.nanoTime();
+ long oldIndex = rowIndex;
if (!started) {
source.execute(rootState);
started = true;
@@ -823,6 +830,8 @@ public class QueryImpl implements Query
break;
}
}
+ nanos = System.nanoTime() - nanos;
+ stats.read(rowIndex - oldIndex, rowIndex, nanos);
}
@Override
@@ -1338,7 +1347,8 @@ public class QueryImpl implements Query
this.constraint,
cols.toArray(new ColumnImpl[0]),
this.namePathMapper,
- this.settings);
+ this.settings,
+ this.stats);
copy.explain = this.explain;
copy.distinct = this.distinct;
@@ -1364,4 +1374,8 @@ public class QueryImpl implements Query
return queryOptions;
}
+ public QueryExecutionStats getQueryExecutionStats() {
+ return stats;
+ }
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/SQL2Parser.java Fri Aug 11 16:45:35 2017
@@ -54,6 +54,7 @@ import org.apache.jackrabbit.oak.query.a
import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
import org.apache.jackrabbit.oak.query.ast.SourceImpl;
import org.apache.jackrabbit.oak.query.ast.StaticOperandImpl;
+import org.apache.jackrabbit.oak.query.stats.QueryStatsData.QueryExecutionStats;
import org.apache.jackrabbit.oak.plugins.memory.PropertyValues;
import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
import org.apache.jackrabbit.oak.spi.query.QueryConstants;
@@ -114,6 +115,8 @@ public class SQL2Parser {
private boolean literalUsageLogged;
+ private final QueryExecutionStats stats;
+
/**
* Create a new parser. A parser can be re-used, but it is not thread safe.
*
@@ -121,10 +124,12 @@ public class SQL2Parser {
* @param nodeTypes the nodetypes
* @param settings the query engine settings
*/
- public SQL2Parser(NamePathMapper namePathMapper, NodeTypeInfoProvider nodeTypes, QueryEngineSettings settings) {
+ public SQL2Parser(NamePathMapper namePathMapper, NodeTypeInfoProvider nodeTypes, QueryEngineSettings settings,
+ QueryExecutionStats stats) {
this.namePathMapper = namePathMapper;
this.nodeTypes = checkNotNull(nodeTypes);
this.settings = checkNotNull(settings);
+ this.stats = checkNotNull(stats);
}
/**
@@ -231,7 +236,7 @@ public class SQL2Parser {
constraint = parseConstraint();
}
QueryImpl q = new QueryImpl(
- statement, source, constraint, columnArray, namePathMapper, settings);
+ statement, source, constraint, columnArray, namePathMapper, settings, stats);
q.setDistinct(distinct);
return q;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/UnionQueryImpl.java Fri Aug 11 16:45:35 2017
@@ -21,22 +21,22 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Maps;
-
import org.apache.jackrabbit.oak.api.PropertyValue;
import org.apache.jackrabbit.oak.api.Result;
import org.apache.jackrabbit.oak.api.Result.SizePrecision;
import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyValues;
+import org.apache.jackrabbit.oak.query.QueryImpl.MeasuringIterator;
import org.apache.jackrabbit.oak.query.ast.ColumnImpl;
import org.apache.jackrabbit.oak.query.ast.OrderingImpl;
-import org.apache.jackrabbit.oak.query.QueryImpl.MeasuringIterator;
-import org.apache.jackrabbit.oak.plugins.memory.PropertyValues;
+import org.apache.jackrabbit.oak.query.stats.QueryStatsData.QueryExecutionStats;
import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterators;
+import com.google.common.collect.Maps;
/**
* Represents a union query.
@@ -408,5 +408,9 @@ public class UnionQueryImpl implements Q
left.verifyNotPotentiallySlow();
right.verifyNotPotentiallySlow();
}
+
+ public QueryExecutionStats getQueryExecutionStats() {
+ return left.getQueryExecutionStats();
+ }
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/SelectorImpl.java Fri Aug 11 16:45:35 2017
@@ -426,6 +426,7 @@ public class SelectorImpl extends Source
public boolean next() {
while (cursor != null && cursor.hasNext()) {
scanCount++;
+ query.getQueryExecutionStats().scan(1, scanCount);
currentRow = cursor.next();
if (isParent) {
// we must not check whether the _parent_ is readable
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/FilterImpl.java Fri Aug 11 16:45:35 2017
@@ -36,7 +36,7 @@ import com.google.common.collect.ArrayLi
import com.google.common.collect.ListMultimap;
import org.apache.jackrabbit.oak.api.PropertyValue;
import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
+import org.apache.jackrabbit.oak.spi.query.QueryLimits;
import org.apache.jackrabbit.oak.query.ast.JoinConditionImpl;
import org.apache.jackrabbit.oak.query.ast.NativeFunctionImpl;
import org.apache.jackrabbit.oak.query.ast.Operator;
@@ -57,7 +57,7 @@ public class FilterImpl implements Filte
private final String queryStatement;
- private final QueryEngineSettings settings;
+ private final QueryLimits settings;
/**
* Whether the filter is always false.
@@ -125,7 +125,19 @@ public class FilterImpl implements Filte
}
private FilterImpl() {
- this(null, null, new QueryEngineSettings());
+ this(null, null, new QueryLimits() {
+
+ @Override
+ public long getLimitInMemory() {
+ return Long.MAX_VALUE;
+ }
+
+ @Override
+ public long getLimitReads() {
+ return Long.MAX_VALUE;
+ }
+
+ });
}
/**
@@ -134,7 +146,7 @@ public class FilterImpl implements Filte
* @param selector the selector for the given filter
* @param queryStatement the query statement
*/
- public FilterImpl(SelectorImpl selector, String queryStatement, QueryEngineSettings settings) {
+ public FilterImpl(SelectorImpl selector, String queryStatement, QueryLimits settings) {
this.selector = selector;
this.queryStatement = queryStatement;
this.matchesAllTypes = selector != null ? selector.matchesAllTypes()
@@ -155,7 +167,7 @@ public class FilterImpl implements Filte
this.selector = impl.selector;
this.matchesAllTypes = selector != null ? selector.matchesAllTypes()
: false;
- this.settings = filter.getQueryEngineSettings();
+ this.settings = filter.getQueryLimits();
}
public void setPreparing(boolean preparing) {
@@ -603,7 +615,7 @@ public class FilterImpl implements Filte
}
@Override
- public QueryEngineSettings getQueryEngineSettings() {
+ public QueryLimits getQueryLimits() {
return settings;
}
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsData.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsData.java?rev=1804821&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsData.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsData.java Fri Aug 11 16:45:35 2017
@@ -0,0 +1,179 @@
+/*
+ * 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.query.stats;
+
+import org.apache.jackrabbit.oak.commons.json.JsopBuilder;
+
+public class QueryStatsData {
+
+ private final String query;
+ private final String language;
+ private final long createdMillis = System.currentTimeMillis();
+ private boolean internal;
+ private String lastThreadName;
+ private long lastExecutedMillis;
+ private long executeCount;
+
+ /**
+ * Rows read by iterating over the query result.
+ */
+ private long totalRowsRead;
+ private long maxRowsRead;
+
+ /**
+ * Rows returned by the index.
+ */
+ private long totalRowsScanned;
+ private long maxRowsScanned;
+ private long planNanos;
+ private long readNanos;
+ private long maxTimeNanos;
+ private boolean captureStackTraces;
+
+ public QueryStatsData(String query, String language) {
+ this.query = query;
+ this.language = language;
+ }
+
+ public String getKey() {
+ return query + "/" + language;
+ }
+
+ /**
+ * The maximum CPU time needed to run one query.
+ *
+ * @return the time in nanoseconds
+ */
+ public long getMaxTimeNanos() {
+ return maxTimeNanos;
+ }
+
+ public long getTotalTimeNanos() {
+ return planNanos + readNanos;
+ }
+
+ public long getMaxRowsScanned() {
+ return maxRowsScanned;
+ }
+
+ public void setCaptureStackTraces(boolean captureStackTraces) {
+ this.captureStackTraces = captureStackTraces;
+ }
+
+ public long getCreatedMillis() {
+ return createdMillis;
+ }
+
+
+ public long getExecuteCount() {
+ return executeCount;
+ }
+
+ public long getTotalRowsRead() {
+ return totalRowsRead;
+ }
+
+ public long getTotalRowsScanned() {
+ return totalRowsScanned;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public String getQuery() {
+ return query;
+ }
+
+ public boolean isInternal() {
+ return internal;
+ }
+
+ public String getLastThreadName() {
+ return lastThreadName;
+ }
+
+ public long getLastExecutedMillis() {
+ return lastExecutedMillis;
+ }
+
+ @Override
+ public String toString() {
+ return new JsopBuilder().object().
+ key("createdMillis").value(getTimeString(createdMillis)).
+ key("lastExecutedMillis").value(getTimeString(lastExecutedMillis)).
+ key("executeCount").value(executeCount).
+ key("totalRowsRead").value(totalRowsRead).
+ key("maxRowsRead").value(maxRowsRead).
+ key("totalRowsScanned").value(totalRowsScanned).
+ key("maxRowsScanned").value(maxRowsScanned).
+ key("planNanos").value(planNanos).
+ key("readNanos").value(readNanos).
+ key("maxTimeNanos").value(maxTimeNanos).
+ key("internal").value(internal).
+ key("query").value(query).
+ key("language").value(language).
+ key("lastThreadName").value(lastThreadName).
+ endObject().toString();
+ }
+
+ public static final String getTimeString(long timeMillis) {
+ return String.format("%tF %tT", timeMillis, timeMillis);
+ }
+
+ public class QueryExecutionStats {
+
+ long time;
+
+ public void execute(long nanos) {
+ executeCount++;
+ lastExecutedMillis = System.currentTimeMillis();
+ time += nanos;
+ planNanos += nanos;
+ maxTimeNanos = Math.max(maxTimeNanos, time);
+ }
+
+ public void setInternal(boolean b) {
+ internal = b;
+ }
+
+ public void setThreadName(String name) {
+ if (captureStackTraces) {
+ StringBuilder buff = new StringBuilder();
+ for(StackTraceElement e : Thread.currentThread().getStackTrace()) {
+ buff.append("\n\tat " + e);
+ }
+ name = name + buff.toString();
+ }
+ lastThreadName = name;
+ }
+
+ public void read(long count, long max, long nanos) {
+ totalRowsRead += count;
+ maxRowsRead = Math.max(maxRowsRead, max);
+ time += nanos;
+ readNanos += nanos;
+ maxTimeNanos = Math.max(maxTimeNanos, time);
+ }
+
+ public void scan(long count, long max) {
+ totalRowsScanned += count;
+ maxRowsScanned = Math.max(maxRowsScanned, max);
+ }
+ }
+
+}
\ No newline at end of file
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsMBean.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsMBean.java?rev=1804821&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsMBean.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsMBean.java Fri Aug 11 16:45:35 2017
@@ -0,0 +1,58 @@
+/*
+ * 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.query.stats;
+
+import javax.management.openmbean.TabularData;
+
+import org.apache.jackrabbit.oak.api.jmx.Description;
+
+public interface QueryStatsMBean {
+
+ String TYPE = "QueryStats";
+
+ /**
+ * Get the slow queries. Those are the ones that scan more than 100'000
+ * nodes, or the configured maximum number of nodes to scan. (Raw execution
+ * time is not taken into account, as execution can be slow if the code is
+ * not compiled yet.)
+ *
+ * @return the slow queries table
+ */
+ @Description("Get the slow queries (those that scan/traverse over many nodes).")
+ TabularData getSlowQueries();
+
+ @Description("Get the popular queries (those that take most of the time).")
+ TabularData getPopularQueries();
+
+ @Description("Get all data as Json.")
+ String asJson();
+
+ @Description("Reset the statistics (clear the list of queries).")
+ void resetStats();
+
+ /**
+ * Whether to capture a thread dump in addition to the thread name.
+ * No thread name / thread dump is captures for internal queries.
+ *
+ * @param captureStackTraces the new valu
+ */
+ @Description("Enable / disable capturing the thread dumps (in addition to the thread name).")
+ void setCaptureStackTraces(boolean captureStackTraces);
+
+ boolean getCaptureStackTraces();
+
+}
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsMBeanImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsMBeanImpl.java?rev=1804821&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsMBeanImpl.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsMBeanImpl.java Fri Aug 11 16:45:35 2017
@@ -0,0 +1,229 @@
+/*
+ * 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.query.stats;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+import org.apache.jackrabbit.oak.commons.jmx.AnnotatedStandardMBean;
+import org.apache.jackrabbit.oak.query.stats.QueryStatsData.QueryExecutionStats;
+import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class QueryStatsMBeanImpl extends AnnotatedStandardMBean
+ implements QueryStatsMBean, QueryStatsReporter {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+ private final int SLOW_QUERY_LIMIT_SCANNED =
+ Integer.getInteger("oak.query.slowScanLimit", 100000);
+ private final int MAX_STATS_DATA =
+ Integer.getInteger("oak.query.stats", 5000);
+ private final int MAX_POPULAR_QUERIES =
+ Integer.getInteger("oak.query.slowLimit", 100);
+ private final ConcurrentSkipListMap<String, QueryStatsData> statistics =
+ new ConcurrentSkipListMap<String, QueryStatsData>();
+ private final QueryEngineSettings settings;
+ private boolean captureStackTraces;
+ private int evictionCount;
+
+ public QueryStatsMBeanImpl(QueryEngineSettings settings) {
+ super(QueryStatsMBean.class);
+ this.settings = settings;
+ }
+
+ @Override
+ public TabularData getSlowQueries() {
+ ArrayList<QueryStatsData> list = new ArrayList<QueryStatsData>();
+ long maxScanned = Math.min(SLOW_QUERY_LIMIT_SCANNED, settings.getLimitReads());
+ for(QueryStatsData s : statistics.values()) {
+ if(s.getMaxRowsScanned() > maxScanned) {
+ list.add(s);
+ }
+ }
+ Collections.sort(list, new Comparator<QueryStatsData>() {
+ @Override
+ public int compare(QueryStatsData o1, QueryStatsData o2) {
+ return -Long.compare(o1.getMaxTimeNanos(), o2.getMaxTimeNanos());
+ }
+ });
+ return asTabularData(list);
+ }
+
+ @Override
+ public TabularData getPopularQueries() {
+ ArrayList<QueryStatsData> list = new ArrayList<QueryStatsData>(statistics.values());
+ Collections.sort(list, new Comparator<QueryStatsData>() {
+ @Override
+ public int compare(QueryStatsData o1, QueryStatsData o2) {
+ return -Long.compare(o1.getTotalTimeNanos(), o2.getTotalTimeNanos());
+ }
+ });
+ while (list.size() > MAX_POPULAR_QUERIES) {
+ list.remove(list.size() - 1);
+ }
+ return asTabularData(list);
+ }
+
+ @Override
+ public void resetStats() {
+ statistics.clear();
+ }
+
+ @Override
+ public void setCaptureStackTraces(boolean captureStackTraces) {
+ this.captureStackTraces = captureStackTraces;
+ }
+
+ @Override
+ public boolean getCaptureStackTraces() {
+ return captureStackTraces;
+ }
+
+ @Override
+ public String asJson() {
+ ArrayList<QueryStatsData> list = new ArrayList<QueryStatsData>(statistics.values());
+ Collections.sort(list, new Comparator<QueryStatsData>() {
+ @Override
+ public int compare(QueryStatsData o1, QueryStatsData o2) {
+ return -Long.compare(o1.getTotalTimeNanos(), o2.getTotalTimeNanos());
+ }
+ });
+ StringBuilder buff = new StringBuilder();
+ buff.append("[\n");
+ int i = 0;
+ for(QueryStatsData s : list) {
+ if (i++ > 0) {
+ buff.append(",\n");
+ }
+ buff.append(s.toString());
+ }
+ return buff.append("\n]\n").toString();
+ }
+
+ @Override
+ public QueryExecutionStats getQueryExecution(String statement, String language) {
+ if (log.isTraceEnabled()) {
+ log.trace("Execute " + language + " / " + statement);
+ }
+ if (statistics.size() > 2 * MAX_STATS_DATA) {
+ evict();
+ }
+ QueryStatsData stats = new QueryStatsData(statement, language);
+ QueryStatsData s2 = statistics.putIfAbsent(stats.getKey(), stats);
+ if (s2 != null) {
+ stats = s2;
+ }
+ stats.setCaptureStackTraces(captureStackTraces);
+ return stats.new QueryExecutionStats();
+ }
+
+ private void evict() {
+ evictionCount++;
+ // retain 50% of the slowest entries
+ // of the rest, retain the newest entries
+ ArrayList<QueryStatsData> list = new ArrayList<QueryStatsData>(statistics.values());
+ Collections.sort(list, new Comparator<QueryStatsData>() {
+ @Override
+ public int compare(QueryStatsData o1, QueryStatsData o2) {
+ int comp = -Long.compare(o1.getTotalTimeNanos(), o2.getTotalTimeNanos());
+ if (comp == 0) {
+ comp = -Long.compare(o1.getCreatedMillis(), o2.getCreatedMillis());
+ }
+ return comp;
+ }
+ });
+ Collections.sort(list.subList(MAX_STATS_DATA / 2, MAX_STATS_DATA), new Comparator<QueryStatsData>() {
+ @Override
+ public int compare(QueryStatsData o1, QueryStatsData o2) {
+ return -Long.compare(o1.getCreatedMillis(), o2.getCreatedMillis());
+ }
+ });
+ for (int i = MAX_STATS_DATA; i < list.size(); i++) {
+ statistics.remove(list.get(i).getKey());
+ }
+ }
+
+ public int getEvictionCount() {
+ return evictionCount;
+ }
+
+ private TabularData asTabularData(ArrayList<QueryStatsData> list) {
+ TabularDataSupport tds = null;
+ try {
+ CompositeType ct = QueryStatsCompositeTypeFactory.getCompositeType();
+ TabularType tt = new TabularType(QueryStatsData.class.getName(),
+ "Query History", ct, QueryStatsCompositeTypeFactory.index);
+ tds = new TabularDataSupport(tt);
+ int position = 1;
+ for (QueryStatsData q : list) {
+ tds.put(new CompositeDataSupport(ct,
+ QueryStatsCompositeTypeFactory.names,
+ QueryStatsCompositeTypeFactory.getValues(q, position++)));
+ }
+ return tds;
+ } catch (Exception e) {
+ log.debug("Error", e);
+ return null;
+ }
+ }
+
+ private static class QueryStatsCompositeTypeFactory {
+
+ private final static String[] index = { "position" };
+
+ private final static String[] names = { "position",
+ "maxTimeMillis", "totalTimeMillis", "executeCount",
+ "rowsRead", "rowsScanned", "maxRowsScanned",
+ "language", "statement", "lastExecuted",
+ "lastThread"};
+
+ private final static String[] descriptions = names;
+
+ @SuppressWarnings("rawtypes")
+ private final static OpenType[] types = { SimpleType.LONG,
+ SimpleType.LONG, SimpleType.LONG, SimpleType.LONG,
+ SimpleType.LONG, SimpleType.LONG, SimpleType.LONG,
+ SimpleType.STRING, SimpleType.STRING, SimpleType.STRING,
+ SimpleType.STRING};
+
+ public static CompositeType getCompositeType() throws OpenDataException {
+ return new CompositeType(QueryStatsMBean.class.getName(),
+ QueryStatsMBean.class.getName(), names, descriptions, types);
+ }
+
+ public static Object[] getValues(QueryStatsData q, int position) {
+ return new Object[] { (long) position,
+ q.getMaxTimeNanos() / 1000000, q.getTotalTimeNanos() / 1000000, q.getExecuteCount(),
+ q.getTotalRowsRead(), q.getTotalRowsScanned(), q.getMaxRowsScanned(),
+ q.getLanguage(), q.getQuery(), QueryStatsData.getTimeString(q.getLastExecutedMillis()),
+ q.isInternal() ? "(internal query)" : q.getLastThreadName()};
+ }
+ }
+
+}
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsReporter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsReporter.java?rev=1804821&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsReporter.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsReporter.java Fri Aug 11 16:45:35 2017
@@ -0,0 +1,25 @@
+/*
+ * 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.query.stats;
+
+import org.apache.jackrabbit.oak.query.stats.QueryStatsData.QueryExecutionStats;
+
+public interface QueryStatsReporter {
+
+ QueryExecutionStats getQueryExecution(String statement, String language);
+
+}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/Filter.java Fri Aug 11 16:45:35 2017
@@ -68,7 +68,7 @@ public interface Filter {
*/
FullTextExpression getFullTextConstraint();
- QueryEngineSettings getQueryEngineSettings();
+ QueryLimits getQueryLimits();
/**
* check whether a certain (valid) path is accessible (can be read) from the user associated with the query Session
@@ -430,7 +430,7 @@ public interface Filter {
}
@Override
- public QueryEngineSettings getQueryEngineSettings() {
+ public QueryEngineSettings getQueryLimits() {
return EMPTY_SETTINGS;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryEngineSettings.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryEngineSettings.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryEngineSettings.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryEngineSettings.java Fri Aug 11 16:45:35 2017
@@ -19,11 +19,14 @@
package org.apache.jackrabbit.oak.spi.query;
import org.apache.jackrabbit.oak.api.jmx.QueryEngineSettingsMBean;
+import org.apache.jackrabbit.oak.query.stats.QueryStatsMBean;
+import org.apache.jackrabbit.oak.query.stats.QueryStatsMBeanImpl;
+import org.apache.jackrabbit.oak.query.stats.QueryStatsReporter;
/**
* Settings of the query engine.
*/
-public class QueryEngineSettings implements QueryEngineSettingsMBean {
+public class QueryEngineSettings implements QueryEngineSettingsMBean, QueryLimits {
/**
* the flag used to turn on/off the optimisations on top of the {@link org.apache.jackrabbit.oak.query.Query} object.
@@ -71,6 +74,8 @@ public class QueryEngineSettings impleme
public static final boolean DEFAULT_FAST_QUERY_SIZE = Boolean.getBoolean(OAK_FAST_QUERY_SIZE);
private boolean fastQuerySize = DEFAULT_FAST_QUERY_SIZE;
+ private QueryStatsMBeanImpl queryStats = new QueryStatsMBeanImpl(this);
+
public QueryEngineSettings() {
}
@@ -127,6 +132,14 @@ public class QueryEngineSettings impleme
return sql2Optimisation;
}
+ public QueryStatsMBean getQueryStats() {
+ return queryStats;
+ }
+
+ public QueryStatsReporter getQueryStatsReporter() {
+ return queryStats;
+ }
+
@Override
public String toString() {
return "QueryEngineSettings{" +
Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryLimits.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryLimits.java?rev=1804821&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryLimits.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryLimits.java Fri Aug 11 16:45:35 2017
@@ -0,0 +1,26 @@
+/*
+ * 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.spi.query;
+
+public interface QueryLimits {
+
+ long getLimitInMemory();
+
+ long getLimitReads();
+}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/FilterTest.java Fri Aug 11 16:45:35 2017
@@ -17,18 +17,14 @@
package org.apache.jackrabbit.oak.query;
-import static org.apache.jackrabbit.oak.InitialContent.INITIAL_CONTENT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import java.text.ParseException;
-import org.apache.jackrabbit.oak.namepath.NamePathMapper;
-import org.apache.jackrabbit.oak.query.ast.NodeTypeInfoProvider;
import org.apache.jackrabbit.oak.query.xpath.XPathToSQL2Converter;
import org.apache.jackrabbit.oak.spi.query.Filter;
-import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
import org.junit.Ignore;
import org.junit.Test;
@@ -37,9 +33,7 @@ import org.junit.Test;
*/
public class FilterTest {
- private final NodeTypeInfoProvider nodeTypes = new NodeStateNodeTypeInfoProvider(INITIAL_CONTENT);
-
- private final SQL2Parser p = new SQL2Parser(NamePathMapper.DEFAULT, nodeTypes, new QueryEngineSettings());
+ private final SQL2Parser p = SQL2ParserTest.createTestSQL2Parser();
private Filter createFilter(String xpath) throws ParseException {
String sql = new XPathToSQL2Converter().convert(xpath);
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/LargeQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/LargeQueryTest.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/LargeQueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/LargeQueryTest.java Fri Aug 11 16:45:35 2017
@@ -16,21 +16,18 @@
*/
package org.apache.jackrabbit.oak.query;
-import static org.apache.jackrabbit.oak.InitialContent.INITIAL_CONTENT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.text.ParseException;
import java.util.Random;
-import org.apache.jackrabbit.oak.query.ast.NodeTypeInfoProvider;
import org.apache.jackrabbit.oak.query.xpath.XPathToSQL2Converter;
-import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
import org.junit.Test;
public class LargeQueryTest {
- private final NodeTypeInfoProvider nodeTypes = new NodeStateNodeTypeInfoProvider(INITIAL_CONTENT);
+ private final SQL2Parser parser = SQL2ParserTest.createTestSQL2Parser();
@Test
public void testSimpleOr() throws ParseException {
@@ -111,8 +108,7 @@ public class LargeQueryTest {
sql2 = sql2.substring(0, xpathIndex);
// should use union now
assertTrue(sql2.indexOf(" or ") < 0);
- SQL2Parser p = new SQL2Parser(null, nodeTypes, new QueryEngineSettings());
- p.parse(sql2);
+ parser.parse(sql2);
}
private String randomCondition(Random r) {
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/NativeQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/NativeQueryTest.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/NativeQueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/NativeQueryTest.java Fri Aug 11 16:45:35 2017
@@ -27,9 +27,6 @@ import org.apache.jackrabbit.oak.api.Res
import org.apache.jackrabbit.oak.api.ResultRow;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.core.ImmutableRoot;
-import org.apache.jackrabbit.oak.namepath.NamePathMapper;
-import org.apache.jackrabbit.oak.query.ast.NodeTypeInfoProvider;
-import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
import org.junit.Test;
public class NativeQueryTest {
@@ -37,9 +34,7 @@ public class NativeQueryTest {
private final ImmutableRoot ROOT = new ImmutableRoot(INITIAL_CONTENT);
private final QueryEngineImpl QUERY_ENGINE = (QueryEngineImpl)ROOT.getQueryEngine();
- private final NodeTypeInfoProvider nodeTypes = new NodeStateNodeTypeInfoProvider(INITIAL_CONTENT);
-
- private final SQL2Parser p = new SQL2Parser(NamePathMapper.DEFAULT, nodeTypes, new QueryEngineSettings());
+ private final SQL2Parser p = SQL2ParserTest.createTestSQL2Parser();
@Test
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryCostOverheadTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryCostOverheadTest.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryCostOverheadTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryCostOverheadTest.java Fri Aug 11 16:45:35 2017
@@ -39,8 +39,8 @@ public class QueryCostOverheadTest {
c1 = new ComparisonImpl(null, null, null);
c2 = new FullTextSearchImpl(null, null, null);
union = new UnionQueryImpl(false,
- new QueryImpl(null, null, c1, null, null, null),
- new QueryImpl(null, null, c2, null, null, null),
+ createQuery(c1),
+ createQuery(c2),
null);
assertFalse("we always expect false from a `UnionQueryImpl`",
union.containsUnfilteredFullTextCondition());
@@ -48,14 +48,14 @@ public class QueryCostOverheadTest {
c1 = new ComparisonImpl(null, null, null);
c2 = new FullTextSearchImpl(null, null, null);
c = new OrImpl(c1, c2);
- query = new QueryImpl(null, null, c, null, null, null);
+ query = createQuery(c);
assertTrue(query.containsUnfilteredFullTextCondition());
c1 = new ComparisonImpl(null, null, null);
c2 = new FullTextSearchImpl(null, null, null);
c3 = new FullTextSearchImpl(null, null, null);
c = new OrImpl(of(c1, c2, c3));
- query = new QueryImpl(null, null, c, null, null, null);
+ query = createQuery(c);
assertTrue(query.containsUnfilteredFullTextCondition());
c2 = new FullTextSearchImpl(null, null, null);
@@ -64,32 +64,35 @@ public class QueryCostOverheadTest {
c1 = new OrImpl(of(c2, c3, c4));
c5 = mock(DescendantNodeImpl.class);
c = new AndImpl(c1, c5);
- query = new QueryImpl(null, null, c, null, null, null);
+ query = createQuery(c);
assertTrue(query.containsUnfilteredFullTextCondition());
c = new FullTextSearchImpl(null, null, null);
- query = new QueryImpl(null, null, c, null, null, null);
+ query = createQuery(c);
assertFalse(query.containsUnfilteredFullTextCondition());
c1 = new FullTextSearchImpl(null, null, null);
c2 = new FullTextSearchImpl(null, null, null);
c3 = new FullTextSearchImpl(null, null, null);
c = new OrImpl(of(c1, c2, c3));
- query = new QueryImpl(null, null, c, null, null, null);
+ query = createQuery(c);
assertFalse(query.containsUnfilteredFullTextCondition());
c1 = new ComparisonImpl(null, null, null);
c2 = new FullTextSearchImpl(null, null, null);
c3 = new FullTextSearchImpl(null, null, null);
c = new AndImpl(of(c1, c2, c3));
- query = new QueryImpl(null, null, c, null, null, null);
+ query = createQuery(c);
assertFalse(query.containsUnfilteredFullTextCondition());
c1 = new ComparisonImpl(null, null, null);
c2 = new ComparisonImpl(null, null, null);
c = new AndImpl(of(c1, c2, c3));
- query = new QueryImpl(null, null, c, null, null, null);
+ query = createQuery(c);
assertFalse(query.containsUnfilteredFullTextCondition());
-
+ }
+
+ QueryImpl createQuery(ConstraintImpl c) {
+ return new QueryImpl(null, null, c, null, null, null, null);
}
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2OptimiseQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2OptimiseQueryTest.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2OptimiseQueryTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2OptimiseQueryTest.java Fri Aug 11 16:45:35 2017
@@ -188,7 +188,8 @@ public class SQL2OptimiseQueryTest exten
*/
@Test
public void optimise() throws ParseException {
- SQL2Parser parser = new SQL2Parser(getMappings(), getNodeTypes(), qeSettings);
+ SQL2Parser parser = SQL2ParserTest.createTestSQL2Parser(
+ getMappings(), getNodeTypes(), qeSettings);
String statement;
Query original, optimised;
@@ -262,7 +263,8 @@ public class SQL2OptimiseQueryTest exten
}
private void optimiseAndOrAnd(String statement, String expected) throws ParseException {
- SQL2Parser parser = new SQL2Parser(getMappings(), getNodeTypes(), qeSettings);
+ SQL2Parser parser = SQL2ParserTest.createTestSQL2Parser(
+ getMappings(), getNodeTypes(), qeSettings);
Query original;
original = parser.parse(statement, false);
assertNotNull(original);
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java Fri Aug 11 16:45:35 2017
@@ -21,7 +21,12 @@ import static org.junit.Assert.assertTru
import java.text.ParseException;
+import org.apache.jackrabbit.oak.api.QueryEngine;
+import org.apache.jackrabbit.oak.namepath.LocalNameMapper;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.namepath.NamePathMapperImpl;
import org.apache.jackrabbit.oak.query.ast.NodeTypeInfoProvider;
+import org.apache.jackrabbit.oak.query.stats.QueryStatsData;
import org.apache.jackrabbit.oak.query.xpath.XPathToSQL2Converter;
import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
import org.junit.Test;
@@ -31,9 +36,21 @@ import org.junit.Test;
*/
public class SQL2ParserTest {
- private final NodeTypeInfoProvider nodeTypes = new NodeStateNodeTypeInfoProvider(INITIAL_CONTENT);
+ private static final NodeTypeInfoProvider nodeTypes = new NodeStateNodeTypeInfoProvider(INITIAL_CONTENT);
+
+ private static final SQL2Parser p = createTestSQL2Parser();
+
+ public static SQL2Parser createTestSQL2Parser() {
+ return createTestSQL2Parser(NamePathMapper.DEFAULT, nodeTypes, new QueryEngineSettings());
+ }
+
+ public static SQL2Parser createTestSQL2Parser(NamePathMapper mappings, NodeTypeInfoProvider nodeTypes2,
+ QueryEngineSettings qeSettings) {
+ QueryStatsData data = new QueryStatsData("", "");
+ return new SQL2Parser(mappings, nodeTypes2, new QueryEngineSettings(),
+ data.new QueryExecutionStats());
+ }
- private final SQL2Parser p = new SQL2Parser(null, nodeTypes, new QueryEngineSettings());
@Test
public void testIgnoreSqlComment() throws ParseException {
@@ -70,5 +87,5 @@ public class SQL2ParserTest {
String token = "and b.[type] in('t1', 't2', 't3')";
assertTrue(q.contains(token));
}
-
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java?rev=1804821&r1=1804820&r2=1804821&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/XPathTest.java Fri Aug 11 16:45:35 2017
@@ -16,16 +16,13 @@
*/
package org.apache.jackrabbit.oak.query;
-import static org.apache.jackrabbit.oak.InitialContent.INITIAL_CONTENT;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.text.ParseException;
-import org.apache.jackrabbit.oak.query.ast.NodeTypeInfoProvider;
import org.apache.jackrabbit.oak.query.xpath.XPathToSQL2Converter;
-import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
import org.junit.Test;
/**
@@ -33,8 +30,7 @@ import org.junit.Test;
*/
public class XPathTest {
- private final NodeTypeInfoProvider nodeTypes =
- new NodeStateNodeTypeInfoProvider(INITIAL_CONTENT);
+ private final SQL2Parser parser = SQL2ParserTest.createTestSQL2Parser();
@Test
public void complexQuery() throws ParseException {
@@ -65,8 +61,7 @@ public class XPathTest {
String xpath = buff.toString();
String sql2 = new XPathToSQL2Converter().convert(xpath);
assertTrue("Length: " + sql2.length(), sql2.length() < 200000);
- SQL2Parser p = new SQL2Parser(null, nodeTypes, new QueryEngineSettings());
- Query q = p.parse(sql2, false);
+ Query q = parser.parse(sql2, false);
q.buildAlternativeQuery();
}
@@ -321,8 +316,7 @@ public class XPathTest {
sql2 = formatSQL(sql2);
expectedSql2 = formatSQL(expectedSql2);
assertEquals(expectedSql2, sql2);
- SQL2Parser p = new SQL2Parser(null, nodeTypes, new QueryEngineSettings());
- p.parse(sql2);
+ parser.parse(sql2);
}
static String formatSQL(String sql) {
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/stats/QueryStatsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/stats/QueryStatsTest.java?rev=1804821&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/stats/QueryStatsTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/stats/QueryStatsTest.java Fri Aug 11 16:45:35 2017
@@ -0,0 +1,59 @@
+/*
+ * 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.query.stats;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.jackrabbit.oak.spi.query.QueryEngineSettings;
+import org.junit.Test;
+
+public class QueryStatsTest {
+
+ @Test
+ public void testEviction() throws InterruptedException {
+ QueryStatsMBeanImpl bean = new QueryStatsMBeanImpl(new QueryEngineSettings());
+ for (int i = 0; i < 10010; i++) {
+ bean.getQueryExecution("old" + i, "");
+ if (i % 100 == 0) {
+ Thread.sleep(1);
+ }
+ }
+ assertEquals(1, bean.getEvictionCount());
+ // remain around 5000
+
+ Thread.sleep(5);
+ for (int i = 0; i < 10; i++) {
+ bean.getQueryExecution("slow" + i, "").execute(10000);
+ }
+ Thread.sleep(5);
+
+ assertEquals(1, bean.getEvictionCount());
+ for (int i = 0; i < 10010; i++) {
+ bean.getQueryExecution("new" + i, "");
+ if (i % 100 == 0) {
+ Thread.sleep(1);
+ }
+ }
+ assertEquals(3, bean.getEvictionCount());
+ String json = bean.asJson();
+ for (int i = 0; i < 10; i++) {
+ assertTrue(json.indexOf("slow" + i) >= 0);
+ }
+ assertTrue(json.indexOf("old") < 0);
+ }
+}