Changes to AsyncFragmentLoader to replace the use of Map with ArrayList.
The end result results in a linear time but with a reduction in initial code
size by ~10K. The linear time is not likely a concern unless the resulting
application is quite large (> 100 fragments).
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7597 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java b/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java
index c36a6a7..8df3955 100644
--- a/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java
+++ b/user/src/com/google/gwt/core/client/impl/AsyncFragmentLoader.java
@@ -20,9 +20,7 @@
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
/**
* <p>
@@ -85,8 +83,8 @@
* so that they can be optional. A value of <code>null</code> for either one
* means that they are not specified.
*/
- void logEventProgress(String eventGroup, String type, Integer fragment,
- Integer size);
+ void logEventProgress(String eventGroup, String type, int fragment,
+ int size);
}
/**
@@ -198,7 +196,11 @@
requestedExclusives.clear();
// add handlers for pending downloads
- handlersToRun.addAll(pendingDownloadErrorHandlers.values());
+ for (LoadErrorHandler handler : pendingDownloadErrorHandlers) {
+ if (handler != null) {
+ handlersToRun.add(handler);
+ }
+ }
pendingDownloadErrorHandlers.clear();
fragmentLoading = -1;
@@ -237,14 +239,14 @@
}-*/;
public void logEventProgress(String eventGroup, String type,
- Integer fragment, Integer size) {
+ int fragment, int size) {
@SuppressWarnings("unused")
boolean toss = isStatsAvailable()
&& stats(createStatsEvent(eventGroup, type, fragment, size));
}
private native JavaScriptObject createStatsEvent(String eventGroup,
- String type, Integer fragment, Integer size) /*-{
+ String type, int fragment, int size) /*-{
var evt = {
moduleName: @com.google.gwt.core.client.GWT::getModuleName()(),
sessionId: $sessionId,
@@ -253,11 +255,11 @@
millis: (new Date()).getTime(),
type: type
};
- if (fragment != null) {
- evt.fragment = fragment.@java.lang.Integer::intValue()();
+ if (fragment >= 0) {
+ evt.fragment = fragment;
}
- if (size != null) {
- evt.size = size.@java.lang.Integer::intValue()();
+ if (size >= 0) {
+ evt.size = size;
}
return evt;
}-*/;
@@ -337,10 +339,8 @@
/**
* Externally provided handlers for all outstanding and queued download
* requests.
- *
- * TODO(spoon) make it a lightweight integer map
*/
- private Map<Integer, LoadErrorHandler> pendingDownloadErrorHandlers = new HashMap<Integer, LoadErrorHandler>();
+ private ArrayList<LoadErrorHandler> pendingDownloadErrorHandlers = new ArrayList<LoadErrorHandler>();
/**
* Whether prefetching is currently enabled.
@@ -382,7 +382,9 @@
*/
public void fragmentHasLoaded(int fragment) {
logFragmentLoaded(fragment);
- pendingDownloadErrorHandlers.remove(fragment);
+ if (fragment < pendingDownloadErrorHandlers.size()) {
+ pendingDownloadErrorHandlers.set(fragment, null);
+ }
if (isInitial(fragment)) {
assert (fragment == remainingInitialFragments.peek());
@@ -408,7 +410,8 @@
* @param splitPoint the split point whose code needs to be loaded
*/
public void inject(int splitPoint, LoadErrorHandler loadErrorHandler) {
- pendingDownloadErrorHandlers.put(splitPoint, loadErrorHandler);
+ setCapacity(pendingDownloadErrorHandlers, splitPoint + 1);
+ pendingDownloadErrorHandlers.set(splitPoint, loadErrorHandler);
if (!isInitial(splitPoint)) {
requestedExclusives.add(splitPoint);
}
@@ -427,7 +430,7 @@
* Log an event with the {@Logger} this instance was provided.
*/
public void logEventProgress(String eventGroup, String type) {
- logEventProgress(eventGroup, type, null, null);
+ logEventProgress(eventGroup, type, -1, -1);
}
/**
@@ -468,7 +471,10 @@
private void clearRequestsAlreadyLoaded() {
while (requestedExclusives.size() > 0
&& isLoaded[requestedExclusives.peek()]) {
- pendingDownloadErrorHandlers.remove(requestedExclusives.remove());
+ int offset = requestedExclusives.remove();
+ if (offset < pendingDownloadErrorHandlers.size()) {
+ pendingDownloadErrorHandlers.set(offset, null);
+ }
}
if (prefetchQueue != null) {
@@ -505,6 +511,19 @@
}
}
+ /**
+ * Return if the the ArrayList is empty.
+ * @param list the list to check if empty
+ */
+ private boolean isEmpty(ArrayList<?> list) {
+ for (int i = 0; i < list.size(); i++) {
+ if (list.get(i) != null) {
+ return false;
+ }
+ }
+ return true;
+ }
+
private boolean isInitial(int splitPoint) {
if (splitPoint == leftoversFragment()) {
return true;
@@ -522,7 +541,7 @@
}
private void logDownloadStart(int fragment) {
- logEventProgress(downloadGroup(fragment), LwmLabels.BEGIN, fragment, null);
+ logEventProgress(downloadGroup(fragment), LwmLabels.BEGIN, fragment, -1);
}
/**
@@ -537,7 +556,18 @@
private void logFragmentLoaded(int fragment) {
String logGroup = downloadGroup(fragment);
- logEventProgress(logGroup, LwmLabels.END, fragment, null);
+ logEventProgress(logGroup, LwmLabels.END, fragment, -1);
+ }
+
+ /**
+ * Set capacity ArrayList list.
+ * @param list the list to add capacity to.
+ * @param size the new size to increase the capacity to.
+ */
+ private void setCapacity(ArrayList<?> list, int size) {
+ while (list.size() < size) {
+ list.add(null);
+ }
}
private void startLoadingFragment(int fragment) {
@@ -560,7 +590,7 @@
initializeRemainingInitialFragments();
clearRequestsAlreadyLoaded();
- if (pendingDownloadErrorHandlers.isEmpty() && !anyPrefetchesRequested()) {
+ if (isEmpty(pendingDownloadErrorHandlers) && !anyPrefetchesRequested()) {
/*
* Don't load anything if there aren't any requests outstanding.
*/
diff --git a/user/test/com/google/gwt/core/client/impl/AsyncFragmentLoaderTest.java b/user/test/com/google/gwt/core/client/impl/AsyncFragmentLoaderTest.java
index 145bb8c..83eeee4 100644
--- a/user/test/com/google/gwt/core/client/impl/AsyncFragmentLoaderTest.java
+++ b/user/test/com/google/gwt/core/client/impl/AsyncFragmentLoaderTest.java
@@ -105,10 +105,10 @@
private static class MockProgressEvent {
public final String eventGroup;
- public final Integer fragment;
+ public final int fragment;
public final String type;
- public MockProgressEvent(String eventGroup, String type, Integer fragment) {
+ public MockProgressEvent(String eventGroup, String type, int fragment) {
this.eventGroup = eventGroup;
this.type = type;
this.fragment = fragment;
@@ -118,7 +118,7 @@
private static class MockProgressLogger implements Logger {
private Queue<MockProgressEvent> events = new LinkedList<MockProgressEvent>();
- public void assertEvent(String eventGroup, String type, Integer fragment) {
+ public void assertEvent(String eventGroup, String type, int fragment) {
MockProgressEvent event = events.remove();
assertEquals(eventGroup, event.eventGroup);
assertEquals(type, event.type);
@@ -131,7 +131,7 @@
}
public void logEventProgress(String eventGroup, String type,
- Integer fragment, Integer size) {
+ int fragment, int size) {
events.add(new MockProgressEvent(eventGroup, type, fragment));
}
}