Fix for broken contract for GroupNode node comparator. #58
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Please verify this implementation as I haven't been able to reproduce the exact state for testing!
This fixes a slight implementation error for the Comparator. I noticed the error because Java's sorting algorithm (TimSort) threw an IllegalArgumentException. The following change should fix that. Error information following.
This comparator's general contract is broken for the case where both
node1 and node2 have negative source indexes. In that case the returned
results are:
which is not symmetric, as is expected by the Comparator interface.
This is noticed by the TimSort implementation when sorting:
12:59:34.108 SEVERE: [38] util.UtilActivator.uncaughtException().108 An uncaught exception occurred in thread=Thread[AWT-EventQueue-0,6,main] and message was: Comparison method violates its general contract! java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeHi(TimSort.java:868)
at java.util.TimSort.mergeAt(TimSort.java:485)
at java.util.TimSort.mergeCollapse(TimSort.java:410)
at java.util.TimSort.sort(TimSort.java:214)
at java.util.TimSort.sort(TimSort.java:173)
at java.util.Arrays.sort(Arrays.java:659)
at java.util.Collections.sort(Collections.java:217)
at net.java.sip.communicator.impl.gui.main.contactlist.GroupNode$1.run(GroupNode.java:323)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:312)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
This proposition tries to distinguish between two nodes by comparing
their hashCode value. This is kind of a work around, however, since this
is already a special case it should not matter that much. Since the
hashCode is a comparable value we can ensure that we make a consistent,
symmetric choice every time. Thus enforcing the contract.