<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    Rolf,<br>
    <br>
    Sorry for rambling. Your original question about memory was related
    to getContent() and efficient iterators and I wanted to point out
    that getChildren() and related methods are more important to me.  I
    threw in a few other related methods and you've answered all my
    questions and taken actions beyond what I expected in such a short
    time frame.<br>
    <br>
    I'm still doing a test migration to JDOM2, and so don't have any
    other comments at this time.<br>
    <br>
    Leigh.<br>
    <br>
    <br>
    On 01/16/2012 04:20 PM, Rolf Lear wrote:
    <blockquote cite="mid:4F14BEE5.6080501@tuis.net" type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=ISO-8859-1">
      <meta name="Generator" content="MS Exchange Server version
        6.5.7036.0">
      <title>Re: [jdom-interest] JDOM and memory</title>
      <!-- Converted from text/plain format -->
      <p><font size="2">Hi Leigh</font>
      </p>
      <p><font size="2">I am uncertain if I am missing something in
          whether your </font>
        <br>
        <font size="2">comments/suggestions are specifically related to
          memory improvement of </font>
        <br>
        <font size="2">JDOM2 (the subject line), or just general
          improvements. Reading your </font>
        <br>
        <font size="2">comments they seem to be unrelated to memory
          specifically, but more </font>
        <br>
        <font size="2">general performance/convenience. That's fine if
          it is, I just want to </font>
        <br>
        <font size="2">make sure I am not missing something...</font>
      </p>
      <p><font size="2">Just to summarize your mail very briefly, you
          are addressing three </font>
        <br>
        <font size="2">areas: getChild*(), XPath, and Exceptions</font>
      </p>
      <br>
      <p><font size="2">getChild...()</font>
        <br>
        <font size="2">=============</font>
      </p>
      <p><font size="2">As for the getChild(...), getChildren(...) and
          getContent(Filter) </font>
        <br>
        <font size="2">methods. They all derive from the same concept
          ... create a FilterList </font>
        <br>
        <font size="2">on the underlying ContentList, and scan it for
          all available (or the </font>
        <br>
        <font size="2">first available for getChild(...) ) matching
          content.</font>
      </p>
      <p><font size="2">JDOM2 already has overridden the 'inefficient'
          iterator (and </font>
        <br>
        <font size="2">listIterator) methods to provide a more efficient
          iterator (a </font>
        <br>
        <font size="2">significant improvement in performance over JDOM
          1.x see </font>
        <br>
        <font size="2"><a moz-do-not-send="true"
            href="http://hunterhacker.github.com/jdom/jdom2/performance.html">http://hunterhacker.github.com/jdom/jdom2/performance.html</a>
          and scroll </font>
        <br>
        <font size="2">down about half the page to 'First major
          performance cycle', compare the </font>
        <br>
        <font size="2">results table to the one below.... )</font>
      </p>
      <p><font size="2">These improvements do *not* override the
          isEmpty() call though, and that </font>
        <br>
        <font size="2">should absolutely be overridden too. By default
          it compares size() == 0, </font>
        <br>
        <font size="2">and that would require a full scan of the
          underlying content, but </font>
        <br>
        <font size="2">iterator.hasNext() in JDOM2 only does a 'lazy'
          scan.</font>
      </p>
      <p><font size="2">So, introduce issue #57, override isEmpty() on
          FilterList. Since </font>
        <br>
        <font size="2">ContentList has a fast size() method then there
          is no need to change </font>
        <br>
        <font size="2">ContentList.isEmpty(). I am trying to think of
          any other methods that </font>
        <br>
        <font size="2">would be slow? There is no way to avoid a full
          scan for FilterList.size()</font>
      </p>
      <p><font size="2">So, in summary on the getChildren code... you
          should already be seeing </font>
        <br>
        <font size="2">improved performance on the getChildren() method
          calls with more </font>
        <br>
        <font size="2">efficient iterators, and soon the isEmpty will be
          even faster too.</font>
      </p>
      <p><font size="2">If/when the ContentList 'moves' in to Element to
          save memory, these </font>
        <br>
        <font size="2">improvements will be preserved.</font>
      </p>
      <br>
      <p><font size="2">XPath</font>
        <br>
        <font size="2">=====</font>
      </p>
      <p><font size="2">In regards to the XPath I took notes from the
          XOM project which has the </font>
        <br>
        <font size="2">'query()' method on all nodes... so for example
          you can:</font>
      </p>
      <p><font size="2">element.query(myxpath);</font>
      </p>
      <p><font size="2">I had a hard look at it and it makes some sense
          to do something similar. </font>
        <br>
        <font size="2">Especially now in JDOM2 where XPath supports more
          than just Element and </font>
        <br>
        <font size="2">Document 'context' items.</font>
      </p>
      <p><font size="2">The issue is that full XPath support requires
          both Namespace and </font>
        <br>
        <font size="2">'Variable' contexts (XOM does address the
          Namespace context). This would </font>
        <br>
        <font size="2">be hard to implement on a simple 'query' method.
          Additionally, XPaths </font>
        <br>
        <font size="2">are intended to be 'compiled' and 'reused'. The
          XOM 'query' </font>
        <br>
        <font size="2">implementation does not support the reuse of the
          XPath. The simple query </font>
        <br>
        <font size="2">method would have to be limited, but would still
          cover (sucks out of </font>
        <br>
        <font size="2">thin air) 95% of XPath use in JDOM I am sure.</font>
      </p>
      <p><font size="2">So, the current XPath implementation in JDOM2 is
          able to do the full </font>
        <br>
        <font size="2">gamut of operation, but loses some convenience
          because you need to </font>
        <br>
        <font size="2">access it outside of the Element/Content.</font>
      </p>
      <p><font size="2">I certainly feel that making XPath more
          accessible to JDOM content would </font>
        <br>
        <font size="2">be 'friendly', but I worry that it will breed
          performance problems if it </font>
        <br>
        <font size="2">is too easy... At the time I worked the JDOM2
          XPath code I looked in to </font>
        <br>
        <font size="2">what it would take to extend the functionality in
          to the 'Content' area </font>
        <br>
        <font size="2">of JDOM (like XOM), but found there were more
          issues than can be </font>
        <br>
        <font size="2">resolved by a person working alone with limited
          XPath experience (me). I </font>
        <br>
        <font size="2">figured I would come back to it. Perhaps now is
          the time.</font>
      </p>
      <p><font size="2">Still, taking your JDOMUtil examples:</font>
      </p>
      <p><font size="2"> > JDOMUtil.selectElementChildren(element,
          xpath)</font>
        <br>
        <font size="2"> > JDOMUtil.selectElement(element, xpath)</font>
        <br>
        <font size="2"> > JDOMUtil.selectAttribute(element, xpath)</font>
        <br>
        <font size="2"> > JDOMUtil.ref(Element element, String xpath,
          String defaultValue)</font>
      </p>
      <p><font size="2">In JDOM2, these same concepts can be 'easily'
          obtained with:</font>
      </p>
      <p><font size="2">Filters.element().filter(XPath.selectNodes(element,
          xpath));</font>
        <br>
        <font size="2">... not sure what the selectElement() would do,
          but you get the idea.</font>
        <br>
        <font size="2">Filters.attribute().filter(XPath.selectNodes(element,
          xpath));</font>
        <br>
        <font size="2">... well, the 'defaultValue' would take a
          tweak....</font>
      </p>
      <br>
      <p><font size="2">Exceptions</font>
        <br>
        <font size="2">==========</font>
      </p>
      <p><font size="2">Interesting observation. I can see the benefit
          of a JDOM 'Runtime' </font>
        <br>
        <font size="2">exception in addition to JDOMException. There are
          a few places where it </font>
        <br>
        <font size="2">could be useful to indicate a programmatic issue
          that does not need to </font>
        <br>
        <font size="2">be explicitly thrown/caught. XPath library is a
          good example.</font>
      </p>
      <p><font size="2">I'll think some more on that... see if I can see
          a problem with </font>
        <br>
        <font size="2">introducing JDOMRuntimeException...... and see
          what other places it </font>
        <br>
        <font size="2">would possibly make sense.</font>
      </p>
      <br>
      <p><font size="2">So, thanks for the comments. If there's anything
          I missed, </font>
        <br>
        <font size="2">misunderstood, or needs attention, please don't
          hesitate!</font>
      </p>
      <p><font size="2">Rolf</font>
      </p>
      <p><font size="2">On 16/01/2012 4:36 PM, Leigh L Klotz Jr wrote:</font>
        <br>
        <font size="2">> I'm currently evaluating the alpha of JDOM2.
          Most of the problems I've</font>
        <br>
        <font size="2">> found with JDOM and Java 6 have been fixed
          in a utility class I have</font>
        <br>
        <font size="2">> called JDOMUtil. A good deal of the methods
          in there are handling</font>
        <br>
        <font size="2">> generic types,</font>
        <br>
        <font size="2">></font>
        <br>
        <font size="2">> As for the question below, I don't often
          have the use case of for()</font>
        <br>
        <font size="2">> iterating over, element.getContent(), but I
          do often iterate over the</font>
        <br>
        <font size="2">> following:</font>
        <br>
        <font size="2">> element.getChildren()</font>
        <br>
        <font size="2">> element.getChildren(name)</font>
        <br>
        <font size="2">> element.getChildren().isEmpty() as a
          surrogate for element.hasChildren()</font>
        <br>
        <font size="2">></font>
        <br>
        <font size="2">> You could have Element.getContent() return a
          List implementation of your</font>
        <br>
        <font size="2">> own, and make the Iterable.iterate() method
          in it (which is what for()</font>
        <br>
        <font size="2">> calls) be efficient. That might also make
          element.getChildren.hasNext be</font>
        <br>
        <font size="2">> efficient, or you could implement isEmpty
          directly.</font>
        <br>
        <font size="2">></font>
        <br>
        <font size="2">> For JDOMUtil, I often use these:</font>
        <br>
        <font size="2">> JDOMUtil.selectElementChildren(element,
          xpath)</font>
        <br>
        <font size="2">> JDOMUtil.selectElement(element, xpath)</font>
        <br>
        <font size="2">> JDOMUtil.selectAttribute(element, xpath)</font>
        <br>
        <font size="2">> JDOMUtil.ref(Element element, String xpath,
          String defaultValue)</font>
        <br>
        <font size="2">></font>
        <br>
        <font size="2">> The JDOMUtil.ref(Element element, String
          xpath, String defaultValue)</font>
        <br>
        <font size="2">> method returns either the leaf-node value of
          the XPath expression, or</font>
        <br>
        <font size="2">> the defaultValue if the nodeset is empty.</font>
        <br>
        <font size="2">></font>
        <br>
        <font size="2">> I've also wrapped every one of the JDOMUtil
          XPath calls with something</font>
        <br>
        <font size="2">> that throws a RuntimeException wrapper for
          JDOMException, and I let pass</font>
        <br>
        <font size="2">> JDOMException and IOException only on
          serialization and parsing</font>
        <br>
        <font size="2">> utilities. I believe that checked exceptions
          for XPath errors are a</font>
        <br>
        <font size="2">> detraction from the simplicity of JDOM.
          XPath exceptions are always</font>
        <br>
        <font size="2">> internal programming errors, and it is the
          rare case where they can be</font>
        <br>
        <font size="2">> corrected at the point of invocation.
          Parsing and IO exceptions can come</font>
        <br>
        <font size="2">> from external system interaction and can
          reasonably be expected to be</font>
        <br>
        <font size="2">> correctable in point source code.</font>
        <br>
        <font size="2">></font>
        <br>
        <font size="2">> Leigh.</font>
        <br>
        <font size="2">></font>
      </p>
    </blockquote>
    <br>
  </body>
</html>