Author: chetanm
Date: Wed Oct 4 13:52:58 2017
New Revision: 1811074
URL: http://svn.apache.org/viewvc?rev=1811074&view=rev
Log:
OAK-6535 - Synchronous Lucene Property Indexes
MBean operation to expose index info for hybrid indexes
Added:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexInfo.java
(with props)
Modified:
jackrabbit/oak/trunk/oak-lucene/pom.xml
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexMBean.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexMBeanImpl.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexUtil.java
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleaner.java
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleanerTest.java
Modified: jackrabbit/oak/trunk/oak-lucene/pom.xml
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/pom.xml?rev=1811074&r1=1811073&r2=1811074&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-lucene/pom.xml Wed Oct 4 13:52:58 2017
@@ -396,5 +396,11 @@
<version>1.3</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <version>2.8.0</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexMBean.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexMBean.java?rev=1811074&r1=1811073&r2=1811074&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexMBean.java
(original)
+++
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexMBean.java
Wed Oct 4 13:52:58 2017
@@ -111,4 +111,8 @@ public interface LuceneIndexMBean {
@Description("Performs any possible cleanup of the hybrid property
indexes")
String performPropertyIndexCleanup() throws CommitFailedException;
+
+ @Description("Fetches hybrid property index info as json for index at
given path")
+ String getHybridIndexInfo(@Name("indexPath") String indexPath);
+
}
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexMBeanImpl.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexMBeanImpl.java?rev=1811074&r1=1811073&r2=1811074&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexMBeanImpl.java
(original)
+++
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexMBeanImpl.java
Wed Oct 4 13:52:58 2017
@@ -51,6 +51,7 @@ import org.apache.jackrabbit.oak.json.Js
import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
import org.apache.jackrabbit.oak.plugins.index.IndexPathService;
import
org.apache.jackrabbit.oak.plugins.index.lucene.BadIndexTracker.BadIndexInfo;
+import
org.apache.jackrabbit.oak.plugins.index.lucene.property.HybridPropertyIndexInfo;
import
org.apache.jackrabbit.oak.plugins.index.lucene.property.PropertyIndexCleaner;
import
org.apache.jackrabbit.oak.plugins.index.lucene.util.PathStoredFieldVisitor;
import
org.apache.jackrabbit.oak.plugins.index.lucene.directory.IndexConsistencyChecker;
@@ -346,6 +347,12 @@ public class LuceneIndexMBeanImpl extend
return result;
}
+ @Override
+ public String getHybridIndexInfo(String indexPath) {
+ NodeState idx = NodeStateUtils.getNode(nodeStore.getRoot(), indexPath);
+ return new HybridPropertyIndexInfo(idx).getInfoAsJson();
+ }
+
private Result getConsistencyCheckResult(String indexPath, boolean
fullCheck) throws IOException {
NodeState root = nodeStore.getRoot();
Level level = fullCheck ? Level.FULL : Level.BLOBS_ONLY;
Added:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexInfo.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexInfo.java?rev=1811074&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexInfo.java
(added)
+++
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexInfo.java
Wed Oct 4 13:52:58 2017
@@ -0,0 +1,108 @@
+/*
+ * 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.plugins.index.lucene.property;
+
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.TreeTraverser;
+import org.apache.jackrabbit.oak.commons.json.JsopBuilder;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+
+import static
org.apache.jackrabbit.oak.plugins.index.lucene.property.HybridPropertyIndexUtil.PROPERTY_INDEX;
+import static
org.apache.jackrabbit.oak.plugins.index.lucene.property.HybridPropertyIndexUtil.PROP_HEAD_BUCKET;
+import static
org.apache.jackrabbit.oak.plugins.index.lucene.property.HybridPropertyIndexUtil.PROP_PREVIOUS_BUCKET;
+import static
org.apache.jackrabbit.oak.plugins.index.lucene.property.HybridPropertyIndexUtil.simplePropertyIndex;
+import static
org.apache.jackrabbit.oak.plugins.index.lucene.property.HybridPropertyIndexUtil.uniquePropertyIndex;
+
+public class HybridPropertyIndexInfo {
+ private final JsopBuilder json = new JsopBuilder();
+ private final NodeState idx;
+
+ public HybridPropertyIndexInfo(NodeState idx) {
+ this.idx = idx;
+ }
+
+ public String getInfoAsJson(){
+ json.resetWriter();
+ json.object();
+ NodeState propertyIndexNode = idx.getChildNode(PROPERTY_INDEX);
+ for (ChildNodeEntry cne : propertyIndexNode.getChildNodeEntries()) {
+ NodeState propIdxState = cne.getNodeState();
+ String propName = cne.getName();
+ json.key(propName).object();
+ if (simplePropertyIndex(propIdxState)) {
+ collectBucketData(propIdxState);
+ } else if (uniquePropertyIndex(propIdxState)) {
+
json.key("entryCount").value(propIdxState.getChildNodeCount(Integer.MAX_VALUE));
+ json.key("unique").value(true);
+ }
+ json.endObject();
+ }
+ json.endObject();
+ return JsopBuilder.prettyPrint(json.toString());
+ }
+
+ private void collectBucketData(NodeState propIdxState) {
+ String head = propIdxState.getString(PROP_HEAD_BUCKET);
+ String previous = propIdxState.getString(PROP_PREVIOUS_BUCKET);
+
+ for (ChildNodeEntry cne : propIdxState.getChildNodeEntries()) {
+ String bucketName = cne.getName();
+ NodeState bucket = cne.getNodeState();
+ json.key(bucketName).object();
+
+ json.key("type");
+ if (Objects.equals(head, bucketName)) {
+ json.value("head");
+ } else if (Objects.equals(previous, bucketName)) {
+ json.value("previous");
+ } else {
+ json.value("garbage");
+ }
+
+
json.key("keyCount").value(bucket.getChildNodeCount(Integer.MAX_VALUE));
+ collectCounts(bucket);
+
+ json.endObject();
+ }
+ }
+
+ private void collectCounts(NodeState bucket) {
+ TreeTraverser<NodeState> t = new TreeTraverser<NodeState>() {
+ @Override
+ public Iterable<NodeState> children(NodeState root) {
+ return Iterables.transform(root.getChildNodeEntries(),
ChildNodeEntry::getNodeState);
+ }
+ };
+ AtomicInteger matches = new AtomicInteger();
+ int totalCount = t.preOrderTraversal(bucket)
+ .transform((st) -> {
+ if (st.getBoolean("match")) {
+ matches.incrementAndGet();
+ }
+ return st;
+ }).size();
+ json.key("entryCount").value(matches.get());
+ json.key("totalCount").value(totalCount);
+ }
+}
Propchange:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexUtil.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexUtil.java?rev=1811074&r1=1811073&r2=1811074&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexUtil.java
(original)
+++
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/HybridPropertyIndexUtil.java
Wed Oct 4 13:52:58 2017
@@ -20,6 +20,7 @@
package org.apache.jackrabbit.oak.plugins.index.lucene.property;
import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
class HybridPropertyIndexUtil {
/**
@@ -59,4 +60,12 @@ class HybridPropertyIndexUtil {
static String getNodeName(String propertyRelativePath) {
return propertyRelativePath.replace('/', '_');
}
+
+ static boolean simplePropertyIndex(NodeState propIdxState) {
+ return
STORAGE_TYPE_CONTENT_MIRROR.equals(propIdxState.getString(PROP_STORAGE_TYPE));
+ }
+
+ static boolean uniquePropertyIndex(NodeState propIdxState) {
+ return
STORAGE_TYPE_UNIQUE.equals(propIdxState.getString(PROP_STORAGE_TYPE));
+ }
}
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleaner.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleaner.java?rev=1811074&r1=1811073&r2=1811074&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleaner.java
(original)
+++
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleaner.java
Wed Oct 4 13:52:58 2017
@@ -50,9 +50,8 @@ import static com.google.common.base.Pre
import static
org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.LuceneIndexConstants.TYPE_LUCENE;
import static
org.apache.jackrabbit.oak.plugins.index.lucene.property.HybridPropertyIndexUtil.PROPERTY_INDEX;
-import static
org.apache.jackrabbit.oak.plugins.index.lucene.property.HybridPropertyIndexUtil.PROP_STORAGE_TYPE;
-import static
org.apache.jackrabbit.oak.plugins.index.lucene.property.HybridPropertyIndexUtil.STORAGE_TYPE_CONTENT_MIRROR;
-import static
org.apache.jackrabbit.oak.plugins.index.lucene.property.HybridPropertyIndexUtil.STORAGE_TYPE_UNIQUE;
+import static
org.apache.jackrabbit.oak.plugins.index.lucene.property.HybridPropertyIndexUtil.simplePropertyIndex;
+import static
org.apache.jackrabbit.oak.plugins.index.lucene.property.HybridPropertyIndexUtil.uniquePropertyIndex;
import static org.apache.jackrabbit.oak.spi.state.NodeStateUtils.getNode;
public class PropertyIndexCleaner implements Runnable{
@@ -246,14 +245,6 @@ public class PropertyIndexCleaner implem
return nb;
}
- private static boolean simplePropertyIndex(NodeState propIdxState) {
- return
STORAGE_TYPE_CONTENT_MIRROR.equals(propIdxState.getString(PROP_STORAGE_TYPE));
- }
-
- private static boolean uniquePropertyIndex(NodeState propIdxState) {
- return
STORAGE_TYPE_UNIQUE.equals(propIdxState.getString(PROP_STORAGE_TYPE));
- }
-
private static final class IndexInfo {
final List<String> oldBucketPaths = new ArrayList<>();
Modified:
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleanerTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleanerTest.java?rev=1811074&r1=1811073&r2=1811074&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleanerTest.java
(original)
+++
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/property/PropertyIndexCleanerTest.java
Wed Oct 4 13:52:58 2017
@@ -27,6 +27,8 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.CheckForNull;
import com.google.common.collect.ImmutableList;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
import org.apache.jackrabbit.oak.InitialContent;
import org.apache.jackrabbit.oak.api.CommitFailedException;
import org.apache.jackrabbit.oak.plugins.index.AsyncIndexInfo;
@@ -43,8 +45,10 @@ import org.apache.jackrabbit.oak.spi.com
import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
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.spi.state.NodeStore;
import org.apache.jackrabbit.oak.stats.Clock;
+import org.json.simple.parser.ParseException;
import org.junit.Before;
import org.junit.Test;
@@ -58,9 +62,7 @@ import static org.apache.jackrabbit.oak.
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.empty;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class PropertyIndexCleanerTest {
@@ -175,6 +177,12 @@ public class PropertyIndexCleanerTest {
//------------------------ Run 1
asyncService.addInfo("async", 1200);
assertCleanUpPerformed(cleaner.performCleanup(false), true);
+ assertJsonInfo(indexPath, "{\n" +
+ " \"foo\": {\n" +
+ " \"entryCount\": 1,\n" +
+ " \"unique\": true\n" +
+ " }\n" +
+ "}");
// /a would be purged, /b would be retained as its created time 1150
is not older than 100 wrt
// indexer time of 1200
@@ -221,6 +229,22 @@ public class PropertyIndexCleanerTest {
//------------------------ Run 1
asyncService.addInfo("async", 1000);
assertCleanUpPerformed(cleaner.performCleanup(false), true);
+ assertJsonInfo(indexPath, "{\n" +
+ " \"foo\": {\n" +
+ " \"1\": {\n" +
+ " \"type\": \"previous\",\n" +
+ " \"keyCount\": 1,\n" +
+ " \"entryCount\": 1,\n" +
+ " \"totalCount\": 3\n" +
+ " },\n" +
+ " \"2\": {\n" +
+ " \"type\": \"head\",\n" +
+ " \"keyCount\": 0,\n" +
+ " \"entryCount\": 0,\n" +
+ " \"totalCount\": 1\n" +
+ " }\n" +
+ " }\n" +
+ "}");
//Second run should not run
assertCleanUpPerformed(cleaner.performCleanup(false), false);
@@ -230,6 +254,17 @@ public class PropertyIndexCleanerTest {
assertEquals(expected, stats.cleanupPerformed);
}
+ private void assertJsonInfo(String indexPath, String expectedJson) throws
ParseException {
+ NodeState idx = NodeStateUtils.getNode(nodeStore.getRoot(), indexPath);
+ String json = new HybridPropertyIndexInfo(idx).getInfoAsJson();
+ JsonObject j1 = (JsonObject) new JsonParser().parse(json);
+ JsonObject j2 = (JsonObject) new JsonParser().parse(expectedJson);
+
+ if (!j1.equals(j2)){
+ assertEquals(j1, j2);
+ }
+ }
+
private void addIndex(String indexPath, IndexDefinitionBuilder defnb)
throws CommitFailedException {
NodeBuilder nb = nodeStore.getRoot().builder();
child(nb, getParentPath(indexPath)).setChildNode(getName(indexPath),
defnb.build());