Change JsScope to use LinkedHashMap instead of HashMap. This allows identifiers to be allocated obfuscated identifiers in the original order of their declaration, which produces a lot more common substrings in the obfuscated output which significantly improves gzip/deflate compression. Experimental Data using gzip -9 on cache.html files:
Mail sample: 191614/197548 (3%) (with patch/without/% improved)
Chronoscope: 1373800/1482204 (7.3%)
Showcase: 1641005/1832098 (10.5%)
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5865 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsScope.java b/dev/core/src/com/google/gwt/dev/js/ast/JsScope.java
index 71489d6..de9552a 100644
--- a/dev/core/src/com/google/gwt/dev/js/ast/JsScope.java
+++ b/dev/core/src/com/google/gwt/dev/js/ast/JsScope.java
@@ -24,7 +24,6 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
/**
* A scope is a factory for creating and allocating
@@ -162,11 +161,7 @@
* Returns an iterator for all the names defined by this scope.
*/
public Iterator<JsName> getAllNames() {
- if (names.size() > 1) {
- return new TreeMap<String, JsName>(names).values().iterator();
- } else {
return names.values().iterator();
- }
}
/**
@@ -206,7 +201,7 @@
*/
protected JsName doCreateName(String ident, String shortIdent) {
JsName name = new JsName(this, ident, shortIdent);
- names = Maps.put(names, ident, name);
+ names = Maps.putOrdered(names, ident, name);
return name;
}
diff --git a/dev/core/src/com/google/gwt/dev/util/collect/Maps.java b/dev/core/src/com/google/gwt/dev/util/collect/Maps.java
index 98fd25e..1cc6899 100644
--- a/dev/core/src/com/google/gwt/dev/util/collect/Maps.java
+++ b/dev/core/src/com/google/gwt/dev/util/collect/Maps.java
@@ -17,6 +17,7 @@
import java.util.Collections;
import java.util.Map;
+import java.util.LinkedHashMap;
/**
* Utility methods for operating on memory-efficient maps. All maps of size 0 or
@@ -117,6 +118,32 @@
}
}
+ /**
+ * A variation of the put method which uses a LinkedHashMap.
+ */
+ public static <K, V> Map<K, V> putOrdered(Map<K, V> map, K key, V value) {
+ switch (map.size()) {
+ case 0:
+ // Empty -> Singleton
+ return Collections.singletonMap(key, value);
+ case 1: {
+ if (map.containsKey(key)) {
+ return create(key, value);
+ }
+ // Singleton -> LinkedHashMap
+ Map<K, V> result = new LinkedHashMap<K, V>();
+ result.put(map.keySet().iterator().next(),
+ map.values().iterator().next());
+ result.put(key, value);
+ return result;
+ }
+ default:
+ // LinkedHashMap
+ map.put(key, value);
+ return map;
+ }
+ }
+
public static <K, V> Map<K, V> remove(Map<K, V> map, K key) {
switch (map.size()) {
case 0: