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 <jus...@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" <commits@sling.apache.org>.