Bill Barker wrote:
> If tag-pooling works for you, I'm happy for you. The current
> implementation
> doesn't work for me big time. However, I'm very interested in Costin's
> claim that it can be done thread-local.
One quick question ( looking at generated code ) - why is the TP limited
to 5 instances ? If you expect 20+ concurent requests ( where the TP
would actually matter ) - you'll have the overhead of TP sync, and almost
no benefit. Can you try again with a larger capacity ?
Regarding the "claim" that it can be done thread-local: I attached a first
draft, I'll enhance it later ( it could use ThreadWithAttributes - to save
one extra hashtable lookup ). Let me know if it helps.
Costin
package org.apache.jasper.runtime;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;
import org.apache.jasper.Constants;
import java.util.Hashtable;
import java.util.Enumeration;
/**
* Pool of tag handlers that can be reused.
* Experimental: use thread local.
*
* @author Jan Luehe
*/
public class TagHandlerPool {
private int maxSize=100;
private int initialSize=5;
private ThreadLocal perThread=new ThreadLocal();
// for cleanup
private Hashtable threadData=new Hashtable();
private static class PerThreadData {
Tag handlers[];
int current;
}
/**
* Constructs a tag handler pool with the default capacity.
*/
public TagHandlerPool() {
this(Constants.MAX_POOL_SIZE);
}
/**
* Constructs a tag handler pool with the given capacity.
*
* @param capacity Tag handler pool capacity
*/
public TagHandlerPool(int capacity) {
this.maxSize = capacity;
//this.handlers = new Tag[capacity];
//this.current = -1;
}
/**
* Gets the next available tag handler from this tag handler pool,
* instantiating one if this tag handler pool is empty.
*
* @param handlerClass Tag handler class
*
* @return Reused or newly instantiated tag handler
*
* @throws JspException if a tag handler cannot be instantiated
*/
public Tag get(Class handlerClass) throws JspException {
PerThreadData ptd=(PerThreadData)perThread.get();
if( ptd!=null && ptd.current >=0 ) {
return ptd.handlers[ptd.current--];
} else {
try {
return (Tag) handlerClass.newInstance();
} catch (Exception e) {
throw new JspException(e.getMessage(), e);
}
}
}
/**
* Adds the given tag handler to this tag handler pool, unless this tag
* handler pool has already reached its capacity, in which case the tag
* handler's release() method is called.
*
* @param handler Tag handler to add to this tag handler pool
*/
public void reuse(Tag handler) {
PerThreadData ptd=(PerThreadData)perThread.get();
if( ptd==null ) {
ptd=new PerThreadData();
ptd.handlers=new Tag[ initialSize ];
ptd.current=0;
threadData.put( ptd, ptd );
}
if (ptd.current < (ptd.handlers.length - 1)) {
ptd.handlers[++ptd.current] = handler;
return;
}
// no more space
if( ptd.handlers.length < maxSize ) {
// reallocate
Tag newH[]=new Tag[ptd.handlers.length + initialSize];
System.arraycopy(ptd.handlers, 0, newH, 0, ptd.handlers.length);
ptd.handlers=newH;
ptd.handlers[++ptd.current]=handler;
return;
}
//else
handler.release();
}
/**
* Calls the release() method of all available tag handlers in this tag
* handler pool.
*/
public synchronized void release() {
Enumeration ptdE=threadData.keys();
while( ptdE.hasMoreElements() ) {
PerThreadData ptd=(PerThreadData)ptdE.nextElement();
for (int i=ptd.current; i>=0; i--) {
ptd.handlers[i].release();
}
}
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>