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