/*******************************************************************************
* Copyright (c) 2006-2013 The RCP Company and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* The RCP Company - initial API and implementation
*******************************************************************************/
package com.rcpcompany.uibindings.extests.trees;
import static com.rcpcompany.test.utils.ui.UITestUtils.*;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import com.rcpcompany.uibindings.IBindingContext;
import com.rcpcompany.uibindings.IColumnBinding;
import com.rcpcompany.uibindings.IManager;
import com.rcpcompany.uibindings.IViewerBinding;
import com.rcpcompany.uibindings.SpecialBinding;
import com.rcpcompany.uibindings.tests.shop.Contact;
import com.rcpcompany.uibindings.tests.shop.Country;
import com.rcpcompany.uibindings.tests.shop.Customer;
import com.rcpcompany.uibindings.tests.shop.Order;
import com.rcpcompany.uibindings.tests.shop.Shop;
import com.rcpcompany.uibindings.tests.shop.ShopFactory;
import com.rcpcompany.uibindings.tests.shop.ShopPackage;
import com.rcpcompany.uibindings.tests.utils.BaseUIBTestUtils;
import com.rcpcompany.uibindings.tests.utils.views.UIBTestView;
import com.rcpcompany.uibindings.utils.IBindingContextSelectionProvider;
import com.rcpcompany.uibindings.utils.IDnDSupport;
import com.rcpcompany.utils.logging.LogUtils;
/**
* Performance tests for trees using {@link TreeViewer#expandAll()}.
*
* @author Tonny Madsen, The RCP Company
*/
@RunWith(Parameterized.class)
public class TreePerformanceTest {
private final int mySizeFactor;
@Parameters
public static List<Object[]> data() {
return Arrays.asList(new Object[][] {
// sizeFactor
{ 1 }, { 10 },
{ 50 },
// { 100 },
// { 200 },
//
// { 500 },
//
// { 1000 },
});
}
public TreePerformanceTest(int sizeFactor) {
mySizeFactor = sizeFactor;
}
private Shop myShop;
private UIBTestView myView;
private IBindingContext myContext;
private Tree myTree;
private TreeColumn myTreeColumn;
private IViewerBinding myTreeBinding;
private IColumnBinding myTreeColumnBinding;
private int myNoShopObjs;
@Before
public void before() {
BaseUIBTestUtils.resetAll();
IManager.Factory.getManager().setEditCellSingleClick(false);
try {
myShop = createModel();
} catch (final OutOfMemoryError ex) {
fail("factor " + mySizeFactor + ": " + ex.getMessage());
}
createView();
myView.getSite().getPage().activate(myView);
}
private Shop createModel() {
final Runtime runtime = Runtime.getRuntime();
myNoShopObjs = 0;
runtime.gc();
final long startMemory = runtime.totalMemory() - runtime.freeMemory();
final long startTime = System.currentTimeMillis();
final Shop shop = ShopFactory.eINSTANCE.createShop();
myNoShopObjs++;
shop.setName("my shop");
final Country country = ShopFactory.eINSTANCE.createCountry();
myNoShopObjs++;
country.setName("name");
country.setName("abbreviation");
country.setShop(shop);
for (int i = 0; i < mySizeFactor; i++) {
final Country c = ShopFactory.eINSTANCE.createCountry();
myNoShopObjs++;
c.setName("name " + i);
c.setAbbreviation("abbreviation " + i);
c.setShop(shop);
}
for (int i = 0; i < mySizeFactor; i++) {
final Contact c = ShopFactory.eINSTANCE.createContact();
myNoShopObjs++;
c.setName("name " + i);
c.setCountry(country);
c.setShop(shop);
final Customer cust = ShopFactory.eINSTANCE.createCustomer();
myNoShopObjs++;
cust.setContact(c);
cust.setShop(shop);
for (int j = 0; j < mySizeFactor; j++) {
final Order o = ShopFactory.eINSTANCE.createOrder();
myNoShopObjs++;
o.setCustomer(cust);
o.setDiscount(1000f);
}
}
final long endTime = System.currentTimeMillis();
runtime.gc();
final long endMemory = runtime.totalMemory() - runtime.freeMemory();
final long deltaTime = endTime - startTime;
final long deltaMemory = endMemory - startMemory;
LogUtils.debug(this, "model (" + mySizeFactor + "): " + myNoShopObjs + " objects " + deltaTime + " ms "
+ deltaMemory + " bytes (= " + (1f * deltaTime / myNoShopObjs) + " ms/obj) "
+ (deltaMemory / myNoShopObjs) + " bytes/obj)");
return shop;
}
/**
* Creates the view - pretty real-life
*/
public void createView() {
myView = BaseUIBTestUtils.createUIBTestView(this);
myContext = IBindingContext.Factory.createContext(myView.getBody());
myTree = new Tree(myView.getBody(), SWT.SINGLE | SWT.FULL_SELECTION);
myTree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
myTree.setHeaderVisible(true);
myTreeColumn = new TreeColumn(myTree, SWT.LEAD);
myTreeColumn.setWidth(300);
// TODO: use listener to make this column 100%
final IObservableList list = WritableList.withElementType(ShopPackage.Literals.SHOP);
list.add(myShop);
myTreeBinding = myContext.addViewer().viewer(myTree).model(list);
myTreeColumnBinding = myTreeBinding.addColumn().column(myTreeColumn).model(SpecialBinding.TREE_ITEM);
myContext.finish();
IBindingContextSelectionProvider.Factory.adapt(myContext, myView.getSite());
IDnDSupport.Factory.installOn(myContext);
myView.getBody().layout();
}
@After
public void disposeView() {
if (myView != null) {
myView.getSite().getPage().hideView(myView);
}
}
@Test
public void testPerformance() {
final TreeViewer viewer = (TreeViewer) myTreeBinding.getViewer();
yield();
final long startTime = System.currentTimeMillis();
/*
* Make sure the tree is properly shown
*/
viewer.expandAll();
yield();
final long endTime = System.currentTimeMillis();
// sleep(2000);
LogUtils.debug(this, "expand (" + mySizeFactor + "): " + (endTime - startTime) + " (= "
+ (1f * (endTime - startTime) / myNoShopObjs) + " ms/obj)");
}
}