[ http://nagoya.apache.org/jira/browse/XALANJ-984?page=history ]

Henry Zongaro updated XALANJ-984:
---------------------------------

      Assign To:     (was: Xalan Developers Mailing List)
           type: Improvement  (was: Bug)
    Description: 
In Extensions.java, the distinct function uses the Hashtable object to track 
unique nodes.  The Hashtable object synchronizes all access to instances of 
itself.  In Xalan 2.3.1, the current code is as follows:

  public static NodeSet distinct(ExpressionContext myContext, NodeIterator ni)
          throws javax.xml.transform.TransformerException
  {

    // Set up our resulting NodeSet and the hashtable we use to keep track of 
duplicate
    // strings.

    NodeSet dist = new NodeSet();
    dist.setShouldCacheNodes(true);

    Hashtable stringTable = new Hashtable();

    Node currNode = ni.nextNode();

    while (currNode != null)
    {
      String key = myContext.toString(currNode);

      if (!stringTable.containsKey(key))
      {
        stringTable.put(key, currNode);
        dist.addElement(currNode);
      }
      currNode = ni.nextNode();
    }

    return dist;
  }

Since the Hashtable instance is used locally within the method, there really is 
not need to use an object that synchronizes access to its instance.  To improve 
performance, a HashSet should be used.  Furthermore, it is a good idea to 
manually clear the HashSet at the end of the method to ensure the HashSet 
instance is garbage collected.  The enhanced code is as follows:

  public static NodeSet distinct(ExpressionContext myContext, NodeIterator ni)
          throws javax.xml.transform.TransformerException
  {

    // Set up our resulting NodeSet and the hashtable we use to keep track of 
duplicate
    // strings.

    NodeSet dist = new NodeSet();
    dist.setShouldCacheNodes(true);

    HashSet stringSet = new HashSet();

    Node currNode = ni.nextNode();

    while (currNode != null)
    {
      String key = myContext.toString(currNode);

      if (stringSet.add(key))
      {
        dist.addElement(currNode);
      }
      currNode = ni.nextNode();
    }

    stringSet.clear();

    return dist;
  }


If you want to "completely" ensure the HashSet is garbage collected (due a 
TransformerException being thrown), the following enhanced code could be used 
instead of the above enhanced code:

  public static NodeSet distinct(ExpressionContext myContext, NodeIterator ni)
          throws javax.xml.transform.TransformerException
  {

    // Set up our resulting NodeSet and the hashtable we use to keep track of 
duplicate
    // strings.

    NodeSet dist = new NodeSet();
    dist.setShouldCacheNodes(true);

    HashSet stringSet = new HashSet();

    try
    {
      Node currNode = ni.nextNode();

      while (currNode != null)
      {
        String key = myContext.toString(currNode);

        if (stringSet.add(key))
        {
          dist.addElement(currNode);
        }
        currNode = ni.nextNode();
      }
    }
    finally
    {
      stringSet.clear();
    }

    return dist;
  }

  was:
In Extensions.java, the distinct function uses the Hashtable object to track 
unique nodes.  The Hashtable object synchronizes all access to instances of 
itself.  In Xalan 2.3.1, the current code is as follows:

  public static NodeSet distinct(ExpressionContext myContext, NodeIterator ni)
          throws javax.xml.transform.TransformerException
  {

    // Set up our resulting NodeSet and the hashtable we use to keep track of 
duplicate
    // strings.

    NodeSet dist = new NodeSet();
    dist.setShouldCacheNodes(true);

    Hashtable stringTable = new Hashtable();

    Node currNode = ni.nextNode();

    while (currNode != null)
    {
      String key = myContext.toString(currNode);

      if (!stringTable.containsKey(key))
      {
        stringTable.put(key, currNode);
        dist.addElement(currNode);
      }
      currNode = ni.nextNode();
    }

    return dist;
  }

Since the Hashtable instance is used locally within the method, there really is 
not need to use an object that synchronizes access to its instance.  To improve 
performance, a HashSet should be used.  Furthermore, it is a good idea to 
manually clear the HashSet at the end of the method to ensure the HashSet 
instance is garbage collected.  The enhanced code is as follows:

  public static NodeSet distinct(ExpressionContext myContext, NodeIterator ni)
          throws javax.xml.transform.TransformerException
  {

    // Set up our resulting NodeSet and the hashtable we use to keep track of 
duplicate
    // strings.

    NodeSet dist = new NodeSet();
    dist.setShouldCacheNodes(true);

    HashSet stringSet = new HashSet();

    Node currNode = ni.nextNode();

    while (currNode != null)
    {
      String key = myContext.toString(currNode);

      if (stringSet.add(key))
      {
        dist.addElement(currNode);
      }
      currNode = ni.nextNode();
    }

    stringSet.clear();

    return dist;
  }


If you want to "completely" ensure the HashSet is garbage collected (due a 
TransformerException being thrown), the following enhanced code could be used 
instead of the above enhanced code:

  public static NodeSet distinct(ExpressionContext myContext, NodeIterator ni)
          throws javax.xml.transform.TransformerException
  {

    // Set up our resulting NodeSet and the hashtable we use to keep track of 
duplicate
    // strings.

    NodeSet dist = new NodeSet();
    dist.setShouldCacheNodes(true);

    HashSet stringSet = new HashSet();

    try
    {
      Node currNode = ni.nextNode();

      while (currNode != null)
      {
        String key = myContext.toString(currNode);

        if (stringSet.add(key))
        {
          dist.addElement(currNode);
        }
        currNode = ni.nextNode();
      }
    }
    finally
    {
      stringSet.clear();
    }

    return dist;
  }

    Environment: 
Operating System: All
Platform: All

  was:
Operating System: All
Platform: All

       Priority: Major
    Bugzilla Id:   (was: 8612)

> Performance Enhancement to Xalan distinct function
> --------------------------------------------------
>
>          Key: XALANJ-984
>          URL: http://nagoya.apache.org/jira/browse/XALANJ-984
>      Project: XalanJ2
>         Type: Improvement
>   Components: XPath-function
>     Versions: 2.3
>  Environment: Operating System: All
> Platform: All
>     Reporter: Larry Becker

>
> In Extensions.java, the distinct function uses the Hashtable object to track 
> unique nodes.  The Hashtable object synchronizes all access to instances of 
> itself.  In Xalan 2.3.1, the current code is as follows:
>   public static NodeSet distinct(ExpressionContext myContext, NodeIterator ni)
>           throws javax.xml.transform.TransformerException
>   {
>     // Set up our resulting NodeSet and the hashtable we use to keep track of 
> duplicate
>     // strings.
>     NodeSet dist = new NodeSet();
>     dist.setShouldCacheNodes(true);
>     Hashtable stringTable = new Hashtable();
>     Node currNode = ni.nextNode();
>     while (currNode != null)
>     {
>       String key = myContext.toString(currNode);
>       if (!stringTable.containsKey(key))
>       {
>         stringTable.put(key, currNode);
>         dist.addElement(currNode);
>       }
>       currNode = ni.nextNode();
>     }
>     return dist;
>   }
> Since the Hashtable instance is used locally within the method, there really 
> is 
> not need to use an object that synchronizes access to its instance.  To 
> improve 
> performance, a HashSet should be used.  Furthermore, it is a good idea to 
> manually clear the HashSet at the end of the method to ensure the HashSet 
> instance is garbage collected.  The enhanced code is as follows:
>   public static NodeSet distinct(ExpressionContext myContext, NodeIterator ni)
>           throws javax.xml.transform.TransformerException
>   {
>     // Set up our resulting NodeSet and the hashtable we use to keep track of 
> duplicate
>     // strings.
>     NodeSet dist = new NodeSet();
>     dist.setShouldCacheNodes(true);
>     HashSet stringSet = new HashSet();
>     Node currNode = ni.nextNode();
>     while (currNode != null)
>     {
>       String key = myContext.toString(currNode);
>       if (stringSet.add(key))
>       {
>         dist.addElement(currNode);
>       }
>       currNode = ni.nextNode();
>     }
>     stringSet.clear();
>     return dist;
>   }
> If you want to "completely" ensure the HashSet is garbage collected (due a 
> TransformerException being thrown), the following enhanced code could be used 
> instead of the above enhanced code:
>   public static NodeSet distinct(ExpressionContext myContext, NodeIterator ni)
>           throws javax.xml.transform.TransformerException
>   {
>     // Set up our resulting NodeSet and the hashtable we use to keep track of 
> duplicate
>     // strings.
>     NodeSet dist = new NodeSet();
>     dist.setShouldCacheNodes(true);
>     HashSet stringSet = new HashSet();
>     try
>     {
>       Node currNode = ni.nextNode();
>       while (currNode != null)
>       {
>         String key = myContext.toString(currNode);
>         if (stringSet.add(key))
>         {
>           dist.addElement(currNode);
>         }
>         currNode = ni.nextNode();
>       }
>     }
>     finally
>     {
>       stringSet.clear();
>     }
>     return dist;
>   }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://nagoya.apache.org/jira/secure/Administrators.jspa
-
If you want more information on JIRA, or have a bug to report see:
   http://www.atlassian.com/software/jira


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

Reply via email to