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:13:10 UTC
svn commit: r1457966 -
/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
Author: curtisr7
Date: Mon Mar 18 20:13:10 2013
New Revision: 1457966
URL: http://svn.apache.org/r1457966
Log:
OPENJPA-2353: Reduce BitSet object allocations in StateManagerImpl.
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java?rev=1457966&r1=1457965&r2=1457966&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java Mon Mar 18 20:13:10 2013
@@ -114,8 +114,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);
@@ -491,14 +493,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);
@@ -946,7 +940,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
@@ -1060,8 +1054,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
@@ -1108,7 +1105,7 @@ public class StateManagerImpl implements
void commit() {
// release locks before oid updated
releaseLocks();
-
+
// update version and oid information
setVersion(_version);
_flags &= ~FLAG_FLUSHED;
@@ -1771,7 +1768,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
@@ -1779,9 +1776,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()
@@ -2755,9 +2752,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;
}
/**
@@ -2786,14 +2781,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);
}
}
@@ -2856,8 +2850,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());
}
}
@@ -2880,7 +2873,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;
}
@@ -2961,7 +2954,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);
@@ -3021,8 +3014,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
public void setBroker(BrokerImpl ctx) {
_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);
+ }
+ }
}