Author: davsclaus
Date: Wed Jan 5 15:32:33 2011
New Revision: 1055489
URL: http://svn.apache.org/viewvc?rev=1055489&view=rev
Log:
CAMEL-3500: Headers on message is now using string interning for Camel keys, to
reduce memory consumption.
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/util/CaseInsensitiveMap.java
camel/trunk/camel-core/src/test/java/org/apache/camel/util/CaseInsensitiveMapTest.java
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/util/CaseInsensitiveMap.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/CaseInsensitiveMap.java?rev=1055489&r1=1055488&r2=1055489&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/util/CaseInsensitiveMap.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/util/CaseInsensitiveMap.java
Wed Jan 5 15:32:33 2011
@@ -65,7 +65,7 @@ public class CaseInsensitiveMap extends
@Override
public Object get(Object key) {
- String s = key.toString().toLowerCase();
+ String s = assembleKey(key);
Object answer = super.get(s);
if (answer == null) {
// fallback to lookup by original key
@@ -79,7 +79,7 @@ public class CaseInsensitiveMap extends
public synchronized Object put(String key, Object value) {
// invalidate views as we mutate
entrySetView = null;
- String s = key.toLowerCase();
+ String s = assembleKey(key);
originalKeys.put(s, key);
return super.put(s, value);
}
@@ -101,7 +101,7 @@ public class CaseInsensitiveMap extends
// invalidate views as we mutate
entrySetView = null;
- String s = key.toString().toLowerCase();
+ String s = assembleKey(key);
originalKeys.remove(s);
return super.remove(s);
}
@@ -120,10 +120,20 @@ public class CaseInsensitiveMap extends
return false;
}
- String s = key.toString().toLowerCase();
+ String s = assembleKey(key);
return super.containsKey(s);
}
+ private static String assembleKey(Object key) {
+ String s = key.toString().toLowerCase();
+ if (s.startsWith("camel")) {
+ // use intern String for headers which is Camel* headers
+ // this reduces memory allocations needed for those common headers
+ s = s.intern();
+ }
+ return s;
+ }
+
@Override
public synchronized Set<Map.Entry<String, Object>> entrySet() {
if (entrySetView == null) {
Modified:
camel/trunk/camel-core/src/test/java/org/apache/camel/util/CaseInsensitiveMapTest.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/util/CaseInsensitiveMapTest.java?rev=1055489&r1=1055488&r2=1055489&view=diff
==============================================================================
---
camel/trunk/camel-core/src/test/java/org/apache/camel/util/CaseInsensitiveMapTest.java
(original)
+++
camel/trunk/camel-core/src/test/java/org/apache/camel/util/CaseInsensitiveMapTest.java
Wed Jan 5 15:32:33 2011
@@ -20,9 +20,11 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
@@ -476,4 +478,38 @@ public class CaseInsensitiveMapTest exte
assertEquals("cheese", map.get("cAKe"));
}
+ public void testCopyMapWithCamelHeadersTest() throws Exception {
+ Map<String, Object> map = new CaseInsensitiveMap();
+ map.put("CamelA", "A");
+ map.put("CamelB", "B");
+ map.put("CamelC", "C");
+
+ // retain maps so we can profile that the map doesn't duplicate
+ // camel keys as they are intern
+ List<Map> maps = new ArrayList<Map>();
+
+ for (int i = 0; i < 10000; i++) {
+ Map<String, Object> copy = new CaseInsensitiveMap(map);
+ assertEquals(3, copy.size());
+ assertEquals("A", copy.get("CamelA"));
+ assertEquals("B", copy.get("CamelB"));
+ assertEquals("C", copy.get("CamelC"));
+
+ maps.add(copy);
+ }
+
+ assertEquals(10000, maps.size());
+
+ assertEquals(3, map.size());
+ assertEquals("A", map.get("CamelA"));
+ assertEquals("B", map.get("CamelB"));
+ assertEquals("C", map.get("CamelC"));
+
+ // use a memory profiler to see memory allocation
+ // often you may want to give it time to run so you
+ // have chance to capture memory snapshot in profiler
+ // Thread.sleep(9999999);
+ }
+
+
}
\ No newline at end of file