Skip to content

Commit

Permalink
Also interpret cost JSON object in case it is returned by oak search
Browse files Browse the repository at this point in the history
engine #730
  • Loading branch information
ghenzler committed Jun 13, 2024
1 parent 86e6ace commit 1e12fbd
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

Expand Down Expand Up @@ -143,14 +145,9 @@ static boolean hasQueryIndexForACLs(final Session session) throws RepositoryExce
Row row = queryResult.getRows().nextRow();
// inspired by https://github.com/apache/jackrabbit-oak/blob/cc8adb42d89bc4625138a62ab074e7794a4d39ab/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/QueryTest.java#L1092
String plan = row.getValue("plan").getString();
String costJson = plan.substring(plan.lastIndexOf('{'));

// use jackson for JSON parsing
ObjectMapper mapper = new ObjectMapper();
String costJsonStr = plan.substring(plan.lastIndexOf('{'));

// read the json strings and convert it into JsonNode
JsonNode node = mapper.readTree(costJson);
double cost = node.get("s").asDouble(Double.MAX_VALUE);
double cost = getCostFromJsonStr(costJsonStr);
// look at https://jackrabbit.apache.org/oak/docs/query/query-engine.html#cost-calculation for the threshold
// https://github.com/apache/jackrabbit-oak/blob/cc8adb42d89bc4625138a62ab074e7794a4d39ab/oak-core/src/main/java/org/apache/jackrabbit/oak/query/index/TraversingIndex.java#L75

Expand All @@ -160,6 +157,18 @@ static boolean hasQueryIndexForACLs(final Session session) throws RepositoryExce
return cost <= COST_THRESHOLD_FOR_QUERY_INDEX;
}

static double getCostFromJsonStr(String jsonStr) throws JsonProcessingException, IOException {
// use jackson for JSON parsing
ObjectMapper mapper = new ObjectMapper().configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);

// read the json strings and convert it into JsonNode
JsonNode node = mapper.readTree(jsonStr);

JsonNode sNode = node.get("s");
double cost = sNode.isContainerNode() ? sNode.get("perExecution").asDouble(Double.MAX_VALUE) : sNode.asDouble(Double.MAX_VALUE);
return cost;
}

/** Get Nodes with XPATH Query. */
public static Set<String> getNodePathsFromQuery(final Session session,
final String xpathQuery) throws RepositoryException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* (C) Copyright 2023 Cognizant Netcentric.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package biz.netcentric.cq.tools.actool.helper;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.IOException;

import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.core.JsonProcessingException;

public class QueryHelperTest {

@Test
public void testGetCostFromJsonScalar() throws JsonProcessingException, IOException {

assertEquals(189540, QueryHelper.getCostFromJsonStr("{ \"s\": 189540.0 }"));
}

@Test
public void testGetCostFromJsonObject() throws JsonProcessingException, IOException {

// the keys in sub object happen to be unquoted, the impl needs to use JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES
assertEquals(1, QueryHelper.getCostFromJsonStr("{ \"s\": { perEntry: 1.0, perExecution: 1.0, count: 47814 } }"));

}

}

0 comments on commit 1e12fbd

Please sign in to comment.