You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:59:55 UTC

[sling-org-apache-sling-resourceresolver] 25/47: SLING-2521 - improving (dramatically) performance of sling:alias lookups during resolution by pre-caching aliases

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.resourceresolver-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resourceresolver.git

commit b03e3d6c2edbe19ec5f84521553711fc3fde042a
Author: Justin Edelson <ju...@apache.org>
AuthorDate: Wed Aug 29 01:47:45 2012 +0000

    SLING-2521 - improving (dramatically) performance of sling:alias lookups during resolution by pre-caching aliases
    
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/resourceresolver@1378421 13f79535-47bb-0310-9956-ffa450edef68
---
 .../impl/ResourceResolverImpl.java                 | 22 +++-----
 .../resourceresolver/impl/mapping/MapEntries.java  | 62 +++++++++++++++++++++-
 2 files changed, 69 insertions(+), 15 deletions(-)

diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
index 9061e4d..5a2fb29 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
@@ -80,7 +80,7 @@ public class ResourceResolverImpl extends SlingAdaptable implements ResourceReso
 
     public static final String PROP_REDIRECT_INTERNAL = "sling:internalRedirect";
 
-    private static final String PROP_ALIAS = "sling:alias";
+    public static final String PROP_ALIAS = "sling:alias";
 
     // The suffix of a resource being a content node of some parent
     // such as nt:file. The slash is included to prevent false
@@ -863,19 +863,13 @@ public class ResourceResolverImpl extends SlingAdaptable implements ResourceReso
 
         // we do not have a child with the exact name, so we look for
         // a child, whose alias matches the childName
