/* * Copyright 2014 Matti Tahvonen. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.vaadin.viritin; import org.vaadin.viritinv7.FilterableListContainer; import org.vaadin.viritin.testdomain.Person; import com.vaadin.v7.data.Container; import com.vaadin.v7.data.Container.Filter; import com.vaadin.v7.data.Item; import com.vaadin.v7.data.util.BeanItemContainer; import com.vaadin.v7.data.util.filter.Between; import com.vaadin.v7.data.util.filter.Compare; import com.vaadin.v7.data.util.filter.SimpleStringFilter; import java.lang.management.ManagementFactory; import java.lang.management.MemoryUsage; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Random; import junit.framework.Assert; import org.apache.commons.lang3.mutable.MutableBoolean; import org.junit.Test; import static org.junit.Assert.*; import org.junit.Ignore; import static org.junit.matchers.JUnitMatchers.hasItems; /** * */ public class FilterableListContainerTest { Random r = new Random(0); private List<Person> getListOfPersons(int total) { List<Person> l = new ArrayList<>(total); for (int i = 0; i < total; i++) { Person p = new Person(); p.setId(i); p.setFirstName("First" + i); p.setLastName("Lastname" + i); p.setAge(r.nextInt(100)); l.add(p); } return l; } final static int amount = 1000000; //final static int amount = 100000; private final Filter ageFilter = new Between("age", 30, 40); private final List<Person> persons = getListOfPersons(amount); @Test public void clearFilters() { final List<Person> listOfPersons = getListOfPersons(100); FilterableListContainer<Person> container = new FilterableListContainer<>( listOfPersons); container.addContainerFilter(new SimpleStringFilter("firstName", "First1", true, true)); Assert.assertNotSame(listOfPersons.size(), container.size()); container.removeAllContainerFilters(); Assert.assertEquals(listOfPersons.size(), container.size()); container.addContainerFilter(new SimpleStringFilter("firstName", "foobar", true, true)); Assert.assertEquals(0, container.size()); final MutableBoolean fired = new MutableBoolean(false); container.addListener(new Container.ItemSetChangeListener() { @Override public void containerItemSetChange( Container.ItemSetChangeEvent event) { fired.setTrue(); } }); container.removeAllContainerFilters(); Assert.assertTrue(fired.booleanValue()); Assert.assertEquals(listOfPersons.size(), container.size()); } @Test @Ignore("Obsolete with V8") public void testFilterableListContainerPerformance() { System.out.println( "\n Testing FilterableListContainer from Viritin (with Filter)"); long initial = reportMemoryUsage(); long ms = System.currentTimeMillis(); FilterableListContainer<Person> lc = new FilterableListContainer<>( persons); System.out.println( "After creation with " + amount + " beans (took " + (System. currentTimeMillis() - ms) + ")"); long after = reportMemoryUsage(); System.err.println("Delta (bytes)" + (after - initial)); doTests(lc, initial); } @Test @Ignore(value = "we know BeanItemContainer filtering is veeery slow, re-activate to investigate possible enhancements in the core.") public void testFilterStd() { System.out.println( "\n Testing BeanItemContainer from core Vaadin (with Filter)"); long initial = reportMemoryUsage(); long ms = System.currentTimeMillis(); BeanItemContainer<Person> lc = new BeanItemContainer<>( Person.class, persons); System.out.println( "After creation with " + amount + " beans (took " + (System. currentTimeMillis() - ms) + ")"); long after = reportMemoryUsage(); System.err.println("Delta (bytes)" + (after - initial)); doTests(lc, initial); } @Test @Ignore("Obsolete with V8") public void testSortingWhenFiltered() { FilterableListContainer<Person> lc = new FilterableListContainer<>( persons); lc.addContainerFilter(new SimpleStringFilter("firstName", "First10000", true, true)); lc.sort(new Object[]{"firstName"}, new boolean[]{false}); Person p = lc.getIdByIndex(0); Assert.assertEquals("First100009", p.getFirstName()); Assert.assertEquals("First10000", lc.getIdByIndex(10).getFirstName()); lc.sort(new Object[]{"firstName"}, new boolean[]{true}); Assert.assertEquals("First10000", lc.getIdByIndex(0).getFirstName()); Assert.assertEquals("First100009", lc.getIdByIndex(10).getFirstName()); } private void doTests(Container.Filterable lc, long initial) { long ms = System.currentTimeMillis(); for (int i = 0; i < amount; i++) { Item item = lc.getItem(persons.get(i)); String str; str = item.getItemProperty("firstName").toString(); } System.out.println( "After loop (took " + (System.currentTimeMillis() - ms) + ")"); long after = reportMemoryUsage(); System.err.println("Delta (bytes)" + (after - initial)); ms = System.currentTimeMillis(); lc.addContainerFilter(ageFilter); int fSize = lc.size(); System.out.println( "Time to filter " + fSize + " out of " + amount + " elements: " + (System. currentTimeMillis() - ms)); ms = System.currentTimeMillis(); for (Object o : lc.getItemIds()) { String str; Person bean = (Person) o; str = bean.getFirstName(); } System.out.println( "After loop through filtered list (took " + (System. currentTimeMillis() - ms) + ")"); long afterF = reportMemoryUsage(); System.err.println("Delta (bytes)" + (afterF - after)); // call to avoid GC:n the whole container lc.getItemIds(); System.out.println("After GC"); after = reportMemoryUsage(); System.out.println(); System.err.println("Delta (bytes)" + (after - initial)); } private long reportMemoryUsage() { try { System.gc(); Thread.sleep(100); System.gc(); Thread.sleep(100); System.gc(); Thread.sleep(100); System.gc(); } catch (InterruptedException ex) { } MemoryUsage mu = ManagementFactory.getMemoryMXBean(). getHeapMemoryUsage(); System.out.println("Memory used (M):" + mu.getUsed() / 1000000); return ManagementFactory.getMemoryMXBean(). getHeapMemoryUsage().getUsed(); } @Test public void testFirstLast() { FilterableListContainer<Person> lc = new FilterableListContainer<>( new ArrayList<>(Arrays.asList( new Person(0, "1", "1", 1), new Person(0, "2", "2", 2), new Person(0, "3", "3", 3) ))); lc.addContainerFilter(new Compare.Greater("age", 1)); assertNotSame(1, lc.firstItemId().getAge()); lc.addContainerFilter(new Compare.LessOrEqual("age", 1)); try { assertNull(lc.firstItemId()); assertNull(lc.lastItemId()); } catch (ArrayIndexOutOfBoundsException ex) { fail("Exception was thrown: " + ex); } } @Test public void testMultiLevelSort() throws Exception { FilterableListContainer<Person> lc = new FilterableListContainer<>( new ArrayList<>(Arrays.asList( new Person(0, "2", "2", 3), new Person(0, "3", "2", 2), new Person(0, "1", "2", 2), new Person(0, "1", "1", 1), new Person(0, "1", "2", 4) ))); lc.sort(new Object[]{"age", "firstName"}, new boolean[]{true, false}); Collection<Person> itemIds = lc.getItemIds(); assertThat(itemIds, hasItems( new Person(0, "1", "1", 1), new Person(0, "3", "2", 2), new Person(0, "1", "2", 2), new Person(0, "2", "2", 3), new Person(0, "1", "2", 4) )); } }