Community
Participate
Working Groups
The LazySortedCollection appears to be getting into a recursive infinite loop when the data being sorted is not distinct. For example I wrote a test case that sorts 30,000 dates. When all the dates are unique the sort works fine. When all of the dates are one of three values, today, yesterday, or tomorrow then the background sort dies after 30 million comparisons. The following line gets printed to the console repeatedly. at org.eclipse.jface.viewers.deferred.LazySortedCollection.getChildren (LazySortedCollection.java:1450) I ran this this test on a windows XP box running M5 Version: 3.1.0 Build id: I20050219-1500. I also reran the test on M6 Version: 3.1.0 Here is the source code for the test: import java.util.ArrayList; import java.util.Calendar; import java.util.Comparator; import java.util.Date; import java.util.List; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.deferred.AbstractConcurrentModel; import org.eclipse.jface.viewers.deferred.DeferredContentProvider; import org.eclipse.jface.viewers.deferred.IConcurrentModelListener; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; /** * * @author cgustafson * */ public class TestVirtualTable { static int num = 0; public TestVirtualTable(Composite parent){ createContents(parent); } private void createContents(Composite parent){ parent.setLayout(new GridLayout()); Table table = new Table(parent,SWT.VIRTUAL | SWT.V_SCROLL); table.setHeaderVisible(true); table.setLinesVisible(true); GridData gd = new GridData(); gd.grabExcessVerticalSpace = true; gd.verticalAlignment = SWT.FILL; gd.grabExcessHorizontalSpace = true; gd.horizontalAlignment = SWT.FILL; gd.heightHint = 500; table.setLayoutData(gd); TableColumn column = new TableColumn(table, SWT.LEFT); column.setText("Date"); column.setWidth(50); TableViewer tableViewer = new TableViewer(table); tableViewer.setColumnProperties(new String[]{"Date"}); tableViewer.setContentProvider(new TestContentProvider(new TestComparator(true))); tableViewer.setLabelProvider(new TestLabelProvider()); int size = 30000; Date data[] = new Date[size]; Calendar cal = Calendar.getInstance(); Date today = cal.getTime(); cal.add(Calendar.DAY_OF_MONTH,-1); Date yesterday = cal.getTime(); cal.add(Calendar.DAY_OF_MONTH,1); Date tomorrow = cal.getTime(); /* * Fails test case */ for (int i=0;i < size;i++){ data[i] = yesterday; i++; data[i] = today; i++; data[i] = tomorrow; } /* * Passes test case */ /* for (int i=0;i < size;i++){ cal.add(Calendar.DAY_OF_MONTH,1); data[i] = cal.getTime(); } */ TestModel model = new TestModel(); model.set(data); tableViewer.setInput(model); tableViewer.refresh(); } class TestContentProvider extends DeferredContentProvider{ public void dispose() { } public TestContentProvider(Comparator sorter){ super(sorter); } } class TestLabelProvider implements ITableLabelProvider{ private List listeners = new ArrayList(); public String getColumnText(Object element, int columnIndex){ return element.toString(); } public Image getColumnImage(Object element, int columnIndex){ return null; } public void dispose(){ } public void removeListener(ILabelProviderListener listener){ listeners.remove(listener); } public boolean isLabelProperty(Object element, String property) { return false; } public void addListener(ILabelProviderListener listener){ listeners.add(listener); } } class TestComparator implements Comparator{ boolean ascending; TestComparator(boolean ascending){ this.ascending = ascending; num = 0; } public int compare(Object o1, Object o2) { Date lhs = (Date) o1; Date rhs = (Date) o2; num++; if ((num % 1000) == 0){ System.out.println("Make the " + num + " comparison. Comapring " + lhs + " to " + rhs ); } int answer; if (ascending){ answer = lhs.compareTo(rhs); } else{ answer = rhs.compareTo(lhs); } if ((num % 1000) == 0){ System.out.println("Answer = " + answer); } return answer; } } public class TestModel extends AbstractConcurrentModel { private ArrayList data = new ArrayList(); public Object[] getElements() { return data.toArray(); } /** * Sets the contents to the given array of elements * * @param newContents new contents of this set */ public void set(Object[] newContents) { data.clear(); for (int i = 0;i<newContents.length;i++){ data.add(newContents[i]); } IConcurrentModelListener[] listeners = getListeners(); for (int i = 0; i < listeners.length; i++) { IConcurrentModelListener listener = listeners[i]; listener.setContents(getElements()); } } /** * Empties the set */ public void clear() { Object[] removed = getElements(); data.clear(); fireRemove(removed); } public void requestUpdate(IConcurrentModelListener listener) { listener.setContents(getElements()); } public int size(){ return data.size(); } } public static void main(String[] args){ System.out.println("Starting table"); Display display = new Display(); Shell shell = new Shell(display); shell.setText("Testing Stuff"); TestVirtualTable table = new TestVirtualTable(shell); shell.pack(); shell.open(); while (!shell.isDisposed()){ if (!display.readAndDispatch()){ display.sleep(); } } display.dispose(); } }
The tree in LazySortedCollection degenerates and we get O(n) recursive calls. Unfortunately, for 3.2, we probably don't have the resources to work on this. Help in the area of deferred viewers would be very much appreciated.
Hitesh is now responsible for watching bugs in the [Viewers] component area.
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie.