You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by cu...@apache.org on 2013/03/18 21:11:00 UTC

svn commit: r1457964 - /openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java

Author: curtisr7
Date: Mon Mar 18 20:11:00 2013
New Revision: 1457964

URL: http://svn.apache.org/r1457964
Log:
OPENJPA-2353: Reduce BitSet object allocations in StateManagerImpl.

Modified:
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java

Modified: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=1457964&r1=1457963&r2=1457964&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java (original)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java Mon Mar 18 20:11:00 2013
@@ -113,8 +113,12 @@ public class StateManagerImpl implements
     private transient PersistenceCapable _pc = null;
     protected transient ClassMetaData _meta = null;
     protected BitSet _loaded = null;
+    
+    // Care needs to be taken when accessing these fields as they will can be null if no fields are
+    // dirty, or have been flushed.
     private BitSet _dirty = null;
     private BitSet _flush = null;
+    
     private BitSet _delayed = null;
     private int _flags = 0;
 
@@ -351,9 +355,7 @@ public class StateManagerImpl implements
 
         FieldMetaData[] fmds = _meta.getFields();
         _loaded = new BitSet(fmds.length);
-        _flush = new BitSet(fmds.length);
-        _dirty = new BitSet(fmds.length);
-
+        
         // mark primary key and non-persistent fields as loaded
         for(int i : _meta.getPkAndNonPersistentManagedFmdIndexes()){
             _loaded.set(i);
@@ -490,14 +492,6 @@ public class StateManagerImpl implements
         return _loaded;
     }
 
