You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by iv...@apache.org on 2008/06/16 17:42:20 UTC
svn commit: r668201 -
/wicket/trunk/wicket/src/main/java/org/apache/wicket/Localizer.java
Author: ivaynberg
Date: Mon Jun 16 08:42:19 2008
New Revision: 668201
URL: http://svn.apache.org/viewvc?rev=668201&view=rev
Log:
WICKET-1667, WICKET-1697: localizer memory leak fixes
Modified:
wicket/trunk/wicket/src/main/java/org/apache/wicket/Localizer.java
Modified: wicket/trunk/wicket/src/main/java/org/apache/wicket/Localizer.java
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/Localizer.java?rev=668201&r1=668200&r2=668201&view=diff
==============================================================================
--- wicket/trunk/wicket/src/main/java/org/apache/wicket/Localizer.java (original)
+++ wicket/trunk/wicket/src/main/java/org/apache/wicket/Localizer.java Mon Jun 16 08:42:19 2008
@@ -16,12 +16,16 @@
*/
package org.apache.wicket;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import org.apache.wicket.markup.repeater.AbstractRepeater;
import org.apache.wicket.model.IModel;
import org.apache.wicket.resource.loader.IStringResourceLoader;
import org.apache.wicket.settings.IResourceSettings;
@@ -57,6 +61,8 @@
/** Cache properties */
private Map<String, String> cache = newCache();
+ private final ClassMetaDatabase metaDatabase = new ClassMetaDatabase();
+
/**
* Create the utils instance class backed by the configuration information contained within the
* supplied application object.
@@ -331,11 +337,26 @@
Component<?> cursor = component;
while (cursor != null)
{
- buffer.append("-").append(cursor.getClass().getName());
- buffer.append(":").append(cursor.getId());
- cursor = cursor.getParent();
+ buffer.append("-").append(metaDatabase.id(cursor.getClass()));
+
if (cursor instanceof Page)
+ {
break;
+ }
+
+ if (cursor.getParent() != null && !(cursor.getParent() instanceof AbstractRepeater))
+ {
+ /*
+ * only append component id if parent is not a repeater because
+ *
+ * (a) these ids are irrelevant when generating resource cache keys
+ *
+ * (b) they cause a lot of redundant keys to be generated
+ */
+ buffer.append(":").append(cursor.getId());
+ }
+ cursor = cursor.getParent();
+
}
buffer.append("-").append(component.getLocale());
@@ -399,4 +420,57 @@
{
return new ConcurrentHashMap<String, String>();
}
+
+ /**
+ * Database that maps class names to an integer id. This is used to make localizer keys shorter
+ * because sometimes they can contain a large number of class names.
+ *
+ * @author igor.vaynberg
+ */
+ private static class ClassMetaDatabase
+ {
+ private final Map<String, Long> nameToId = new HashMap<String, Long>();
+ private final ReadWriteLock nameToIdLock = new ReentrantReadWriteLock();
+ private long nameCounter = 0;
+
+ /**
+ * Returns a unique id that represents this class' name. This can be used for compressing
+ * class names. Notice this id should not be used across cluster nodes.
+ *
+ * @param clazz
+ * @return long id of class name
+ */
+ public long id(Class<?> clazz)
+ {
+ final String name = clazz.getName();
+ nameToIdLock.readLock().lock();
+ try
+ {
+ Long id = nameToId.get(name);
+ if (id == null)
+ {
+ nameToIdLock.readLock().unlock();
+ nameToIdLock.writeLock().lock();
+ try
+ {
+ nameToId.put(name, nameCounter);
+ id = nameCounter;
+ nameCounter++;
+ }
+ finally
+ {
+ nameToIdLock.readLock().lock();
+ nameToIdLock.writeLock().unlock();
+ }
+ }
+ return id;
+ }
+ finally
+ {
+ nameToIdLock.readLock().unlock();
+ }
+ }
+ }
+
+
}
\ No newline at end of file