<?xml version="1.0" standalone="no"?>
<!DOCTYPE s1 SYSTEM "../../style/dtd/document.dtd">
<!-- 
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 2001, Sun
 * Microsystems., http://www.sun.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 -->
  <s1 title="&lt;xsl:key&gt; / key() / IdKeyPattern">

  <s2 title="Contents">
  <ul>
    <li><link anchor="functionality">Functionality</link></li>
    <li><link anchor="implementation">Implementation</link></li>    
  </ul>
  </s2>

  <anchor name="functionality"/>
  <s2 title="Functionality">

  <p>The <code>&lt;xsl:key&gt;</code> element is a top-level element that can be
  used to define a named index of nodes from the source XML tree(s). The
  element has three attributes:</p>

  <ul>
    <li>
      <code>name</code> - the name of the index
    </li>
    <li>
      <code>match</code> - a pattern that defines the nodeset we want
      indexed
    </li>
    <li>
      <code>use</code> - an expression that defines the value to be used
      as the index key value.
    </li>
  </ul>

  <p>A named index can be accessed using either the <code>key()</code> function
  or a KeyPattern. Both these methods address the index using its defined name
  (the "name" attribute above) and a parameter defining one or more lookup
  values for the index. The function or pattern returns a node set containing
  all nodes in the index whose key value match the parameter's value(s):</p>

  <source>
    &lt;xsl:key name="book-author" match="book" use="author"/&gt;
        :
        :
    &lt;xsl:for-each select="key('book-author', 'Mikhail Bulgakov')"&gt;
      &lt;xsl:value-of select="author"/&gt;
      &lt;xsl:text&gt;: &lt;/xsl:text&gt;
      &lt;xsl:value-of select="author"/&gt;
      &lt;xsl:text&gt;&amp;#xa;&lt;/xsl:text&gt;
    &lt;/xsl:for-each&gt;</source>

  <p>The KeyPattern can be used within an index definition to create unions
  and intersections of node sets:</p><source>
    &lt;xsl:key name="cultcies" match="farmer | fisherman" use="name"/&gt;</source>

  <p>This could have been done using regular <code>&lt;xsl:for-each&gt;</code>
  and <code>&lt;xsl:select&gt;</code> elements. However, if your stylesheet
  accesses the same selection of nodes over and over again, the transformation
  will be much more efficient using pre-indexed keys as shown above.</p>

  </s2>

  <anchor name="implementation"/>
  <s2 title="Implementation">

    <anchor name="indexing"/>
    <s3 title="Indexing">

    <p>The <code>AbstractTranslet</code> class has a global hashtable that holds
    an index for each named key in the stylesheet (hashing on the "name"
    attribute of <code>&lt;xsl:key&gt;</code>). <code>AbstractTranslet</code>
    has a couple of public methods for inserting and retrieving data from this
    hashtable:</p><source>
    public void buildKeyIndex(String keyName, int nodeID, String value);
    public KeyIndex KeyIndex getKeyIndex(String keyName);</source>

    <p>The <code>Key</code> class compiles code that traverses the input DOM and
    extracts nodes that match some given parameters (the <code>"match"</code>
    attribute of the <code>&lt;xsl:key&gt;</code> element). A new element is
    inserted into the named key's index. The nodes' DOM index and the value
    translated from the <code>"use"</code> attribute of the
    <code>&lt;xsl:key&gt;</code> element are stored in the new entry in the
    index.</p>

    <p>Something similar is done for indexing IDs. This index is generated from
    the <code>ID</code> and <code>IDREF</code> fields in the input document's
    DTD. This means that the code for generating this index cannot be generated
    at compile-time, which again means that the code has to be generic enough
    to handle all DTDs. The class that handles this is the
    <code>org.apache.xalan.xsltc.dom.DTDMonitor</code> class. This class
    implements the <code>org.xml.sax.XMLReader</code> and
    <code>org.xml.sax.DTDHandler</code> interfaces. A client application using
    the native API must instanciate a <code>DTDMonitor</code> and pass it to the
    translet code - if, and only if, it wants IDs indexed (one can improve
    performance by omitting this step). This is descrived in the
    <link idref="xsltc_native_api">XSLTC Native API reference</link>. The
    <code>DTDMonitor</code> class will use the same indexing as the code
    generated by the <code>Key</code> class. The index for ID's is called
    "##id". We assume that no stylesheets will contain a key with this name.</p>

    <p>The index itself is implemented in the
    <code>org.apache.xalan.xsltc.dom.KeyIndex</code> class. The index has an
    hashtable with all the values from the matching nodes (the part of the node
    used to generate this value is the one specified in the <code>"use"</code>
    attribute). For every matching value there is a bit-array (implemented in
    the <code>org.apache.xalan.xsltc.BitArray</code> class), holding a list of
    all node indexes for which this value gives a match:</p>
    <p><img src="key_relations.gif" alt="key_relations.gif"/></p>
    <p><ref>Figure 1: Indexing tables</ref></p>

    <p>The <code>KeyIndex</code> class implements the <code>NodeIterator</code>
    interface, so that it can be returned directly by the implementation of the
    <code>key()</code> function. This is how the index generated by
    <code>&lt;xsl:key&gt;</code> and the node-set returned by the
    <code>key()</code> and KeyPattern are tied together. You can see how this is
    done in the <code>translate()</code> method of the <code>KeyCall</code>
    class.</p>

    <p>The <code>key()</code> function can be called in two ways:</p><source>
    key('key-name','value')
    key('key-name','node-set')</source>

    <p>The first parameter is always the name of the key. We use this value to
    lookup our index from the _keyIndexes hashtable in AbstractTranslet:</p>
    <source>
    il.append(classGen.aloadThis());
    _name.translate(classGen, methodGen);
    il.append(new INVOKEVIRTUAL(getKeyIndex));</source>

    <p>This compiles into a call to
    <code>AbstractTranslet.getKeyIndex(String name)</code>, and it leaves a
    <code>KeyIndex</code> object on the stack. What we then need to do it to
    initialise the <code>KeyIndex</code> to give us nodes with the requested
    value. This is done by leaving the <code>KeyIndex</code> object on the stack
    and pushing the <code>"value"</code> parameter to <code>key()</code>, before
    calling <code>lookup()</code> on the index:</p><source>
    il.append(DUP);  // duplicate the KeyIndex obejct before return
    _value.translate(classGen, methodGen);
    il.append(new INVOKEVIRTUAL(lookup));</source>

    <p>This compiles into a call to <code>KeyIndex.lookup(String value)</code>.
    This will initialise the <code>KeyIndex</code> object to return nodes that
    match the given value, so the <code>KeyIndex</code> object can be left on
    the stack when we return. This because the <code>KeyIndex</code> object
    implements the <code>NodeIterator</code> interface.</p>

    <p>This matter is a bit more complex when the second parameter of
    <code>key()</code> is a node-set. In this case we need to traverse the nodes
    in the set and do a lookup for each node in the set. What I do is this:</p>

    <ul>
      <li>
        construct a <code>KeyIndex</code> object that will hold the
        return node-set
      </li>
      <li>
        find the named <code>KeyIndex</code> object from the hashtable in
        AbstractTranslet
      </li>
      <li>
        get an iterator for the node-set and do the folowing loop:</li>
        <ul>
          <li>get string value for current node</li>
          <li>do lookup in KeyIndex object for the named index</li>
          <li>merge the resulting node-set into the return node-set</li>
        </ul>
      <li>
        leave the return node-set on stack when done
      </li>
    </ul>

    </s3>

    <anchor name="improvements"/>
    <s3 title="Possible indexing improvements">

    <p>The indexing implementation can be very, very memeory exhaustive as there
    is one <code>BitArray</code> allocated for each value for every index. This
    is particulary bad for the index used for IDs ('##id'), where a single value
    should only map to one, single node. This means that a whole
    <code>BitArray</code> is used just to contain one node. The
    <code>KeyIndex</code> class should be updated to hold the first node for a
    value in an <code>Integer</code> object, and then replace that with a
    <code>BitArray</code> or a <code>Vector</code> only is a second node is
    added to the value. Here is an outline for <code>KeyIndex</code>:</p>
    <source>

    public void add(Object value, int node) {
        Object container;
	if ((container = (BitArray)_index.get(value)) == null) {
            _index.put(value, new Integer(node));
	}
	else {
            // Check if there is _one_ node for this value
            if (container instanceof Integer) {
                int first = ((Integer)container
                _nodes = new BitArray(_arraySize);
                _nodes.setMask(node &amp; 0xff000000);
                _nodes.setBit(first &amp; 0x00ffffff);
                _nodes.setBit(node &amp; 0x00ffffff);
                _index.put(value, _nodes);
            }
            // Otherwise add node to axisting bit array
            else {
                _nodex = (BitArray)container;
                _nodes.setBit(node &amp; 0x00ffffff);
            }
        }
    }</source>

    <p>Other methods inside the <code>KeyIndex</code> should be updated to
    reflect this.</p>

    </s3>

    <anchor name="patterns"/>
    <s3 title="Id and Key patterns">

    <p>As already mentioned, the challenge with the <code>id()</code> and
    <code>key()</code> patterns is that they have no specific node type. 
    Patterns are normally grouped based on their pattern's "kernel" node type.
    This is done in the <code>org.apache.xalan.xsltc.compiler.Mode</code> class.
    The <code>Mode</code> class has a method, <code>flatternAlaternative</code>,
    that does this grouping, and all templates with a common kernel node type
    will be inserted into a "test sequence". A test sequence is a set templates
    with the same kernel node type. The <code>TestSeq</code> class generates
    code that will figure out which pattern, amongst several patterns with the
    same kernel node type, that matches a certain node. This is used by the
    <code>Mode</code> class when generating the <code>applyTemplates</code>
    method in the translet. A test sequence is also generated for all templates
    whose pattern does not have a kernel node type. This is the case for all
    Id and KeyPatterns. This test sequence, if necessary, is put before the
    big <code>switch()</code> in the <code>applyTemplates()</code> mehtod. This
    test has to be done for every single node that is traversed, causing the
    transformation to slow down siginificantly. This is why we do <em>not</em>
    recommend using this type of patterns with XSLTC.</p>

    </s3>

  </s2>

</s1>