-        final Iterator<Resource> children = listChildren(parent);
-        while (children.hasNext()) {
-            child = children.next();
-            if (!child.getPath().endsWith(JCR_CONTENT_LEAF)) {
-                final String[] aliases = getProperty(child, PROP_ALIAS, String[].class);
-                if (aliases != null) {
-                    for (final String alias : aliases) {
-                        if (childName.equals(alias)) {
-                            logger.debug("getChildInternal: Found Resource {} with alias {} to use", child, childName);
-                            return child;
-                        }
-                    }
-                }
+        
+        final Map<String, String> aliases = factory.getMapEntries().getAliasMap(parent.getPath());
+        if (aliases != null) {
+            if (aliases.containsKey(childName)) {
+                final Resource aliasedChild = getResource(parent, aliases.get(childName));
+                logger.debug("getChildInternal: Found Resource {} with alias {} to use", aliasedChild, childName);
+                return aliasedChild;
             }
         }
 
diff --git a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
index 29d9169..533affe 100644
--- a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
+++ b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
@@ -96,6 +96,8 @@ public class MapEntries implements EventHandler {
 
     private Collection<String> vanityTargets;
 
+    private Map<String, Map<String, String>> aliasMap;
+
     private ServiceRegistration registration;
 
     private EventAdmin eventAdmin;
@@ -113,6 +115,7 @@ public class MapEntries implements EventHandler {
         this.resolveMapsMap = Collections.singletonMap(GLOBAL_LIST_KEY, (List<MapEntry>)Collections.EMPTY_LIST);
         this.mapMaps = Collections.<MapEntry> emptyList();
         this.vanityTargets = Collections.<String> emptySet();
+        this.aliasMap = Collections.<String, Map<String, String>>emptyMap();
         this.registration = null;
         this.eventAdmin = null;
     }
@@ -128,6 +131,7 @@ public class MapEntries implements EventHandler {
         this.resolveMapsMap = Collections.singletonMap(GLOBAL_LIST_KEY, (List<MapEntry>)Collections.EMPTY_LIST);
         this.mapMaps = Collections.<MapEntry> emptyList();
         this.vanityTargets = Collections.<String> emptySet();
+        this.aliasMap = Collections.<String, Map<String, String>>emptyMap();
 
         doInit();
 
@@ -207,9 +211,12 @@ public class MapEntries implements EventHandler {
             Collections.sort(globalResolveMap);
             newResolveMapsMap.put(GLOBAL_LIST_KEY, globalResolveMap);
 
+            final Map<String, Map<String, String>> aliasMap = this.loadAliases(resolver);
+
             this.vanityTargets = Collections.unmodifiableCollection(vanityTargets);
             this.resolveMapsMap = Collections.unmodifiableMap(newResolveMapsMap);
             this.mapMaps = Collections.unmodifiableSet(new TreeSet<MapEntry>(newMapMaps.values()));
+            this.aliasMap = makeUnmodifiableMap(aliasMap);
 
             sendChangeEvent();
 
@@ -224,6 +231,14 @@ public class MapEntries implements EventHandler {
         }
     }
 
+    private <K1, K2, V> Map<K1, Map<K2, V>> makeUnmodifiableMap(final Map<K1, Map<K2, V>> map) {
+        final Map<K1, Map<K2, V>> newMap = new HashMap<K1, Map<K2, V>>();
+        for (final K1 key : map.keySet()) {
+            newMap.put(key, Collections.unmodifiableMap(map.get(key)));
+        }
+        return Collections.unmodifiableMap(newMap);
+    }
+
     /**
      * Cleans up this class.
      */
@@ -311,6 +326,10 @@ public class MapEntries implements EventHandler {
         return mapMaps;
     }
 
+    public Map<String, String> getAliasMap(final String parentPath) {
+        return aliasMap.get(parentPath);
+    }
+
     // ---------- EventListener interface
 
     /**
@@ -346,6 +365,12 @@ public class MapEntries implements EventHandler {
                     break;
                 }
             }
+            for (final String target : this.aliasMap.keySet()) {
+                if (target.startsWith(path)) {
+                    doInit = true;
+                    break;
+                }
+            }
         }
 
         // trigger an update
@@ -439,6 +464,41 @@ public class MapEntries implements EventHandler {
         Collections.sort(entries);
     }
 
+    private Map<String, Map<String, String>> loadAliases(final ResourceResolver resolver) {
+        final Map<String, Map<String, String>> map = new HashMap<String, Map<String, String>>();
+        final String queryString = "SELECT sling:alias FROM nt:base WHERE sling:alias IS NOT NULL";
+        final Iterator<Resource> i = resolver.findResources(queryString, "sql");
+        while (i.hasNext()) {
+            final Resource resource = i.next();
+
+            // ignore system tree
+            if (resource.getPath().startsWith(JCR_SYSTEM_PREFIX)) {
+                log.debug("loadAliases: Ignoring {}", resource);
+                continue;
+            }
+
+            // require properties
+            final ValueMap props = resource.adaptTo(ValueMap.class);
+            if (props == null) {
+                log.debug("loadAliases: Ignoring {} without properties", resource);
+                continue;
+            }
+
+            final String parentPath = resource.getParent().getPath();
+            Map<String, String> parentMap = map.get(parentPath);
+            if (parentMap == null) {
+                parentMap = new HashMap<String, String>();
+                map.put(parentPath, parentMap);
+            }
+            for (final String alias : props.get(ResourceResolverImpl.PROP_ALIAS, String[].class)) {
+                parentMap.put(alias, resource.getName());
+            }
+        }
+
+        return map;
+
+    }
+
     /**
      * Load vanity paths Search for all nodes inheriting the sling:VanityPath
      * mixin
@@ -648,7 +708,7 @@ public class MapEntries implements EventHandler {
         final String[] nodeProps = { "sling:vanityPath", "sling:vanityOrder",
                         PROP_REDIRECT_EXTERNAL_REDIRECT_STATUS, PROP_REDIRECT_EXTERNAL,
                         ResourceResolverImpl.PROP_REDIRECT_INTERNAL, PROP_REDIRECT_EXTERNAL_STATUS,
-                        PROP_REG_EXP };
+                        PROP_REG_EXP, ResourceResolverImpl.PROP_ALIAS };
         final String[] eventProps = { "resourceAddedAttributes", "resourceChangedAttributes", "resourceRemovedAttributes" };
         final StringBuilder filter = new StringBuilder();
         filter.append("(|");

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.