Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8301761: The sorting of the SortedList can become invalid #1519

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ public final class SortedList<E> extends TransformationList<E, E>{

private final SortHelper helper = new SortHelper();

private final Element<E> tempElement = new Element<>(null, -1);


/**
* Creates a new SortedList wrapped around the source list.
Expand Down Expand Up @@ -298,7 +296,12 @@ public ElementComparator(Comparator<? super E> comparator) {

@Override
public int compare(Element<E> o1, Element<E> o2) {
return comparator.compare(o1.e, o2.e);
int result = comparator.compare(o1.e, o2.e);
if (result != 0) {
return result;
} else {
return Integer.compare(o1.index, o2.index);
}
}

}
Expand All @@ -325,24 +328,23 @@ private void updateIndices(int from, int viewFrom, int difference) {
}
}

private int findPosition(E e) {
private int findPosition(Element<E> element) {
if (sorted.length == 0) {
return 0;
}
tempElement.e = e;
int pos = Arrays.binarySearch(sorted, 0, size, tempElement, elementComparator);
return pos;
return Arrays.binarySearch(sorted, 0, size, element, elementComparator);
}

private void insertToMapping(E e, int idx) {
int pos = findPosition(e);
Element<E> newElement = new Element<>(e, idx);
int pos = findPosition(newElement);
if (pos < 0) {
pos = ~pos;
}
ensureSize(size + 1);
updateIndices(idx, pos, 1);
System.arraycopy(sorted, pos, sorted, pos + 1, size - pos);
sorted[pos] = new Element<>(e, idx);
sorted[pos] = newElement;
System.arraycopy(perm, idx, perm, idx + 1, size - idx);
perm[idx] = pos;
++size;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -609,4 +609,26 @@ public void testGetViewIndexOutOfBounds() {
assertThrows(IndexOutOfBoundsException.class, () -> sortedList.getViewIndex(sortedList.size()));
assertDoesNotThrow(() -> sortedList.getViewIndex(sortedList.size() - 1));
}

@Test
public void testSortingMaintainsInsertionOrderForEqualElements() {
ObservableList<Person> list = FXCollections.observableArrayList();

Person p1 = new Person("a");
Person p2 = new Person("b");
Person p3 = new Person("a");

list.addAll(p2, p1);
// After adding p2 and p1, list= [p2, p1], sorted list= [p1, p2]
SortedList<Person> sorted = new SortedList<>(list, Comparator.comparing(p -> p.name.get()));

list.add(p3);
// After adding p3, list= [p2, p1, p3]
// p1 and p3 have equal names, but p3 was added after p1, so p3 should come after p1 in the sorted list
// Expected sorted list= [p1, p3, p2]

assertSame(sorted.get(0), p1);
assertSame(sorted.get(1), p3);
assertSame(sorted.get(2), p2);
}
}