[
https://issues.apache.org/jira/browse/COLLECTIONS-111?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12526540
]
Henri Yandell commented on COLLECTIONS-111:
-------------------------------------------
The first block of code is a bit of protection that stops an
IndexOutOfBoundsException. It's not possible to enter updateIteratorChain()
without lockChain() having been called, so it's not possible for the iterator
to be empty and then get values later. This initial bit of code looks good.
Then a return statement is removed. With the return statement, an empty
iterator would be considered to be full, so removing this return statement
makes sense. It does mean that there's a new code path to go through the first
time. Jonathan does report that the first element doesn't return, which might
point to this return statement; but he also reports other later elements are
missing which doesn't.
The following changes are one change. An if statement is rolled into the while
loop below it. It's the biggest change, but it seems to be fine.
The new code path means that:
a) An empty iterator is passed down to the while loop. Its hasNext() is false
and currentIteratorIndex (=0) is not less than size-1 (=-1). So the while loop
is not entered and the method returns as before.
b) The first iterator in the array is at its beginning. In Jonthan's case its
hasNext is true, and currentIteratorIndex (=0) is not less than size-1 (0). The
while loop is not entered and the method returns as before. The alternative to
Jonathan's case would be an empty iterator, but that would also not enter the
while loop due to the second clause.
So none of the code changes would appear to cause any problems, and things
would appear to be thread safe because they are read-only at that time - unless
more than one thing is reading the iterator.
That's the only explanation I can see - that there was another thread that was
sometimes reading the other iterator. It doesn't match to Jonathan's report of
2.1.1 being fine and 3.1 being bad.
I've been looking at trunk and not 3.1. Looking at the diff between 3.1 and
trunk, the only change has been protection in remove() against calling
updateCurrentIterator() unless the currentIterator is null. As the report only
has the one iterator in the chain, I can't see this bug leading to elements
vanishing. updateIteratorChain doesn't do element moving, just iterators.
So... I'm all for closing this as Cannot Reproduce.
> IteratorChain skips over elements in iterator
> ---------------------------------------------
>
> Key: COLLECTIONS-111
> URL: https://issues.apache.org/jira/browse/COLLECTIONS-111
> Project: Commons Collections
> Issue Type: Bug
> Components: Iterator
> Affects Versions: 3.1
> Environment: Operating System: Windows XP
> Platform: PC
> Reporter: Jonathan Giles
> Fix For: 3.3
>
>
> Hi there,
> When using the IteratorChain class to add multiple iterators, it appears that
> using itChain.hasNext() and itChain.next() skips a number of elements in the
> iterator at each step.
> Given a single iterator of 7 elements, and using the following code:
> private IteratorChain buildIterator() {
> // this iterator contains the children of the current object only
> Iterator it = getChildren(p);
>
> // we use an IteratorChain to add multiple iterators together without the
> overhead of copying
> IteratorChain itChain = new IteratorChain(it);
> return itChain;
> }
> and then simply
> IteratorChain it = treeModel.getAllTreeNodes(obj);
>
> // FIXME this only prints one or two of the results, which is a bug!
> while (it.hasNext())
> System.out.println(": " + it.next().getClass());
> I put in 7 elements, but only get 2 out - the 2nd and the last elements. It
> appears that through my debugging that the nextClause variable is updated even
> when the hasNext() function is called.
> Also, if I put 7 system.out.println statements, all elements are printed as
> normal.
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.