Author: catholicon
Date: Wed Apr 3 15:23:42 2019
New Revision: 1856883
URL: http://svn.apache.org/viewvc?rev=1856883&view=rev
Log:
OAK-8138: In cases where search hit count is less than sample size defined for
statistical mode for facets, secure mode should be used so that the counts are
accurate for non-admin users.
Applying patch contributed by Nitin Gupta
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/StatisticalSortedSetDocValuesFacetCounts.java
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/SecureFacetTest.java
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/StatisticalSortedSetDocValuesFacetCounts.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/StatisticalSortedSetDocValuesFacetCounts.java?rev=1856883&r1=1856882&r2=1856883&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/StatisticalSortedSetDocValuesFacetCounts.java
(original)
+++
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/StatisticalSortedSetDocValuesFacetCounts.java
Wed Apr 3 15:23:42 2019
@@ -52,12 +52,14 @@ class StatisticalSortedSetDocValuesFacet
private final Filter filter;
private final IndexReader reader;
private final SecureFacetConfiguration secureFacetConfiguration;
+ private final DefaultSortedSetDocValuesReaderState state;
private FacetResult facetResult = null;
StatisticalSortedSetDocValuesFacetCounts(DefaultSortedSetDocValuesReaderState
state,
FacetsCollector
facetsCollector, Filter filter,
SecureFacetConfiguration
secureFacetConfiguration) throws IOException {
super(state, facetsCollector);
+ this.state = state;
this.reader = state.origReader;
this.facetsCollector = facetsCollector;
this.filter = filter;
@@ -89,6 +91,13 @@ class StatisticalSortedSetDocValuesFacet
hitCount += matchingDocs.totalHits;
}
int sampleSize =
secureFacetConfiguration.getStatisticalFacetSampleSize();
+ // In case the hit count is less than sample size(A very small
reposiotry perhaps)
+ // Delegate getting FacetResults to
SecureSortedSetDocValuesFacetCounts to get the exact count
+ // instead of statistical count. <OAK-8138>
+ if (hitCount < sampleSize) {
+ return new SecureSortedSetDocValuesFacetCounts(state,
facetsCollector, filter).getTopChildren(topN, dim, path);
+ }
+
long randomSeed = secureFacetConfiguration.getRandomSeed();
LOG.debug("Sampling facet dim {}; hitCount: {}, sampleSize: {}, seed:
{}", dim, hitCount, sampleSize, randomSeed);
Modified:
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/SecureFacetTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/SecureFacetTest.java?rev=1856883&r1=1856882&r2=1856883&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/SecureFacetTest.java
(original)
+++
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/SecureFacetTest.java
Wed Apr 3 15:23:42 2019
@@ -136,7 +136,7 @@ public class SecureFacetTest {
Node par = allow(getOrCreateByPath("/parent", "oak:Unstructured",
session));
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < NUM_LABELS; i++) {
Node subPar = par.addNode("par" + i);
for (int j = 0; j < NUM_LEAF_NODES; j++) {
Node child = subPar.addNode("c" + j);
@@ -172,6 +172,51 @@ public class SecureFacetTest {
assertNotEquals("Acl-ed and actual counts mustn't be same",
actualLabelCount, actualAclLabelCount);
}
+ private void createSmallDataset() throws RepositoryException{
+ Random rGen = new Random(42);
+ int[] labelCount = new int[NUM_LABELS];
+ int[] aclLabelCount = new int[NUM_LABELS];
+ int[] aclPar1LabelCount = new int[NUM_LABELS];
+
+ Node par = allow(getOrCreateByPath("/parent", "oak:Unstructured",
session));
+
+ for (int i = 0; i < NUM_LABELS; i++) {
+ Node subPar = par.addNode("par" + i);
+ for (int j = 0; j < NUM_LEAF_NODES/(2 * NUM_LABELS); j++) {
+ Node child = subPar.addNode("c" + j);
+ child.setProperty("cons", "val");
+
+ // Add a random label out of "l0", "l1", "l2", "l3"
+ int labelNum = rGen.nextInt(NUM_LABELS);
+ child.setProperty("foo", "l" + labelNum);
+
+ labelCount[labelNum]++;
+ if (i != 0) {
+ aclLabelCount[labelNum]++;
+ }
+ if (i == 1) {
+ aclPar1LabelCount[labelNum]++;
+ }
+ }
+
+ // deny access for one sub-parent
+ if (i == 0) {
+ deny(subPar);
+ }
+ }
+
+ session.save();
+
+ for (int i = 0; i < labelCount.length; i++) {
+ actualLabelCount.put("l" + i, labelCount[i]);
+ actualAclLabelCount.put("l" + i, aclLabelCount[i]);
+ actualAclPar1LabelCount.put("l" + i, aclPar1LabelCount[i]);
+ }
+
+ assertNotEquals("Acl-ed and actual counts mustn't be same",
actualLabelCount, actualAclLabelCount);
+
+ }
+
@Test
public void secureFacets() throws Exception {
createLargeDataset();
@@ -225,6 +270,23 @@ public class SecureFacetTest {
}
@Test
+ public void statisticalFacetsWithHitCountLessThanSampleSize() throws
Exception {
+ Node facetConfig = getOrCreateByPath(indexNode.getPath() + "/" +
FACETS, "nt:unstructured", session);
+ facetConfig.setProperty(PROP_SECURE_FACETS,
PROP_SECURE_FACETS_VALUE_STATISTICAL);
+ indexNode.setProperty(PROP_REFRESH_DEFN, true);
+ session.save();
+
+ createSmallDataset();
+
+ Map<String, Integer> facets = getFacets();
+ assertEquals("Unexpected number of facets",
actualAclLabelCount.size(), facets.size());
+
+ // Since the hit count is less than sample size -> flow should have
switched to secure facet count instead of statistical
+ // and thus the count should be exactly equal
+ assertEquals(actualAclLabelCount, facets);
+ }
+
+ @Test
public void statisticalFacets_withHitCountSameAsSampleSize() throws
Exception {
Node facetConfig = getOrCreateByPath(indexNode.getPath() + "/" +
FACETS, "nt:unstructured", session);
facetConfig.setProperty(PROP_SECURE_FACETS,
PROP_SECURE_FACETS_VALUE_STATISTICAL);