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 16:16:19 UTC

svn commit: r1692123 - in /sling/trunk/bundles/resourceresolver/src: main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java test/java/org/apache/sling/resourceresolver/impl/mapping/MapEntriesTest.java

Author: asanso
Date: Tue Jul 21 14:16:19 2015
New Revision: 1692123

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

Modified:
    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/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=1692123&r1=1692122&r2=1692123&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 14:16:19 2015
@@ -453,10 +453,9 @@ public class MapEntries implements Event
 
     private void doAddVanity(String path) {
         Resource resource = resolver.getResource(path);
-        if (maxCachedVanityPathEntries < vanityCounter.longValue()) {
+        if (maxCachedVanityPathEntries == -1 || vanityCounter.longValue() < maxCachedVanityPathEntries) {
             // fill up the cache and the bloom filter
             loadVanityPath(resource, resolveMapsMap, vanityTargets, true, true);
-            vanityCounter.incrementAndGet();
         } else {
             // fill up the bloom filter
             loadVanityPath(resource, resolveMapsMap, vanityTargets, false, true);
@@ -491,7 +490,7 @@ public class MapEntries implements Event
         }
         vanityTargets.remove(actualContentPath);
         if (vanityCounter.longValue() > 0) {
-            vanityCounter.decrementAndGet();
+            vanityCounter.addAndGet(-2);
         }     
     }
 
@@ -871,9 +870,8 @@ public class MapEntries implements Event
             final Iterator<Resource> i = queryResolver.findResources(queryString, "sql");
             while (i.hasNext()) {
                 final Resource resource = i.next();
-                if (maxCachedVanityPathEntriesStartup) {                    
+                if (maxCachedVanityPathEntriesStartup || vanityCounter.longValue() < maxCachedVanityPathEntries) {                    
                     loadVanityPath(resource, resolveMapsMap, vanityTargets, true, false);
-                    vanityCounter.incrementAndGet();
                     entryMap = resolveMapsMap;
                 } else {                    
                     final Map <String, List<String>> targetPaths = new HashMap <String, List<String>>();
@@ -1127,11 +1125,10 @@ public class MapEntries implements Event
 
         while (i.hasNext() && (createVanityBloomFilter || maxCachedVanityPathEntries < vanityCounter.longValue())) {
             final Resource resource = i.next();
-            if (maxCachedVanityPathEntries < vanityCounter.longValue()) {
+            if (maxCachedVanityPathEntries == -1 || vanityCounter.longValue() < maxCachedVanityPathEntries) {
                 // fill up the cache and the bloom filter
                 loadVanityPath(resource, entryMap, targetPaths, true,
                         createVanityBloomFilter);
-                vanityCounter.incrementAndGet();
             } else {
                 // fill up the bloom filter
                 loadVanityPath(resource, entryMap, targetPaths, false,
@@ -1208,7 +1205,12 @@ public class MapEntries implements Event
                     }
                     if (addedEntry) {
                         // 3. keep the path to return
-                        this.updateTargetPaths(targetPaths, redirect, checkPath);  
+                        this.updateTargetPaths(targetPaths, redirect, checkPath); 
+                        //increment only if the instance variable
+                        if (entryMap == resolveMapsMap) {
+                            vanityCounter.addAndGet(2);
+                        }
+
                         if (newVanity) {
                             // update bloom filter
                             BloomFilterUtils.add(vanityBloomFilter, checkPath);

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=1692123&r1=1692122&r2=1692123&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 14:16:19 2015
@@ -385,6 +385,11 @@ public class MapEntriesTest {
         entries = mapEntries.getResolveMaps();
         assertEquals(2, entries.size());
         
+        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
+        vanityCounter.setAccessible(true);  
+        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
+        assertEquals(2, counter.longValue());        
+        
         //bad vanity
         Resource badVanityPath = mock(Resource.class, "badVanityPath");
         when(resourceResolver.getResource("/badVanityPath")).thenReturn(badVanityPath);
@@ -416,6 +421,9 @@ public class MapEntriesTest {
         
         entries = mapEntries.getResolveMaps();
         assertEquals(4, entries.size());
+        
+        counter = (AtomicLong) vanityCounter.get(mapEntries);
+        assertEquals(4, counter.longValue());        
 
         vanityTargets = (Map<String, List<String>>) field.get(mapEntries);
         assertEquals(2, vanityTargets.size());
@@ -425,6 +433,81 @@ public class MapEntriesTest {
     }
     
     @Test
+    public void test_doAddVanity_1() throws Exception {
+        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
+        field1.setAccessible(true);  
+        field1.set(mapEntries, 10);
+        
+        List<MapEntry> entries = mapEntries.getResolveMaps();
+        assertEquals(0, entries.size());
+        Field field = MapEntries.class.getDeclaredField("vanityTargets");
+        field.setAccessible(true);
+        Map<String, List<String>> vanityTargets = (Map<String, List<String>>) field.get(mapEntries);
+        assertEquals(0, vanityTargets.size());
+        
+        Method method = MapEntries.class.getDeclaredMethod("doAddVanity", String.class);
+        method.setAccessible(true);
+        
+        Resource justVanityPath = mock(Resource.class, "justVanityPath");
+        when(resourceResolver.getResource("/justVanityPath")).thenReturn(justVanityPath);
+        when(justVanityPath.getPath()).thenReturn("/justVanityPath");                 
+        when(justVanityPath.getName()).thenReturn("justVanityPath");
+        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));
+        
+        method.invoke(mapEntries, "/justVanityPath");
+
+        entries = mapEntries.getResolveMaps();
+        assertEquals(2, entries.size());
+        
+        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
+        vanityCounter.setAccessible(true);  
+        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
+        assertEquals(2, counter.longValue());        
+        
+        //bad vanity
+        Resource badVanityPath = mock(Resource.class, "badVanityPath");
+        when(resourceResolver.getResource("/badVanityPath")).thenReturn(badVanityPath);
+        when(badVanityPath.getPath()).thenReturn("/badVanityPath");
+        when(badVanityPath.getName()).thenReturn("badVanityPath");        
+        when(badVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/content/mypage/en-us-{132"));
+        
+        method.invoke(mapEntries, "/badVanityPath");
+        
+
+        assertEquals(2, entries.size());
+
+        vanityTargets = (Map<String, List<String>>) field.get(mapEntries);
+        assertEquals(1, vanityTargets.size());
+        
+        //vanity under jcr:content
+        Resource vanityPathOnJcrContentParent = mock(Resource.class, "vanityPathOnJcrContentParent");
+        when(vanityPathOnJcrContentParent.getPath()).thenReturn("/vanityPathOnJcrContent");
+        when(vanityPathOnJcrContentParent.getName()).thenReturn("vanityPathOnJcrContent");
+
+        Resource vanityPathOnJcrContent = mock(Resource.class, "vanityPathOnJcrContent");
+        when(resourceResolver.getResource("/vanityPathOnJcrContent/jcr:content")).thenReturn(vanityPathOnJcrContent);
+        when(vanityPathOnJcrContent.getPath()).thenReturn("/vanityPathOnJcrContent/jcr:content");
+        when(vanityPathOnJcrContent.getName()).thenReturn("jcr:content");
+        when(vanityPathOnJcrContent.getParent()).thenReturn(vanityPathOnJcrContentParent);
+        when(vanityPathOnJcrContent.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/vanityPathOnJcrContent"));
+        
+        method.invoke(mapEntries, "/vanityPathOnJcrContent/jcr:content");
+        
+        entries = mapEntries.getResolveMaps();
+        assertEquals(4, entries.size());
+        
+        counter = (AtomicLong) vanityCounter.get(mapEntries);
+        assertEquals(4, counter.longValue());
+
+        vanityTargets = (Map<String, List<String>>) field.get(mapEntries);
+        assertEquals(2, vanityTargets.size());
+        
+        assertNull(vanityTargets.get("/vanityPathOnJcrContent/jcr:content"));
+        assertNotNull(vanityTargets.get("/vanityPathOnJcrContent"));
+    }
+    
+    
+    @Test
     public void test_doUpdateVanity() throws Exception {
         Field field0 = MapEntries.class.getDeclaredField("resolveMapsMap");
         field0.setAccessible(true);   
@@ -1424,7 +1507,7 @@ public class MapEntriesTest {
         Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
         vanityCounter.setAccessible(true);  
         AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
-        assertEquals(1, counter.longValue());        
+        assertEquals(2, counter.longValue());        
     }
     
     @Test
@@ -1459,11 +1542,91 @@ public class MapEntriesTest {
         
         Method method = MapEntries.class.getDeclaredMethod("getVanityPaths", String.class);
         method.setAccessible(true);
-        method.invoke(mapEntries, "/existing");   
+        method.invoke(mapEntries, "/justVanityPath");   
         
         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_4() throws Exception { 
+        
+        final Resource badVanityPath = mock(Resource.class, "badVanityPath");
+        when(badVanityPath.getPath()).thenReturn("/badVanityPath");
+        when(badVanityPath.getName()).thenReturn("badVanityPath");
+        when(badVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/content/mypage/en-us-{132"));
+        
+        
+        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(badVanityPath).iterator();
+                } else {
+                    return Collections.<Resource> emptySet().iterator();
+                }
+            }
+        });
+        
+        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
+        field1.setAccessible(true);  
+        field1.set(mapEntries, 0);
+        
+        Field field2 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntriesStartup");
+        field2.setAccessible(true);  
+        field2.set(mapEntries, true);
+        
+        Method method = MapEntries.class.getDeclaredMethod("getVanityPaths", String.class);
+        method.setAccessible(true);
+        method.invoke(mapEntries, "/badVanityPath");   
+        
+        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_5() throws Exception { 
+        
+        final Resource justVanityPath = mock(Resource.class, "justVanityPath");
+        when(resourceResolver.getResource("/justVanityPath")).thenReturn(justVanityPath);
+        when(justVanityPath.getPath()).thenReturn("/justVanityPath");                 
+        when(justVanityPath.getName()).thenReturn("justVanityPath");
+        when(justVanityPath.adaptTo(ValueMap.class)).thenReturn(buildValueMap("sling:vanityPath", "/target/justVanityPath"));
+        
+        
+        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(justVanityPath).iterator();
+                } else {
+                    return Collections.<Resource> emptySet().iterator();
+                }
+            }
+        });
+        
+        Field field1 = MapEntries.class.getDeclaredField("maxCachedVanityPathEntries");
+        field1.setAccessible(true);  
+        field1.set(mapEntries, 2);
+        
+        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, "/justVanityPath");   
+        
+        Field vanityCounter = MapEntries.class.getDeclaredField("vanityCounter");
+        vanityCounter.setAccessible(true);  
+        AtomicLong counter = (AtomicLong) vanityCounter.get(mapEntries);
+        assertEquals(2, counter.longValue());        
+    }
+    
 }