You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by as...@apache.org on 2015/07/21 13:15:26 UTC

svn commit: r1692087 - in /sling/trunk/bundles/resourceresolver/src: main/java/org/apache/sling/resourceresolver/impl/ main/java/org/apache/sling/resourceresolver/impl/mapping/ test/java/org/apache/sling/resourceresolver/impl/mapping/

Author: asanso
Date: Tue Jul 21 11:15:26 2015
New Revision: 1692087

URL: http://svn.apache.org/r1692087
Log:
SLING-4891 - Improve MapEntries to cache searched vanity paths 

Modified:
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java
    sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
    sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java?rev=1692087&r1=1692086&r2=1692087&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/CommonResourceResolverFactoryImpl.java Tue Jul 21 11:15:26 2015
@@ -357,6 +357,11 @@ public class CommonResourceResolverFacto
     public long getMaxCachedVanityPathEntries() {
         return this.activator.getMaxCachedVanityPathEntries();
     }
+    
+    @Override
+    public boolean isMaxCachedVanityPathEntriesStartup() {
+        return this.activator.isMaxCachedVanityPathEntriesStartup();
+    }
 
     @Override
     public int getVanityBloomFilterMaxBytes() {

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java?rev=1692087&r1=1692086&r2=1692087&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverFactoryActivator.java Tue Jul 21 11:15:26 2015
@@ -191,6 +191,13 @@ public class ResourceResolverFactoryActi
               description = "The maximum number of cached vanity path entries. " +
                             "Default is -1 (no limit)")
     private static final String PROP_MAX_CACHED_VANITY_PATHS = "resource.resolver.vanitypath.maxEntries";
