Revision: 3927
Author: [email protected]
Date: Thu Aug 26 14:41:06 2010
Log: Added performance enhancements to the SPJSONMessageDecoder. A
decode(JSONTokener) method has been created which has similar functionality
to the already existing decode(JSONArray) method.
Normally when a JSONArray is created, it creates its own JSONTokener and
parses all of the tokens. These tokens are saved in an ArrayList as a
buffer. When you get a JSONObject at a particular index, it can return the
JSONObject right away.
However, this process can cause memory usage to spike very high on
extremely large JSONArrays. The new decode(JSONTokener) method will instead
make the persister call immediately after parsing each JSONObject token. By
doing so, the JSONObject token can be marked for garbage collection when it
finishes the persister call.
http://code.google.com/p/power-architect/source/detail?r=3927
Modified:
/trunk/src/main/java/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java
Mon Aug 23 15:29:34 2010
+++
/trunk/src/main/java/ca/sqlpower/architect/enterprise/NetworkConflictResolver.java
Thu Aug 26 14:41:06 2010
@@ -39,6 +39,7 @@
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
+import org.json.JSONTokener;
import org.springframework.security.AccessDeniedException;
import ca.sqlpower.architect.swingui.PlayPenComponent;
@@ -49,18 +50,18 @@
import ca.sqlpower.dao.PersistedSPObject;
import ca.sqlpower.dao.RemovedObjectEntry;
import ca.sqlpower.dao.SPPersistenceException;
+import ca.sqlpower.dao.SPPersister.DataType;
import ca.sqlpower.dao.SPPersisterListener;
import ca.sqlpower.dao.SPSessionPersister;
-import ca.sqlpower.dao.SPPersister.DataType;
import ca.sqlpower.dao.json.SPJSONMessageDecoder;
import ca.sqlpower.dao.session.SessionPersisterSuperConverter;
import ca.sqlpower.object.SPObject;
import ca.sqlpower.sqlobject.SQLRelationship.ColumnMapping;
import ca.sqlpower.util.MonitorableImpl;
import ca.sqlpower.util.SQLPowerUtils;
-import ca.sqlpower.util.UserPrompterFactory;
import ca.sqlpower.util.UserPrompter.UserPromptOptions;
import ca.sqlpower.util.UserPrompter.UserPromptResponse;
+import ca.sqlpower.util.UserPrompterFactory;
import ca.sqlpower.util.UserPrompterFactory.UserPromptType;
import com.enterprisedt.util.debug.Logger;
@@ -281,7 +282,7 @@
@Override
public void run() {
// Try to apply update
- decodeMessage(json, newRev);
+ decodeMessage(new JSONTokener(json), newRev);
// We need an additional step here for checking
for special case conflicts
List<ConflictMessage> conflicts =
detectConflicts();
if (conflicts.size() == 0) {
@@ -368,12 +369,15 @@
// The updater may have been interrupted/closed/deleted
while waiting for an update.
if (this.isInterrupted() || cancelled) break;
- final JSONObject json = new
JSONObject(message.getBody());
+ JSONObject json = new JSONObject(message.getBody());
+ final JSONTokener tokener = new
JSONTokener(json.getString("data"));
+ final int currentRevision =
json.getInt("currentRevision");
+
session.runInForeground(new Runnable() {
public void run() {
try {
if (!postingJSON.get()) {
- decodeMessage(json.getString("data"),
json.getInt("currentRevision"));
+ decodeMessage(tokener, currentRevision);
}
} catch (AccessDeniedException e) {
interrupt();
@@ -425,15 +429,17 @@
inboundHttpClient.getConnectionManager().shutdown();
}
-
+
/**
* Exists for code reuse.
*
- * @param jsonArray
+ * @param tokener
+ * {...@link JSONTokener} that tokenizes multiple persister
calls.
* @param newRevision
+ * The new revision number.
* @throws SPPersistenceException
*/
- private void decodeMessage(String jsonArray, int newRevision) {
+ private void decodeMessage(JSONTokener tokener, int newRevision) {
try {
if (currentRevision < newRevision) {
List<UpdateListener> updateListenersCopy = new
ArrayList<UpdateListener>(updateListeners);
@@ -441,7 +447,7 @@
listener.preUpdatePerformed(NetworkConflictResolver.this);
}
// Now we can apply the update ...
- jsonDecoder.decode(jsonArray);
+ jsonDecoder.decode(tokener);
currentRevision = newRevision;
for (UpdateListener listener : updateListenersCopy) {