[
https://issues.apache.org/jira/browse/COLLECTIONS-770?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17533748#comment-17533748
]
Steve Bosman commented on COLLECTIONS-770:
------------------------------------------
I can see there are two different forms of nesting here. The iterators end up
inside UnmodifiableIterators and also nested inside IteratorChains. It seems to
me the solution is to collapse the nesting when creating a new unioned
IteratorChain. I have had a quick try and it looks like the numbers in the test
case above can be vastly reduced. It does however rely on a modification to
UnmodifiableIterator to allow access to the IteratorChain.
e.g. given four iterators it1, it2, it3, and it4 inside two iterator chains
ic1, and ic2 then when unioned create a chain (it1, it2, it3, it4) instead of a
chain (ic1, ic2)
There is similar logic for unmodifiableIterators, but more hoops to jump
through.
I hope the above explanation is okay, but if I can get this tested and working,
I will submit a PR which should make it more obvious.
> ToString method is unresponsive after multiple SetUtils union calls
> -------------------------------------------------------------------
>
> Key: COLLECTIONS-770
> URL: https://issues.apache.org/jira/browse/COLLECTIONS-770
> Project: Commons Collections
> Issue Type: Bug
> Affects Versions: 4.4
> Reporter: Thomas Bürli
> Priority: Minor
> Attachments: SetUtilsTest.java, countHasNextCall.patch, stackdump.txt
>
>
> I had the following code and my application stopped responsing as soon the
> number of names for a userId got too big.
> {code:java}
> Map<String, Set<String>> stringMap = new TreeMap<>();
> for (String name : names) {
> for (String userId : userIds) {
> stringMap.merge(userId, Collections.singleton(name),
> SetUtils::union);
> }
> }
> {code}
> I did some debugging and it occurs when the toString method of one the set is
> called. It looks like the issues is with the iterator of "SetUtils.SetView".
> Here just the method I used to create test sets and in the attachment you
> find the full tests class and a stack dump. The execution time is growing
> exponentially with the numbers of times the SetUtils.union is called. So for
> 29 elements it took 16 seconds to execute toString, and with 30 it took 32
> seconds.
> {code:java}
> @Test
> void setWith20Elements() {
> assertTimeout(ofSeconds(2), () -> createSet(30).toString());
> }
> Set<String> createSet(int number) {
> List<String> inputs = new ArrayList<>();
> for (int i = 0; i < number; i++) {
> inputs.add("Test"+ i);
> }
> Set<String> testSet = Collections.singleton("String1");
> for (String element : inputs) {
> Set<String> part = Collections.singleton(element);
> testSet = SetUtils.union(testSet,part);
> }
> return testSet;
> }
> {code}
> Thanks for your support
--
This message was sent by Atlassian Jira
(v8.20.7#820007)