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);


Reply via email to