Thanks for the reply Morten.

> Morten replies:
> > John asks:
> > The following I consider suspicious on the basis
> > that during cloning the state of the clone's
> > _isRestartable should be changed, not the 
> > original object's flag:
> > 
> > PrecedingIterator:       this._isRestartable = false;
> > AncestorIterator:        this._isRestartable = false;
> > StepIterator:            this._isRestartable = false;
> > UnionIterator:           this._isRestartable = false;
> 
> (Note that the _isRestartable flag is set in the source 
> iterator _before_ it is cloned, so the flag is set to
> false in both source and clone.)

When you say "source" I'm taking you to mean the object
on which cloneIterator() was called.

> Cloned iterators are used for variables and parameters. The 
> cloneIterator() method is called when the variable or 
> parameter is read to ensure that the variable or parameter's 
> value does not change. The value of global parameters and 
> variables never change, so it is OK to tag them as not 
> restartable. Iterators stored in local parameters and 
> variables are not re-used but are rather overwritten 
> every time their values change, so marking them as 
> non-restartable should not make any difference.

Well, I've noticed that in some cases the compiler is
re-using iterator objects - not reconstructing them. Consider
the following snippet:

<xsl:template match="/">
<xsl:variable name="var" select="dataset/lump[1]/point"/>
var<xsl:value-of select="$var"/>var
var<xsl:value-of select="$var"/>var
</xsl:template>

The path is compiled into an iterator-tree (or
whatever you want to call it) that looks like:

NodeIterator nodeiterator_0_ =
  new StepIterator(
    new StepIterator(
      dom.getTypedAxisIterator(3, 7),
      new NthIterator(
        dom.getTypedAxisIterator(3, 8),
        1
      )
    ),
    dom.getTypedAxisIterator(3, 9)
  ).setStartNode(i);

This iterator is then subsequently used twice to
retrieve a DOM node. The node is retrieved in the
case of each value-of with code like:

int node = nodeiterator_0_.reset().cloneIterator().next();

Notice that cloneIterator() is being called on the
object returned by reset(). Since cloneIterator() changes
the _isRestartable flag of 'this', and 'this' is
nodeiterator_0_ then the side effect is that
nodeiterator_0_ is no longer restartable after it is
cloned the first time.

Admittedly, this appears to cause no problem for the
above snippet since the second use of $var doesn't
happen in a different node context - and necessitate
a setStartNode(int) on the original object. In mentioning
it at all I guess I figured I was just trying to tidy-up
the code.

Thanks for all the info in your reply.

john

Reply via email to