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) {

Reply via email to