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]>

Reply via email to