FIXED - bug 303847: [Databinding] MapSimpleValueObservableMap#get(Object) is not scaling very well
https://bugs.eclipse.org/bugs/show_bug.cgi?id=303847
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentityMap.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentityMap.java
index 4fdf296..48f055a 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentityMap.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentityMap.java
@@ -9,7 +9,7 @@
* Matthew Hall - initial API and implementation (bug 215531)
* Matthew Hall - bug 228125
* (through ViewerElementMap.java)
- * Matthew Hall - bug 262269
+ * Matthew Hall - bugs 262269, 303847
******************************************************************************/
package org.eclipse.core.internal.databinding.identity;
@@ -63,7 +63,7 @@
}
public boolean containsKey(Object key) {
- return wrappedMap.containsKey(new IdentityWrapper(key));
+ return wrappedMap.containsKey(IdentityWrapper.wrap(key));
}
public boolean containsValue(Object value) {
@@ -152,8 +152,8 @@
public boolean remove(Object o) {
final Map.Entry unwrappedEntry = (Map.Entry) o;
- final IdentityWrapper wrappedKey = new IdentityWrapper(
- unwrappedEntry.getKey());
+ final IdentityWrapper wrappedKey = IdentityWrapper
+ .wrap(unwrappedEntry.getKey());
Map.Entry wrappedEntry = new Map.Entry() {
public Object getKey() {
return wrappedKey;
@@ -247,7 +247,7 @@
}
public Object get(Object key) {
- return wrappedMap.get(new IdentityWrapper(key));
+ return wrappedMap.get(IdentityWrapper.wrap(key));
}
public boolean isEmpty() {
@@ -270,12 +270,12 @@
}
public boolean contains(Object o) {
- return wrappedKeySet.contains(new IdentityWrapper(o));
+ return wrappedKeySet.contains(IdentityWrapper.wrap(o));
}
public boolean containsAll(Collection c) {
for (Iterator iterator = c.iterator(); iterator.hasNext();)
- if (!wrappedKeySet.contains(new IdentityWrapper(iterator
+ if (!wrappedKeySet.contains(IdentityWrapper.wrap(iterator
.next())))
return false;
return true;
@@ -304,14 +304,14 @@
}
public boolean remove(Object o) {
- return wrappedKeySet.remove(new IdentityWrapper(o));
+ return wrappedKeySet.remove(IdentityWrapper.wrap(o));
}
public boolean removeAll(Collection c) {
boolean changed = false;
for (Iterator iterator = c.iterator(); iterator.hasNext();)
- changed |= wrappedKeySet.remove(new IdentityWrapper(
- iterator.next()));
+ changed |= wrappedKeySet.remove(IdentityWrapper
+ .wrap(iterator.next()));
return changed;
}
@@ -368,20 +368,20 @@
}
public Object put(Object key, Object value) {
- return wrappedMap.put(new IdentityWrapper(key), value);
+ return wrappedMap.put(IdentityWrapper.wrap(key), value);
}
public void putAll(Map other) {
for (Iterator iterator = other.entrySet().iterator(); iterator
.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
- wrappedMap.put(new IdentityWrapper(entry.getKey()), entry
+ wrappedMap.put(IdentityWrapper.wrap(entry.getKey()), entry
.getValue());
}
}
public Object remove(Object key) {
- return wrappedMap.remove(new IdentityWrapper(key));
+ return wrappedMap.remove(IdentityWrapper.wrap(key));
}
public int size() {
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentitySet.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentitySet.java
index f914438..04e61a1 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentitySet.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentitySet.java
@@ -9,7 +9,7 @@
* Matthew Hall - initial API and implementation (bug 215531)
* Matthew Hall - bug 124684
* (through ViewerElementSet.java)
- * Matthew Hall - bug 262269
+ * Matthew Hall - bugs 262269, 303847
******************************************************************************/
package org.eclipse.core.internal.databinding.identity;
@@ -54,13 +54,13 @@
}
public boolean add(Object o) {
- return wrappedSet.add(new IdentityWrapper(o));
+ return wrappedSet.add(IdentityWrapper.wrap(o));
}
public boolean addAll(Collection c) {
boolean changed = false;
for (Iterator iterator = c.iterator(); iterator.hasNext();)
- changed |= wrappedSet.add(new IdentityWrapper(iterator.next()));
+ changed |= wrappedSet.add(IdentityWrapper.wrap(iterator.next()));
return changed;
}
@@ -69,12 +69,12 @@
}
public boolean contains(Object o) {
- return wrappedSet.contains(new IdentityWrapper(o));
+ return wrappedSet.contains(IdentityWrapper.wrap(o));
}
public boolean containsAll(Collection c) {
for (Iterator iterator = c.iterator(); iterator.hasNext();)
- if (!wrappedSet.contains(new IdentityWrapper(iterator.next())))
+ if (!wrappedSet.contains(IdentityWrapper.wrap(iterator.next())))
return false;
return true;
}
@@ -101,7 +101,7 @@
}
public boolean remove(Object o) {
- return wrappedSet.remove(new IdentityWrapper(o));
+ return wrappedSet.remove(IdentityWrapper.wrap(o));
}
public boolean removeAll(Collection c) {
diff --git a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentityWrapper.java b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentityWrapper.java
index c3cb5f9..508ccec 100644
--- a/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentityWrapper.java
+++ b/bundles/org.eclipse.core.databinding.observable/src/org/eclipse/core/internal/databinding/identity/IdentityWrapper.java
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Daniel Kruegler - bug 137435
+ * Matthew Hall - bug 303847
******************************************************************************/
package org.eclipse.core.internal.databinding.identity;
@@ -21,15 +22,27 @@
*
*/
public class IdentityWrapper {
+ private static final IdentityWrapper NULL_WRAPPER = new IdentityWrapper(
+ null);
+
+ /**
+ * @param o
+ * the object to wrap
+ * @return an IdentityWrapper wrapping the specified object
+ */
+ public static IdentityWrapper wrap(Object o) {
+ return o == null ? NULL_WRAPPER : new IdentityWrapper(o);
+ }
+
final Object o;
/**
* @param o
*/
- public IdentityWrapper(Object o) {
+ private IdentityWrapper(Object o) {
this.o = o;
}
-
+
/**
* @return the unwrapped object
*/
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 290702d..43fb647 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
@@ -7,7 +7,7 @@
*
* Contributors:
* Matthew Hall - initial API and implementation (bug 194734)
- * Matthew Hall - bugs 265561, 262287, 268203, 268688, 301774
+ * Matthew Hall - bugs 265561, 262287, 268203, 268688, 301774, 303847
******************************************************************************/
package org.eclipse.core.internal.databinding.property.map;
@@ -209,6 +209,18 @@
return super.keySet();
}
+ public boolean containsKey(Object key) {
+ getterCalled();
+
+ return getMap().containsKey(key);
+ }
+
+ public Object get(Object key) {
+ getterCalled();
+
+ return getMap().get(key);
+ }
+
public Object put(Object key, Object value) {
checkRealm();
diff --git a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/MapSimpleValueObservableMap.java b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/MapSimpleValueObservableMap.java
index 4708e01..a9a9394 100644
--- a/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/MapSimpleValueObservableMap.java
+++ b/bundles/org.eclipse.core.databinding.property/src/org/eclipse/core/internal/databinding/property/value/MapSimpleValueObservableMap.java
@@ -7,7 +7,7 @@
*
* Contributors:
* Matthew Hall - initial API and implementation (bug 194734)
- * Matthew Hall - bugs 262269, 265561, 262287, 268688, 278550
+ * Matthew Hall - bugs 262269, 265561, 262287, 268688, 278550, 303847
* Ovidio Mallo - bugs 299619, 301370
******************************************************************************/
@@ -310,6 +310,18 @@
}
}
+ public boolean containsKey(Object key) {
+ getterCalled();
+
+ return masterMap.containsKey(key);
+ }
+
+ public Object get(Object key) {
+ getterCalled();
+
+ return detailProperty.getValue(masterMap.get(key));
+ }
+
public Object put(Object key, Object value) {
if (!masterMap.containsKey(key))
return null;
@@ -320,6 +332,17 @@
return oldValue;
}
+ public Object remove(Object key) {
+ checkRealm();
+
+ Object masterValue = masterMap.get(key);
+ Object oldValue = detailProperty.getValue(masterValue);
+
+ masterMap.remove(key);
+
+ return oldValue;
+ }
+
private void notifyIfChanged(Object masterValue) {
if (cachedValues != null) {
final Set keys = keysFor(masterValue);
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/IdentityMap.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/IdentityMap.java
index 8f464bf..b8a1510 100644
--- a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/IdentityMap.java
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/IdentityMap.java
@@ -9,7 +9,7 @@
* Matthew Hall - initial API and implementation (bug 215531)
* Matthew Hall - bug 228125
* (through ViewerElementMap.java)
- * Matthew Hall - bug 262269
+ * Matthew Hall - bugs 262269, 303847
******************************************************************************/
package org.eclipse.core.internal.databinding;
@@ -62,7 +62,7 @@
}
public boolean containsKey(Object key) {
- return wrappedMap.containsKey(new IdentityWrapper(key));
+ return wrappedMap.containsKey(IdentityWrapper.wrap(key));
}
public boolean containsValue(Object value) {
@@ -151,8 +151,8 @@
public boolean remove(Object o) {
final Map.Entry unwrappedEntry = (Map.Entry) o;
- final IdentityWrapper wrappedKey = new IdentityWrapper(
- unwrappedEntry.getKey());
+ final IdentityWrapper wrappedKey = IdentityWrapper
+ .wrap(unwrappedEntry.getKey());
Map.Entry wrappedEntry = new Map.Entry() {
public Object getKey() {
return wrappedKey;
@@ -246,7 +246,7 @@
}
public Object get(Object key) {
- return wrappedMap.get(new IdentityWrapper(key));
+ return wrappedMap.get(IdentityWrapper.wrap(key));
}
public boolean isEmpty() {
@@ -269,12 +269,12 @@
}
public boolean contains(Object o) {
- return wrappedKeySet.contains(new IdentityWrapper(o));
+ return wrappedKeySet.contains(IdentityWrapper.wrap(o));
}
public boolean containsAll(Collection c) {
for (Iterator iterator = c.iterator(); iterator.hasNext();)
- if (!wrappedKeySet.contains(new IdentityWrapper(iterator
+ if (!wrappedKeySet.contains(IdentityWrapper.wrap(iterator
.next())))
return false;
return true;
@@ -303,14 +303,14 @@
}
public boolean remove(Object o) {
- return wrappedKeySet.remove(new IdentityWrapper(o));
+ return wrappedKeySet.remove(IdentityWrapper.wrap(o));
}
public boolean removeAll(Collection c) {
boolean changed = false;
for (Iterator iterator = c.iterator(); iterator.hasNext();)
- changed |= wrappedKeySet.remove(new IdentityWrapper(
- iterator.next()));
+ changed |= wrappedKeySet.remove(IdentityWrapper
+ .wrap(iterator.next()));
return changed;
}
@@ -367,20 +367,20 @@
}
public Object put(Object key, Object value) {
- return wrappedMap.put(new IdentityWrapper(key), value);
+ return wrappedMap.put(IdentityWrapper.wrap(key), value);
}
public void putAll(Map other) {
for (Iterator iterator = other.entrySet().iterator(); iterator
.hasNext();) {
Map.Entry entry = (Map.Entry) iterator.next();
- wrappedMap.put(new IdentityWrapper(entry.getKey()), entry
+ wrappedMap.put(IdentityWrapper.wrap(entry.getKey()), entry
.getValue());
}
}
public Object remove(Object key) {
- return wrappedMap.remove(new IdentityWrapper(key));
+ return wrappedMap.remove(IdentityWrapper.wrap(key));
}
public int size() {
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/IdentitySet.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/IdentitySet.java
index 4aa7713..4fc3704 100644
--- a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/IdentitySet.java
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/IdentitySet.java
@@ -9,7 +9,7 @@
* Matthew Hall - initial API and implementation (bug 215531)
* Matthew Hall - bug 124684
* (through ViewerElementSet.java)
- * Matthew Hall - bug 262269
+ * Matthew Hall - bugs 262269, 303847
******************************************************************************/
package org.eclipse.core.internal.databinding;
@@ -54,13 +54,13 @@
}
public boolean add(Object o) {
- return wrappedSet.add(new IdentityWrapper(o));
+ return wrappedSet.add(IdentityWrapper.wrap(o));
}
public boolean addAll(Collection c) {
boolean changed = false;
for (Iterator iterator = c.iterator(); iterator.hasNext();)
- changed |= wrappedSet.add(new IdentityWrapper(iterator.next()));
+ changed |= wrappedSet.add(IdentityWrapper.wrap(iterator.next()));
return changed;
}
@@ -69,12 +69,12 @@
}
public boolean contains(Object o) {
- return wrappedSet.contains(new IdentityWrapper(o));
+ return wrappedSet.contains(IdentityWrapper.wrap(o));
}
public boolean containsAll(Collection c) {
for (Iterator iterator = c.iterator(); iterator.hasNext();)
- if (!wrappedSet.contains(new IdentityWrapper(iterator.next())))
+ if (!wrappedSet.contains(IdentityWrapper.wrap(iterator.next())))
return false;
return true;
}
@@ -101,7 +101,7 @@
}
public boolean remove(Object o) {
- return wrappedSet.remove(new IdentityWrapper(o));
+ return wrappedSet.remove(IdentityWrapper.wrap(o));
}
public boolean removeAll(Collection c) {
diff --git a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/IdentityWrapper.java b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/IdentityWrapper.java
index 978c996..7122a91 100644
--- a/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/IdentityWrapper.java
+++ b/bundles/org.eclipse.core.databinding/src/org/eclipse/core/internal/databinding/IdentityWrapper.java
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Daniel Kruegler - bug 137435
+ * Matthew Hall - bug 303847
******************************************************************************/
package org.eclipse.core.internal.databinding;
@@ -21,15 +22,28 @@
*
*/
public class IdentityWrapper {
+
+ private static final IdentityWrapper NULL_WRAPPER = new IdentityWrapper(
+ null);
+
+ /**
+ * @param obj
+ * the object to wrap
+ * @return an IdentityWrapper wrapping the specified object
+ */
+ public static IdentityWrapper wrap(Object obj) {
+ return obj == null ? NULL_WRAPPER : new IdentityWrapper(obj);
+ }
+
final Object o;
/**
* @param o
*/
- public IdentityWrapper(Object o) {
+ private IdentityWrapper(Object o) {
this.o = o;
}
-
+
/**
* @return the unwrapped object
*/