Author: fmeschbe
Date: Wed Sep 3 06:40:35 2008
New Revision: 691609
URL: http://svn.apache.org/viewvc?rev=691609&view=rev
Log:
SLING-641 cache bundle entries for better performance
Added:
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java
Modified:
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceProvider.java
Modified:
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java?rev=691609&r1=691608&r2=691609&view=diff
==============================================================================
---
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java
(original)
+++
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResource.java
Wed Sep 3 06:40:35 2008
@@ -44,7 +44,7 @@
private final ResourceResolver resourceResolver;
- private final Bundle bundle;
+ private final BundleResourceCache bundle;
private final MappedPath mappedPath;
@@ -57,7 +57,8 @@
private final ResourceMetadata metadata;
public static BundleResource getResource(ResourceResolver resourceResolver,
- Bundle bundle, MappedPath mappedPath, String resourcePath) {
+ BundleResourceCache bundle, MappedPath mappedPath,
+ String resourcePath) {
String entryPath = mappedPath.getEntryPath(resourcePath);
@@ -100,8 +101,9 @@
return null;
}
- public BundleResource(ResourceResolver resourceResolver, Bundle bundle,
- MappedPath mappedPath, String resourcePath) {
+ public BundleResource(ResourceResolver resourceResolver,
+ BundleResourceCache bundle, MappedPath mappedPath,
+ String resourcePath) {
this.resourceResolver = resourceResolver;
this.bundle = bundle;
@@ -109,8 +111,8 @@
metadata = new ResourceMetadata();
metadata.setResolutionPath(resourcePath);
- metadata.setCreationTime(bundle.getLastModified());
- metadata.setModificationTime(bundle.getLastModified());
+ metadata.setCreationTime(bundle.getBundle().getLastModified());
+ metadata.setModificationTime(bundle.getBundle().getLastModified());
if (resourcePath.endsWith("/")) {
@@ -197,8 +199,8 @@
if (url == null) {
try {
url = new URL(BundleResourceURLStreamHandler.PROTOCOL, null,
- -1, path, new BundleResourceURLStreamHandler(bundle,
- mappedPath.getEntryPath(path)));
+ -1, path, new BundleResourceURLStreamHandler(
+ bundle.getBundle(), mappedPath.getEntryPath(path)));
} catch (MalformedURLException mue) {
log.error("getURL: Cannot get URL for " + this, mue);
}
@@ -211,14 +213,14 @@
return new BundleResourceIterator(this);
}
- Bundle getBundle() {
+ BundleResourceCache getBundle() {
return bundle;
}
MappedPath getMappedPath() {
return mappedPath;
}
-
+
boolean isFile() {
return NT_FILE.equals(getResourceType());
}
Added:
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java?rev=691609&view=auto
==============================================================================
---
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java
(added)
+++
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceCache.java
Wed Sep 3 06:40:35 2008
@@ -0,0 +1,124 @@
+/*
+ * $Url: $
+ * $Id: $
+ *
+ * Copyright 1997-2005 Day Management AG
+ * Barfuesserplatz 6, 4001 Basel, Switzerland
+ * All Rights Reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * Day Management AG, ("Confidential Information"). You shall not
+ * disclose such Confidential Information and shall use it only in
+ * accordance with the terms of the license agreement you entered into
+ * with Day.
+ */
+package org.apache.sling.bundleresource.impl;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.osgi.framework.Bundle;
+
+public class BundleResourceCache {
+
+ private static final URL NOT_FOUND_URL;
+
+ private static final List<String> NOT_FOUND_CHILDREN =
Collections.<String> emptyList();
+
+ private final BundleResourceMap<String, URL> cache;
+
+ private final BundleResourceMap<String, List<String>> listCache;
+
+ private final Bundle bundle;
+
+ static {
+ try {
+ NOT_FOUND_URL = new URL("file:///not_found");
+ } catch (MalformedURLException mue) {
+ throw new ExceptionInInitializerError(mue);
+ }
+ }
+
+ BundleResourceCache(Bundle bundle) {
+ this.bundle = bundle;
+ this.cache = new BundleResourceMap<String, URL>(50);
+ this.listCache = new BundleResourceMap<String, List<String>>(20);
+ }
+
+ Bundle getBundle() {
+ return bundle;
+ }
+
+ URL getEntry(String path) {
+ URL url = cache.get(path);
+ if (url == null) {
+ url = bundle.getEntry(path);
+
+ if (url == null) {
+ url = NOT_FOUND_URL;
+ }
+
+ cache.put(path, url);
+ }
+
+ return (url == NOT_FOUND_URL) ? null : url;
+ }
+
+ Iterator<String> getEntryPaths(String path) {
+ List<String> list = listCache.get(path);
+ if (list == null) {
+
+ @SuppressWarnings("unchecked")
+ Enumeration<String> entries = bundle.getEntryPaths(path);
+ if (entries != null && entries.hasMoreElements()) {
+ list = new LinkedList<String>();
+ while (entries.hasMoreElements()) {
+ list.add(entries.nextElement());
+ }
+ }
+
+ if (list == null) {
+ list = NOT_FOUND_CHILDREN;
+ }
+
+ listCache.put(path, list);
+ }
+
+ return (list == NOT_FOUND_CHILDREN) ? null : list.iterator();
+ }
+
+ private static class BundleResourceMap<K, V> extends LinkedHashMap<String,
V> {
+
+ /**
+ * The default size of a bundle resource cache.
+ */
+ public static final int DEFAULT_LIMIT = 100;
+
+ private final int limit;
+
+ BundleResourceMap(int limit) {
+ if (limit <= 0) {
+ limit = DEFAULT_LIMIT;
+ }
+
+ this.limit = limit;
+ }
+
+ /**
+ * Returns <code>true</code> if the current number of elements in the
+ * map exceeds the configured limit.
+ */
+ @Override
+ protected boolean removeEldestEntry(Entry<String, V> eldest) {
+ return size() > limit;
+ }
+ }
+
+}
Modified:
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java?rev=691609&r1=691608&r2=691609&view=diff
==============================================================================
---
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java
(original)
+++
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceIterator.java
Wed Sep 3 06:40:35 2008
@@ -42,12 +42,12 @@
private final ResourceResolver resourceResolver;
/** Bundle providing the entry resources */
- private final Bundle bundle;
+ private final BundleResourceCache bundle;
private final MappedPath mappedPath;
/** Underlying bundle entry path enumeration */
- private final Enumeration<String> entries;
+ private final Iterator<String> entries;
/** The length of the parent entry path, see seek() */
private final int prefixLength;
@@ -58,7 +58,6 @@
/**
* Creates an instance using the given parent bundle resource.
*/
- @SuppressWarnings("unchecked")
BundleResourceIterator(BundleResource parent) {
if (parent.isFile()) {
@@ -78,17 +77,14 @@
this.resourceResolver = parent.getResourceResolver();
this.bundle = parent.getBundle();
this.mappedPath = parent.getMappedPath();
-
- // unchecked cast
this.entries = parent.getBundle().getEntryPaths(parentPath);
this.prefixLength = parentPath.length();
-
- this.nextResult = seek();
+
+ this.nextResult = (entries != null) ? seek() : null;
}
}
- @SuppressWarnings("unchecked")
- BundleResourceIterator(ResourceResolver resourceResolver, Bundle bundle,
+ BundleResourceIterator(ResourceResolver resourceResolver,
BundleResourceCache bundle,
MappedPath mappedPath, String parentPath) {
// trailing slash to enumerate children
@@ -99,8 +95,6 @@
this.resourceResolver = resourceResolver;
this.bundle = bundle;
this.mappedPath = mappedPath;
-
- // unchecked cast
this.entries = bundle.getEntryPaths(parentPath);
this.prefixLength = parentPath.length();
@@ -136,8 +130,8 @@
* direct child of the parent resource.
*/
private Resource seek() {
- while (entries.hasMoreElements()) {
- String entry = entries.nextElement();
+ while (entries.hasNext()) {
+ String entry = entries.next();
// require leading slash
if (!entry.startsWith("/")) {
Modified:
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceProvider.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceProvider.java?rev=691609&r1=691608&r2=691609&view=diff
==============================================================================
---
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceProvider.java
(original)
+++
incubator/sling/trunk/extensions/bundleresource/src/main/java/org/apache/sling/bundleresource/impl/BundleResourceProvider.java
Wed Sep 3 06:40:35 2008
@@ -18,12 +18,14 @@
*/
package org.apache.sling.bundleresource.impl;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.StringTokenizer;
import javax.servlet.http.HttpServletRequest;
@@ -40,20 +42,20 @@
public class BundleResourceProvider implements ResourceProvider {
/** The bundle providing the resources */
- private final Bundle bundle;
+ private final BundleResourceCache bundle;
/** The root paths */
private final MappedPath[] roots;
private ServiceRegistration serviceRegistration;
-
+
/**
* Creates Bundle resource provider accessing entries in the given Bundle
an
* supporting resources below root paths given by the rootList which is a
* comma (and whitespace) separated list of absolute paths.
*/
public BundleResourceProvider(Bundle bundle, String rootList) {
- this.bundle = bundle;
+ this.bundle = new BundleResourceCache(bundle);
StringTokenizer pt = new StringTokenizer(rootList, ", \t\n\r\f");
List<MappedPath> prefixList = new ArrayList<MappedPath>();