FIXED - bug 332367: [DataBinding] Performance of (WritableList|SimplePropertyObservableMap)#clear()
https://bugs.eclipse.org/bugs/show_bug.cgi?id=332367
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/WritableList.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/WritableList.java
index 8302f6e..7d447a5 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/WritableList.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/databinding/observable/list/WritableList.java
@@ -12,6 +12,7 @@
* Brad Reynolds - bug 147515
* Sebastian Fuchs <spacehorst@gmail.com> - bug 243848
* Matthew Hall - bugs 208858, 213145, 243848
+ * Ovidio Mallo - bug 332367
*******************************************************************************/
package org.eclipse.core.databinding.observable.list;
@@ -19,6 +20,7 @@
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
+import java.util.ListIterator;
import org.eclipse.core.databinding.observable.Diffs;
import org.eclipse.core.databinding.observable.Realm;
@@ -125,9 +127,9 @@
public Object set(int index, Object element) {
checkRealm();
Object oldElement = wrappedList.set(index, element);
- fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(index,
- false, oldElement), Diffs.createListDiffEntry(index, true,
- element)));
+ fireListChange(Diffs.createListDiff(
+ Diffs.createListDiffEntry(index, false, oldElement),
+ Diffs.createListDiffEntry(index, true, element)));
return oldElement;
}
@@ -147,9 +149,9 @@
return wrappedList.get(oldIndex);
Object element = wrappedList.remove(oldIndex);
wrappedList.add(newIndex, element);
- fireListChange(Diffs.createListDiff(Diffs.createListDiffEntry(oldIndex,
- false, element), Diffs.createListDiffEntry(newIndex, true,
- element)));
+ fireListChange(Diffs.createListDiff(
+ Diffs.createListDiffEntry(oldIndex, false, element),
+ Diffs.createListDiffEntry(newIndex, true, element)));
return element;
}
@@ -259,15 +261,19 @@
public void clear() {
checkRealm();
- List entries = new ArrayList();
- for (Iterator it = wrappedList.iterator(); it.hasNext();) {
- Object element = it.next();
- // always report 0 as the remove index
- entries.add(Diffs.createListDiffEntry(0, false, element));
- it.remove();
+ // We remove the elements from back to front which is typically much
+ // faster on common list implementations like ArrayList.
+ ListDiffEntry[] entries = new ListDiffEntry[wrappedList.size()];
+ int entryIndex = 0;
+ for (ListIterator it = wrappedList.listIterator(wrappedList.size()); it
+ .hasPrevious();) {
+ int elementIndex = it.previousIndex();
+ Object element = it.previous();
+ entries[entryIndex++] = Diffs.createListDiffEntry(elementIndex,
+ false, element);
}
- fireListChange(Diffs.createListDiff((ListDiffEntry[]) entries
- .toArray(new ListDiffEntry[entries.size()])));
+ wrappedList.clear();
+ fireListChange(Diffs.createListDiff(entries));
}
/**
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/map/SimplePropertyObservableMap.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/map/SimplePropertyObservableMap.java
index ee1e56e..df7fd0d 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/map/SimplePropertyObservableMap.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/map/SimplePropertyObservableMap.java
@@ -8,6 +8,7 @@
* Contributors:
* Matthew Hall - initial API and implementation (bug 194734)
* Matthew Hall - bugs 265561, 262287, 268203, 268688, 301774, 303847
+ * Ovidio Mallo - bug 332367
******************************************************************************/
package org.eclipse.core.internal.databinding.property.map;
@@ -184,8 +185,8 @@
getterCalled();
checkForComodification();
- MapDiff diff = Diffs.createMapDiffSingleRemove(last.getKey(), last
- .getValue());
+ MapDiff diff = Diffs.createMapDiffSingleRemove(last.getKey(),
+ last.getValue());
updateMap(map, diff);
iterator.remove(); // stay in sync
@@ -281,6 +282,17 @@
return oldValue;
}
+ public void clear() {
+ getterCalled();
+
+ Map map = getMap();
+ if (map.isEmpty())
+ return;
+
+ MapDiff diff = Diffs.createMapDiffRemoveAll(new HashMap(map));
+ updateMap(map, diff);
+ }
+
public Collection values() {
getterCalled();
// AbstractMap depends on entrySet() to fulfil values() API, so all