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/10/27 13:28:48 UTC
svn commit: r1813533 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats:
QueryRecorder.java QueryStatsData.java
Author: thomasm
Date: Fri Oct 27 13:28:48 2017
New Revision: 1813533
URL: http://svn.apache.org/viewvc?rev=1813533&view=rev
Log:
OAK-6807 Query Recorder
Added:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryRecorder.java
Modified:
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/QueryRecorder.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryRecorder.java?rev=1813533&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryRecorder.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryRecorder.java Fri Oct 27 13:28:48 2017
@@ -0,0 +1,137 @@
+/*
+ * 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.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.util.HashMap;
+import java.util.Map.Entry;
+import java.util.TreeSet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class QueryRecorder {
+
+ private static final Logger LOG = LoggerFactory.getLogger(QueryRecorder.class);
+ private static final HashMap<String, Integer> RECORD_QUERIES_MAP = new HashMap<String, Integer>();
+ private final static int QUERIES_MAX = Integer.getInteger("oak.query.record", 5000);
+
+ public static void main(String... args) throws IOException {
+ // command line version: read from a file
+ LineNumberReader reader = new LineNumberReader(
+ new BufferedReader(new FileReader(args[0])));
+ TreeSet<String> sorted = new TreeSet<String>();
+ int lineCount = 0;
+ while(true) {
+ String line = reader.readLine();
+ if(line == null) {
+ break;
+ }
+ sorted.add(simplify(line));
+ lineCount++;
+ }
+ reader.close();
+ for(String s : sorted) {
+ System.out.println(s);
+ }
+ System.out.println("sorted: " + sorted.size() + " original: " + lineCount);
+ }
+
+ public static void record(String query, boolean internal) {
+ if (internal) {
+ return;
+ }
+ if (!LOG.isDebugEnabled()) {
+ return;
+ }
+ query = query.replace('\n', ' ');
+ query = query.replace('\t', ' ');
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("query:\t{}", query);
+ }
+ try {
+ query = simplify(query);
+ } catch (Exception e) {
+ LOG.trace("failed to simplify {}", query, e);
+ }
+ record(query);
+ }
+
+ public static String simplify(String query) {
+ query = query.replaceAll("'[^']*'", "'x'");
+ query = query.replaceAll("ISDESCENDANTNODE\\(\\[/[^]]*\\]\\)", "ISDESCENDANTNODE('x')");
+ int pathIndex = query.indexOf("/jcr:root/");
+ if (pathIndex >= 0) {
+ int start = pathIndex + "/jcr:root/".length();
+ int end = getFirstOccurance(query, start,
+ " ", "/element(", "/text(", "/*", "/(", "/jcr:deref(");
+ String path = query.substring(start, end);
+ int first = path.indexOf('/');
+ if (first > 0) {
+ first = path.indexOf('/', first + 1);
+ if (first > 0) {
+ path = path.substring(0, first + 1) + "...";
+ }
+ }
+ String newQuery = query.substring(0, pathIndex) + "/jcr:root/" + path + query.substring(end, query.length());
+ query = newQuery;
+ }
+ return query;
+ }
+
+ static int getFirstOccurance(String text, int start, String... strings) {
+ int first = text.length();
+ for(String s : strings) {
+ int index = text.indexOf(s, start + 1);
+ if (index > 0 && index < first) {
+ first = index;
+ }
+ }
+ return first;
+ }
+
+ private static void record(String query) {
+ HashMap<String, Integer> map = RECORD_QUERIES_MAP;
+ if (map.size() > QUERIES_MAX) {
+ HashMap<String, Integer> old;
+ synchronized (map) {
+ old = new HashMap<>(map);
+ map.clear();
+ }
+ for(Entry<String, Integer> e : old.entrySet()) {
+ log(e.getKey(), e.getValue());
+ }
+ }
+ Integer count;
+ synchronized (map) {
+ count = map.get(query);
+ count = count == null ? 1 : count + 1;
+ map.put(query, count);
+ }
+ if (count == 1 || count % 100 == 0) {
+ log(query, count);
+ }
+ }
+
+ private static void log(String query, int count) {
+ LOG.debug("count:\t{}\tquery:\t{}", count, query);
+ }
+
+}
Modified: 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=1813533&r1=1813532&r2=1813533&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsData.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/query/stats/QueryStatsData.java Fri Oct 27 13:28:48 2017
@@ -140,6 +140,7 @@ public class QueryStatsData {
long time;
public void execute(long nanos) {
+ QueryRecorder.record(query, internal);
executeCount++;
lastExecutedMillis = System.currentTimeMillis();
time += nanos;