Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[platform-ui-dev] LazySortedCollection recursive infinite loop

Hello,

 

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)


 

Assuming that this is a bug that can be fixed I guess
the next question would be, is this the correct
approach to sort large amounts of data that could
potentially have a very small set of distinct values?
We have a table that could potentially display up to
50,000 records. Most of the columns on this table have
fairly distinct data that would result in a fairly
balanced tree. But, we do have a few flags (either
there on or off) that I suspect would slow down this
algorithm significantly.

 

Thanks

Chad

 

P.S- 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();

            }

} 

 

 


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 


Back to the top