+    
+    private static final boolean DEFAULT_MAX_CACHED_VANITY_PATHS_STARTUP = true;
+    @Property(boolValue = DEFAULT_MAX_CACHED_VANITY_PATHS_STARTUP,
+              label = "Limit the maximum number of cached vanity path entries only at startup",
+              description = "Limit the maximum number of cached vanity path entries only at startup" +
+                            "Default is true")
+    private static final String PROP_MAX_CACHED_VANITY_PATHS_STARTUP = "resource.resolver.vanitypath.maxEntries.startup";
 
     private static final int DEFAULT_VANITY_BLOOM_FILTER_MAX_BYTES = 1024000;
     @Property(longValue = DEFAULT_VANITY_BLOOM_FILTER_MAX_BYTES,
@@ -284,6 +291,9 @@ public class ResourceResolverFactoryActi
 
     /** max number of cache vanity path entries */
     private long maxCachedVanityPathEntries = DEFAULT_MAX_CACHED_VANITY_PATHS;
+    
+    /** limit max number of cache vanity path entries only at startup*/
+    private boolean maxCachedVanityPathEntriesStartup = DEFAULT_MAX_CACHED_VANITY_PATHS_STARTUP;
 
     /** Maximum number of vanity bloom filter bytes */
     private int vanityBloomFilterMaxBytes = DEFAULT_VANITY_BLOOM_FILTER_MAX_BYTES;
@@ -394,6 +404,10 @@ public class ResourceResolverFactoryActi
     public long getMaxCachedVanityPathEntries() {
         return this.maxCachedVanityPathEntries;
     }
+    
+    public boolean isMaxCachedVanityPathEntriesStartup() {
+        return this.maxCachedVanityPathEntriesStartup;
+    }
 
     public int getVanityBloomFilterMaxBytes() {
         return this.vanityBloomFilterMaxBytes;
@@ -503,6 +517,7 @@ public class ResourceResolverFactoryActi
 
         this.enableOptimizeAliasResolution = PropertiesUtil.toBoolean(properties.get(PROP_ENABLE_OPTIMIZE_ALIAS_RESOLUTION), DEFAULT_ENABLE_OPTIMIZE_ALIAS_RESOLUTION);
         this.maxCachedVanityPathEntries = PropertiesUtil.toLong(properties.get(PROP_MAX_CACHED_VANITY_PATHS), DEFAULT_MAX_CACHED_VANITY_PATHS);
+        this.maxCachedVanityPathEntriesStartup = PropertiesUtil.toBoolean(properties.get(PROP_MAX_CACHED_VANITY_PATHS_STARTUP), DEFAULT_MAX_CACHED_VANITY_PATHS_STARTUP);
         this.vanityBloomFilterMaxBytes = PropertiesUtil.toInteger(properties.get(PROP_VANITY_BLOOM_FILTER_MAX_BYTES), DEFAULT_VANITY_BLOOM_FILTER_MAX_BYTES);
 
         this.vanityPathPrecedence = PropertiesUtil.toBoolean(properties.get(PROP_VANITY_PATH_PRECEDENCE), DEFAULT_VANITY_PATH_PRECEDENCE);

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java?rev=1692087&r1=1692086&r2=1692087&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapConfigurationProvider.java Tue Jul 21 11:15:26 2015
@@ -42,6 +42,8 @@ public interface MapConfigurationProvide
     
     long getMaxCachedVanityPathEntries();
     
+    boolean isMaxCachedVanityPathEntriesStartup();
+    
     int getVanityBloomFilterMaxBytes();
 
     boolean isOptimizeAliasResolutionEnabled();

Modified: sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java?rev=1692087&r1=1692086&r2=1692087&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java (original)
+++ sling/trunk/bundles/resourceresolver/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java Tue Jul 21 11:15:26 2015
@@ -124,6 +124,8 @@ public class MapEntries implements Event
     
     private final long maxCachedVanityPathEntries;
     
+    private final boolean maxCachedVanityPathEntriesStartup;
+    
     private final int vanityBloomFilterMaxBytes;
 
     private final boolean enableOptimizeAliasResolution;
@@ -156,6 +158,7 @@ public class MapEntries implements Event
         this.eventAdmin = null;
         this.enabledVanityPaths = true;
         this.maxCachedVanityPathEntries = -1;
+        this.maxCachedVanityPathEntriesStartup = true;
         this.vanityBloomFilterMaxBytes = 0;
         this.enableOptimizeAliasResolution = true;
         this.vanityPathConfig = null;
@@ -172,6 +175,7 @@ public class MapEntries implements Event
         this.mapRoot = factory.getMapRoot();
         this.enabledVanityPaths = factory.isVanityPathEnabled();
         this.maxCachedVanityPathEntries = factory.getMaxCachedVanityPathEntries();
+        this.maxCachedVanityPathEntriesStartup = factory.isMaxCachedVanityPathEntriesStartup();
         this.vanityBloomFilterMaxBytes = factory.getVanityBloomFilterMaxBytes();
         this.vanityPathConfig = factory.getVanityPathConfig();
         this.enableOptimizeAliasResolution = factory.isOptimizeAliasResolutionEnabled();
@@ -853,8 +857,7 @@ public class MapEntries implements Event
      */
     private Map<String, List<MapEntry>> getVanityPaths(String vanityPath) {
 
-        final Map<String, List<MapEntry>> entryMap = new HashMap<String, List<MapEntry>>();  
-        final Map <String, List<String>> targetPaths = new HashMap <String, List<String>>();
+        Map<String, List<MapEntry>> entryMap = new HashMap<String, List<MapEntry>>();    
         
         // sling:VanityPath (uppercase V) is the mixin name
         // sling:vanityPath (lowercase) is the property name        
@@ -868,7 +871,14 @@ public class MapEntries implements Event
             final Iterator<Resource> i = queryResolver.findResources(queryString, "sql");
             while (i.hasNext()) {
                 final Resource resource = i.next();
-                loadVanityPath(resource, entryMap, targetPaths, true, false);
+                if (maxCachedVanityPathEntriesStartup) {                    
+                    loadVanityPath(resource, resolveMapsMap, vanityTargets, true, false);
+                    vanityCounter.incrementAndGet();
+                    entryMap = resolveMapsMap;
+                } else {                    
+                    final Map <String, List<String>> targetPaths = new HashMap <String, List<String>>();
+                    loadVanityPath(resource, entryMap, targetPaths, true, false);
+                }               
             }
         } catch (LoginException e) {
             log.error("Exception while obtaining queryResolver", e);

Modified: sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java?rev=1692087&r1=1692086&r2=1692087&view=diff
==============================================================================
--- sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java (original)
+++ sling/trunk/bundles/resourceresolver/src/test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java Tue Jul 21 11:15:26 2015
@@ -40,7 +40,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
+import java.util.concurrent.atomic.AtomicLong;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceUtil;
@@ -110,6 +110,10 @@ public class MapEntriesTest {
         field1.setAccessible(true);  
         field1.set(mapEntries, -1);
         
+        Field field2 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntriesStartup");
+        field2.setAccessible(true);  
+        field2.set(mapEntries, true);
+        
     }
     
     @After
@@ -1368,4 +1372,104 @@ public class MapEntriesTest {
         Boolean resfreshed = (Boolean ) method.invoke(mapEntries, "/node", true);
         assertTrue(resfreshed.booleanValue());
     }
+    
+    @Test
+    //SLING-4891
+    public void test_getVanityPaths_1() throws Exception {
+        
+        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
+        field1.setAccessible(true);  
+        field1.set(mapEntries, 10);
+        
+        Method method = MapEntries.class.getDeclaredMethod("getVanityPaths", String.class);
+        method.setAccessible(true);
+        method.invoke(mapEntries, "/notExisting");   
+        
+        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
+        vanityCounter.setAccessible(true);  
+        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
+        assertEquals(0, counter.longValue());        
+    }
+    
+    @Test
+    //SLING-4891
+    public void test_getVanityPaths_2() throws Exception { 
+        
+        Resource parent = mock(Resource.class);
+        when(parent.getPath()).thenReturn("/parent");
+        final Resource result = mock(Resource.class);
+ 
+        when(result.getParent()).thenReturn(parent);
+        when(result.getPath()).thenReturn("/parent/child");
+        when(result.getName()).thenReturn("child");
+        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "vanity"));
+        
+        
+        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
+
+            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
+                if (invocation.getArguments()[0].toString().contains("sling:vanityPath")) {
+                    return Collections.singleton(result).iterator();
+                } else {
+                    return Collections.<Resource> emptySet().iterator();
+                }
+            }
+        });
+        
+        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
+        field1.setAccessible(true);  
+        field1.set(mapEntries, 10);
+        
+        Method method = MapEntries.class.getDeclaredMethod("getVanityPaths", String.class);
+        method.setAccessible(true);
+        method.invoke(mapEntries, "/existing");   
+        
+        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
+        vanityCounter.setAccessible(true);  
+        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
+        assertEquals(1, counter.longValue());        
+    }
+    
+    @Test
+    //SLING-4891
+    public void test_getVanityPaths_3() throws Exception { 
+        
+        Resource parent = mock(Resource.class);
+        when(parent.getPath()).thenReturn("/parent");
+        final Resource result = mock(Resource.class);
+ 
+        when(result.getParent()).thenReturn(parent);
+        when(result.getPath()).thenReturn("/parent/child");
+        when(result.getName()).thenReturn("child");
+        when(result.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "vanity"));
+        
+        
+        when(resourceResolver.findResources(anyString(), eq("sql"))).thenAnswer(new Answer<Iterator<Resource>>() {
+
+            public Iterator<Resource> answer(InvocationOnMock invocation) throws Throwable {
+                if (invocation.getArguments()[0].toString().contains("sling:vanityPath")) {
+                    return Collections.singleton(result).iterator();
+                } else {
+                    return Collections.<Resource> emptySet().iterator();
+                }
+            }
+        });
+        
+        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
+        field1.setAccessible(true);  
+        field1.set(mapEntries, 10);
+        
+        Field field2 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntriesStartup");
+        field2.setAccessible(true);  
+        field2.set(mapEntries, false);
+        
+        Method method = MapEntries.class.getDeclaredMethod("getVanityPaths", String.class);
+        method.setAccessible(true);
+        method.invoke(mapEntries, "/existing");   
+        
+        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
+        vanityCounter.setAccessible(true);  
+        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
+        assertEquals(0, counter.longValue());        
+    }
 }