-    public BitSet getFlushed() {
-        return _flush;
-    }
-
-    public BitSet getDirty() {
-        return _dirty;
-    }
-
     public BitSet getUnloaded(FetchConfiguration fetch) {
         // collect fields to load from data store based on fetch configuration
         BitSet fields = getUnloadedInternal(fetch, LOAD_FGS, null);
@@ -945,7 +939,7 @@ public class StateManagerImpl implements
 
         lock();
         try {
-            if (_saved == null || !_loaded.get(field) || !_dirty.get(field))
+            if (_saved == null || !_loaded.get(field) || !isFieldDirty(field))
                 return fetchField(field, false);
 
             // if the field is dirty but we never loaded it, we can't restore it
@@ -1059,8 +1053,11 @@ public class StateManagerImpl implements
             boolean needPostUpdate = !(wasNew && !wasFlushed)
                     && (ImplHelper.getUpdateFields(this) != null);
 
-            // all dirty fields were flushed
-            _flush.or(_dirty);
+            // all dirty fields were flushed, we are referencing the _dirty BitSet directly here
+            // because we don't want to instantiate it if we don't have to.
+            if (_dirty != null) {
+                getFlushed().or(_dirty);
+            }
 
             // important to set flushed bit after calling _state.flush so
             // that the state can tell whether this is the first flush
@@ -1107,7 +1104,7 @@ public class StateManagerImpl implements
     void commit() {
         // release locks before oid updated
         releaseLocks();
-
+ 
         // update version and oid information
         setVersion(_version);
         _flags &= ~FLAG_FLUSHED;
@@ -1770,7 +1767,7 @@ public class StateManagerImpl implements
 
             // note that the field is in need of flushing again, and tell the
             // broker too
-            _flush.clear(field);
+            clearFlushField(field);
             _broker.setDirty(this, newFlush && !clean);
 
             // save the field for rollback if needed
@@ -1778,9 +1775,9 @@ public class StateManagerImpl implements
 
             // dirty the field and mark loaded; load fetch group if needed
             int lockLevel = calculateLockLevel(active, true, null);
-            if (!_dirty.get(field)) {
+            if (!isFieldDirty(field)) {
                 setLoaded(field, true);
-                _dirty.set(field);
+                setFieldDirty(field);
 
                 // make sure the field's fetch group is loaded
                 if (loadFetchGroup && isPersistent()
@@ -2754,9 +2751,7 @@ public class StateManagerImpl implements
         _flags &= ~FLAG_FLUSHED;
         _flags &= ~FLAG_FLUSHED_DIRTY;
 
-        int fmds = _meta.getFields().length;
-        for (int i = 0; i < fmds; i++)
-            _flush.clear(i);
+        _flush = null;
     }
 
     /**
@@ -2785,14 +2780,13 @@ public class StateManagerImpl implements
         FieldMetaData[] fmds = _meta.getFields();
         boolean update = !isNew() || isFlushed();
         for (int i = 0; i < fmds.length; i++) {
-            if (val && (!update
-                || fmds[i].getUpdateStrategy() != UpdateStrategies.IGNORE))
-                _dirty.set(i);
+            if (val && (!update || fmds[i].getUpdateStrategy() != UpdateStrategies.IGNORE))
+                setFieldDirty(i);
             else if (!val) {
                 // we never consider clean fields flushed; this also takes
                 // care of clearing the flushed fields on commit/rollback
-                _flush.clear(i);
-                _dirty.clear(i);
+                clearFlushField(i);
+                clearDirty(i);
             }
         }
 
@@ -2855,8 +2849,7 @@ public class StateManagerImpl implements
             // record a saved field manager even if no field is currently loaded
             // as existence of a SaveFieldManager is critical for a dirty check
             if (_saved == null)
-            	_saved = new SaveFieldManager(this, getPersistenceCapable(), 
-            				_dirty);
+                _saved = new SaveFieldManager(this, getPersistenceCapable(), getDirty());
         }
     }
 
@@ -2879,7 +2872,7 @@ public class StateManagerImpl implements
         // save the old field value anyway
         if (_saved == null) {
             if (_loaded.get(field))
-                _saved = new SaveFieldManager(this, null, _dirty);
+                _saved = new SaveFieldManager(this, null, getDirty());
             else
                 return;
         }
@@ -2960,7 +2953,7 @@ public class StateManagerImpl implements
             for (FieldMetaData fmd : _meta.getProxyFields()) {
                 int index = fmd.getIndex();
                 // only reload if dirty
-                if (_loaded.get(index) && _dirty.get(index)) {
+                if (_loaded.get(index) && isFieldDirty(index)) {
                     provideField(_pc, _single, index);
                     if (_single.proxy(reset, replaceNull)) {
                         replaceField(_pc, _single, index);
@@ -3020,8 +3013,7 @@ public class StateManagerImpl implements
             if (!logical)
                 assignObjectId(false, true);
             for (int i = 0, len = _meta.getFields().length; i < len; i++) {
-                if ((logical || !assignField(i, true)) && !_flush.get(i)
-                    && _dirty.get(i)) {
+                if ((logical || !assignField(i, true)) && !isFieldFlushed(i) && isFieldDirty(i)) {
                     provideField(_pc, _single, i);
                     if (_single.preFlush(logical, call))
                         replaceField(_pc, _single, i);
@@ -3472,4 +3464,53 @@ public class StateManagerImpl implements
         _broker = ctx;
     }
 
+    public BitSet getFlushed() {
+        if (_flush == null) {
+            _flush = new BitSet(_meta.getFields().length);
+        }
+        return _flush;
+    }
+
+    private boolean isFieldFlushed(int index) {
+        if (_flush == null) {
+            return false;
+        }
+        return _flush.get(index);
+    }
+
+    /**
+     * Will clear the bit at the specified if the _flush BetSet has been created.
+     */
+    private void clearFlushField(int index) {
+        if (_flush != null) {
+            getFlushed().clear(index);
+        }
+    }
+
+    public BitSet getDirty() {
+        if (_dirty == null) {
+            _dirty = new BitSet(_meta.getFields().length);
+        }
+        return _dirty;
+    }
+
+    private boolean isFieldDirty(int index) {
+        if (_dirty == null) {
+            return false;
+        }
+        return _dirty.get(index);
+    }
+
+    private void setFieldDirty(int index) {
+        getDirty().set(index);
+    }
+
+    /**
+     * Will clear the bit at the specified index if the _dirty BetSet has been created.
+     */
+    private void clearDirty(int index) {
+        if (_dirty != null) {
+            getDirty().clear(index);
+        }
+    }
 }