summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/vaadin/data/util/AbstractInMemoryContainer.java2
-rw-r--r--src/com/vaadin/data/util/IndexedContainer.java18
-rw-r--r--tests/src/com/vaadin/tests/server/container/PerformanceTestIndexedContainer.java117
3 files changed, 133 insertions, 4 deletions
diff --git a/src/com/vaadin/data/util/AbstractInMemoryContainer.java b/src/com/vaadin/data/util/AbstractInMemoryContainer.java
index 3a9a0a8987..3a48d9e0de 100644
--- a/src/com/vaadin/data/util/AbstractInMemoryContainer.java
+++ b/src/com/vaadin/data/util/AbstractInMemoryContainer.java
@@ -722,7 +722,7 @@ public abstract class AbstractInMemoryContainer<ITEMIDTYPE, PROPERTYIDCLASS, ITE
getAllItemIds().indexOf(previousItemId) + 1, newItemId,
item);
}
- if (newItem != null) {
+ if (newItem != null && filter) {
// TODO filter only this item, use fireItemAdded()
filterAll();
if (!isFiltered()) {
diff --git a/src/com/vaadin/data/util/IndexedContainer.java b/src/com/vaadin/data/util/IndexedContainer.java
index 7fbb1e9128..2f45def4f1 100644
--- a/src/com/vaadin/data/util/IndexedContainer.java
+++ b/src/com/vaadin/data/util/IndexedContainer.java
@@ -106,8 +106,11 @@ public class IndexedContainer extends
this();
if (items != null) {
for (final Iterator<?> i = itemIds.iterator(); i.hasNext();) {
- this.addItem(i.next());
+ Object itemId = i.next();
+ internalAddItemAtEnd(itemId, new IndexedContainerItem(itemId),
+ false);
}
+ filterAll();
}
}
@@ -246,8 +249,17 @@ public class IndexedContainer extends
*/
@Override
public Item addItem(Object itemId) {
- return internalAddItemAtEnd(itemId, new IndexedContainerItem(itemId),
- true);
+ Item item = internalAddItemAtEnd(itemId, new IndexedContainerItem(
+ itemId), false);
+ if (!isFiltered()) {
+ // always the last item
+ fireItemAdded(size() - 1, itemId, item);
+ } else if (passesFilters(itemId)) {
+ getFilteredItemIds().add(itemId);
+ // always the last item
+ fireItemAdded(size() - 1, itemId, item);
+ }
+ return item;
}
/**
diff --git a/tests/src/com/vaadin/tests/server/container/PerformanceTestIndexedContainer.java b/tests/src/com/vaadin/tests/server/container/PerformanceTestIndexedContainer.java
new file mode 100644
index 0000000000..62e6d88e72
--- /dev/null
+++ b/tests/src/com/vaadin/tests/server/container/PerformanceTestIndexedContainer.java
@@ -0,0 +1,117 @@
+package com.vaadin.tests.server.container;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import com.vaadin.data.util.IndexedContainer;
+
+public class PerformanceTestIndexedContainer extends TestCase {
+
+ private static final int REPEATS = 10;
+ private final static int ITEMS = 50000;
+ private static final long ADD_ITEM_FAIL_THRESHOLD = 200;
+ // TODO should improve performance of these methods
+ private static final long ADD_ITEM_AT_FAIL_THRESHOLD = 5000;
+ private static final long ADD_ITEM_AFTER_FAIL_THRESHOLD = 5000;
+ private static final long ADD_ITEM_AFTER_LAST_FAIL_THRESHOLD = 5000;
+ private static final long ADD_ITEMS_CONSTRUCTOR_FAIL_THRESHOLD = 200;
+
+ public void testAddItemPerformance() {
+ Collection<Long> times = new ArrayList<Long>();
+ for (int j = 0; j < REPEATS; ++j) {
+ IndexedContainer c = new IndexedContainer();
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < ITEMS; i++) {
+ c.addItem();
+ }
+ times.add(System.currentTimeMillis() - start);
+ }
+ checkMedian(ITEMS, times, "IndexedContainer.addItem()",
+ ADD_ITEM_FAIL_THRESHOLD);
+ }
+
+ public void testAddItemAtPerformance() {
+ Collection<Long> times = new ArrayList<Long>();
+ for (int j = 0; j < REPEATS; ++j) {
+ IndexedContainer c = new IndexedContainer();
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < ITEMS; i++) {
+ c.addItemAt(0);
+ }
+ times.add(System.currentTimeMillis() - start);
+ }
+ checkMedian(ITEMS, times, "IndexedContainer.addItemAt()",
+ ADD_ITEM_AT_FAIL_THRESHOLD);
+ }
+
+ public void testAddItemAfterPerformance() {
+ Object initialId = "Item0";
+ Collection<Long> times = new ArrayList<Long>();
+ for (int j = 0; j < REPEATS; ++j) {
+ IndexedContainer c = new IndexedContainer();
+ c.addItem(initialId);
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < ITEMS; i++) {
+ c.addItemAfter(initialId);
+ }
+ times.add(System.currentTimeMillis() - start);
+ }
+ checkMedian(ITEMS, times, "IndexedContainer.addItemAfter()",
+ ADD_ITEM_AFTER_FAIL_THRESHOLD);
+ }
+
+ public void testAddItemAfterLastPerformance() {
+ // TODO running with less items because slow otherwise
+ Collection<Long> times = new ArrayList<Long>();
+ for (int j = 0; j < REPEATS; ++j) {
+ IndexedContainer c = new IndexedContainer();
+ c.addItem();
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < ITEMS / 3; i++) {
+ c.addItemAfter(c.lastItemId());
+ }
+ times.add(System.currentTimeMillis() - start);
+ }
+ checkMedian(ITEMS / 3, times, "IndexedContainer.addItemAfter(lastId)",
+ ADD_ITEM_AFTER_LAST_FAIL_THRESHOLD);
+ }
+
+ public void testAddItemsConstructorPerformance() {
+ Collection<Object> items = new ArrayList<Object>(50000);
+ for (int i = 0; i < ITEMS; ++i) {
+ items.add(new Object());
+ }
+
+ SortedSet<Long> times = new TreeSet<Long>();
+ for (int j = 0; j < REPEATS; ++j) {
+ long start = System.currentTimeMillis();
+ new IndexedContainer(items);
+ times.add(System.currentTimeMillis() - start);
+ }
+ checkMedian(ITEMS, times, "IndexedContainer(Collection)",
+ ADD_ITEMS_CONSTRUCTOR_FAIL_THRESHOLD);
+ }
+
+ private void checkMedian(int items, Collection<Long> times,
+ String methodName, long threshold) {
+ long median = median(times);
+ System.out.println(methodName + " timings (ms) for " + items
+ + " items: " + times);
+ Assert.assertTrue(methodName + " too slow, median time " + median
+ + "ms for " + items + " items", median <= threshold);
+ }
+
+ private Long median(Collection<Long> times) {
+ ArrayList<Long> list = new ArrayList<Long>(times);
+ Collections.sort(list);
+ // not exact median in some cases, but good enough
+ return list.get(list.size() / 2);
+ }
+
+}