You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by sc...@apache.org on 2008/02/15 19:38:35 UTC
svn commit: r628144 -
/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java
Author: scheu
Date: Fri Feb 15 10:38:34 2008
New Revision: 628144
URL: http://svn.apache.org/viewvc?rev=628144&view=rev
Log:
AXIS2-3519
Contributor: David Strite
Create and use pool of JAXB Unmarshaller objects.
Modified:
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java?rev=628144&r1=628143&r2=628144&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java Fri Feb 15 10:38:34 2008
@@ -61,15 +61,10 @@
private static Map<ClassLoader, Map<String, JAXBContextValue>> jaxbMap =
new ConcurrentHashMap<ClassLoader, Map<String, JAXBContextValue>>();
- private static Map<JAXBContext, Unmarshaller> umap =
- new ConcurrentHashMap<JAXBContext, Unmarshaller>();
-
- private static Map<JAXBContext, Marshaller> mmap =
- new ConcurrentHashMap<JAXBContext, Marshaller>();
-
- private static Map<JAXBContext, JAXBIntrospector> imap =
- new ConcurrentHashMap<JAXBContext, JAXBIntrospector>();
-
+ private static Pool<JAXBContext, Marshaller> mpool = new Pool<JAXBContext, Marshaller>();
+ private static Pool<JAXBContext, Unmarshaller> upool = new Pool<JAXBContext, Unmarshaller>();
+ private static Pool<JAXBContext, JAXBIntrospector> ipool = new Pool<JAXBContext, JAXBIntrospector>();
+
// From Lizet Ernand:
// If you really care about the performance,
// and/or your application is going to read a lot of small documents,
@@ -82,9 +77,8 @@
private static boolean ENABLE_MARSHALL_POOLING = false;
private static boolean ENABLE_UNMARSHALL_POOLING = true;
private static boolean ENABLE_INTROSPECTION_POOLING = false;
-
- // The maps are freed up when a LOAD FACTOR is hit
- private static int MAX_LOAD_FACTOR = 32;
+
+ private static int MAX_LOAD_FACTOR = 32; // Maximum number of JAXBContext to store
// Construction Type
public enum CONSTRUCTION_TYPE {
@@ -384,18 +378,18 @@
}
return context.createUnmarshaller();
}
- Unmarshaller u = umap.remove(context);
- if (u == null) {
+ Unmarshaller unm = upool.get(context);
+ if (unm == null) {
if (log.isDebugEnabled()) {
log.debug("Unmarshaller created [not in pool]");
}
- u = context.createUnmarshaller();
+ unm = context.createUnmarshaller();
} else {
if (log.isDebugEnabled()) {
log.debug("Unmarshaller obtained [from pool]");
}
}
- return u;
+ return unm;
}
/**
@@ -410,9 +404,7 @@
log.debug("Unmarshaller placed back into pool");
}
if (ENABLE_UNMARSHALL_POOLING) {
- adjustPoolSize(umap);
- unmarshaller.setAttachmentUnmarshaller(null);
- umap.put(context, unmarshaller);
+ upool.put(context, unmarshaller);
}
}
@@ -431,7 +423,7 @@
}
m = context.createMarshaller();
} else {
- m = mmap.remove(context);
+ m = mpool.get(context);
if (m == null) {
if (log.isDebugEnabled()) {
log.debug("Marshaller created [not in pool]");
@@ -459,9 +451,8 @@
log.debug("Marshaller placed back into pool");
}
if (ENABLE_MARSHALL_POOLING) {
- adjustPoolSize(mmap);
marshaller.setAttachmentMarshaller(null);
- mmap.put(context, marshaller);
+ mpool.put(context, marshaller);
}
}
@@ -480,7 +471,7 @@
}
i = context.createJAXBIntrospector();
} else {
- i = imap.remove(context);
+ i = ipool.get(context);
if (i == null) {
if (log.isDebugEnabled()) {
log.debug("JAXBIntrospector created [not in pool]");
@@ -507,8 +498,7 @@
log.debug("JAXBIntrospector placed back into pool");
}
if (ENABLE_INTROSPECTION_POOLING) {
- adjustPoolSize(imap);
- imap.put(context, introspector);
+ ipool.put(context, introspector);
}
}
@@ -911,12 +901,19 @@
return jaxbContext;
}
- /**
- * Adjust the number of objects in the hash map if the limit is exceeded
- *
- * @param map
- */
- private static synchronized void adjustPoolSize(Map map) {
+ /** Holds the JAXBContext and the manner by which it was constructed */
+ static class JAXBContextValue {
+
+ public JAXBContext jaxbContext;
+ public CONSTRUCTION_TYPE constructionType;
+
+ public JAXBContextValue(JAXBContext jaxbContext, CONSTRUCTION_TYPE constructionType) {
+ this.jaxbContext = jaxbContext;
+ this.constructionType = constructionType;
+ }
+ }
+
+ static private void adjustPoolSize(Map map) {
if (map.size() > MAX_LOAD_FACTOR) {
// Remove every other Entry in the map.
Iterator it = map.entrySet().iterator();
@@ -931,15 +928,88 @@
}
}
- /** Holds the JAXBContext and the manner by which it was constructed */
- static class JAXBContextValue {
+ /**
+ * Pool a list of items for a specific key
+ *
+ * @param <K> Key
+ * @param <V> Pooled object
+ */
+ private static class Pool<K,V> {
+ private Map<K,List<V>> map = new ConcurrentHashMap<K, List<V>>();
- public JAXBContext jaxbContext;
- public CONSTRUCTION_TYPE constructionType;
+ // The maps are freed up when a LOAD FACTOR is hit
+ private static int MAX_LIST_FACTOR = 10;
+
+ /**
+ * @param key
+ * @return removed item from pool or null.
+ */
+ public V get(K key) {
+ List<V> values = getValues(key);
+ synchronized (values) {
+ if(values.size()>0) {
+ return values.remove(values.size()-1);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Add item back to pool
+ * @param key
+ * @param value
+ */
+ public void put(K key, V value) {
+ adjustSize();
+ List<V> values = getValues(key);
+ synchronized (values) {
+ if (values.size() < MAX_LIST_FACTOR) {
+ values.add(value);
+ }
+ }
+ }
- public JAXBContextValue(JAXBContext jaxbContext, CONSTRUCTION_TYPE constructionType) {
- this.jaxbContext = jaxbContext;
- this.constructionType = constructionType;
+ /**
+ * Get or create a list of the values for the key
+ * @param key
+ * @return list of values.
+ */
+ private List<V> getValues(K key) {
+ List<V> values = map.get(key);
+ if(values !=null) {
+ return values;
+ }
+ synchronized (this) {
+ values = map.get(key);
+ if(values==null) {
+ values = new ArrayList<V>();
+ map.put(key, values);
+ }
+ return values;
+ }
+ }
+
+ /**
+ * AdjustSize
+ * When the number of keys exceeds the maximum load, half
+ * of the entries are deleted.
+ *
+ * The assumption is that the JAXBContexts, UnMarshallers, Marshallers, etc. require
+ * a large footprint.
+ */
+ private void adjustSize() {
+ if (map.size() > MAX_LOAD_FACTOR) {
+ // Remove every other Entry in the map.
+ Iterator it = map.entrySet().iterator();
+ boolean removeIt = false;
+ while (it.hasNext()) {
+ it.next();
+ if (removeIt) {
+ it.remove();
+ }
+ removeIt = !removeIt;
+ }
+ }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org