Kin-Man and I have been throwing around some ideas of how to support
tag pooling and reuse in Jasper 2.

According to the spec, only tags with the same set of attributes may
be reused (see JSP.10.1.1, p.163, "Lifecycle" section, item 3):
 
  [3] Note that since there are no guarantees on the state of the
  properties, a tag handler that had some optional properties set can
  only be reused if those properties are set to a new (known)
  value. This means that tag handlers can only be reused within the same
  "AttSet" (set of attributes that have been set).

This means that while the same tag handler instance may be used to
service these tags:

  <some_prefix:some_tag a="1" b="2"/>
  <some_prefix:some_tag a="1" b="3"/>
  <some_prefix:some_tag a="1" b="4"/>
  <some_prefix:some_tag a="1" b="5"/>

it may not be used to service

  <some_prefix:some_tag a="1" b="5" c="3"/>

One of the ideas we have considered is to support tag reuse on a
per-page basis, without allowing tag handlers to be shared across
simultaneous page invocations. In this approach, each custom tag is
assigned a tag handler variable name at compile time, based on its
full name, its attribute names, and its nesting level (with respect to
tags with the same name and AttSet). According to this, the two
<prefix1:tag1> tags in:

  <prefix1:tag1 a="1" b="2"/>

  <prefix2:tag2 c="1" d="2">
    <prefix1:tag1 a="1" b="2"/>
  </prefix2:tag2>

would be assigned the same tag handler variable name (both are at
nesting level 0 with respect to their tag "class"), whereas the two
<prefix1:tag1> tags in:

  <prefix1:tag1 a="1" b="2">
    <prefix2:tag2 c="1" d="2">
      <prefix1:tag1 a="1" b="2"/>
    </prefix2:tag2>
  </prefix1:tag1>

would be assigned different tag handler variable names, because they
are at different nesting levels. All tag handler variables determined
in this fashion would be declared as (local) variables at the beginning of
the _jspService() method.

The advantages of this approach would be:
- No need for synchronization.
- Tag handler reuse is determined at compile time.

Disadvantages would be:
- Tag handlers are not shared across multiple page invocations.
- Does not work well with the proposed approach to remove the 64K limit,
since a (possibly large) number of tag handlers would have to be
passed as arguments to (sub)method calls.

------------------------------------------------------------------------------
PROPOSAL:

An alternative proposal that we discussed would allow for tag pooling
across page invocations, using a stack-based approach.

With this approch, each node representing a custom tag is assigned as one
of its fields (at compile time) the name of a tag handler stack,
based on the tag's full name and attribute set (tag's nesting level is
ignored).
All tag handlers in the same stack are intended to be shared among tags
with the same name and attribute set.

For example, if this tag is encountered:

  <a:b c="1" d"=2"/>

a tag handler for it is acquired from the stack named a_b_c_d. If
this stack is empty, a new tag handler is created. When the tag
handler is no longer in use, it is pushed back on the stack so it
can be reused.

The tag handler stacks are declared as instance variables (and
therefore won't need to be passed as arguments to any (sub)method
calls implemented as part of the proposal to remove the 64K limit).

Notice that this approach is very similar to what was done in Tomcat
3.x, except that we would get rid of the TagPoolManager, which stored
all the tag handler stacks (pools) in a hashtable (keyed by the pool
name). This would save us a hash operation and synchronization (on the
hashtable) on every stack lookup.

Note that this approach allows for optimizations in
iterations. Instead of acquiring a tag handler from the appropriate
stack and returning it to the stack in each iteration step, the tag
handler could be acquired at the beginning of the iteration and held
on to for the duration of the iteration.

If this sounds like a reasonable approach, I'll go ahead and provide a
patch for Jasper 2 implementing it.


Jan





--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to