mirror of https://github.com/apache/openjpa.git
OPENJPA-2353: Reduce BitSet object allocations in StateManagerImpl.
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1457966 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
70a201a55d
commit
47e402ce90
|
@ -114,8 +114,12 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
private transient PersistenceCapable _pc = null;
|
private transient PersistenceCapable _pc = null;
|
||||||
protected transient ClassMetaData _meta = null;
|
protected transient ClassMetaData _meta = null;
|
||||||
protected BitSet _loaded = 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 _dirty = null;
|
||||||
private BitSet _flush = null;
|
private BitSet _flush = null;
|
||||||
|
|
||||||
private BitSet _delayed = null;
|
private BitSet _delayed = null;
|
||||||
private int _flags = 0;
|
private int _flags = 0;
|
||||||
|
|
||||||
|
@ -351,9 +355,7 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
|
|
||||||
FieldMetaData[] fmds = _meta.getFields();
|
FieldMetaData[] fmds = _meta.getFields();
|
||||||
_loaded = new BitSet(fmds.length);
|
_loaded = new BitSet(fmds.length);
|
||||||
_flush = new BitSet(fmds.length);
|
|
||||||
_dirty = new BitSet(fmds.length);
|
|
||||||
|
|
||||||
// mark primary key and non-persistent fields as loaded
|
// mark primary key and non-persistent fields as loaded
|
||||||
for(int i : _meta.getPkAndNonPersistentManagedFmdIndexes()){
|
for(int i : _meta.getPkAndNonPersistentManagedFmdIndexes()){
|
||||||
_loaded.set(i);
|
_loaded.set(i);
|
||||||
|
@ -491,14 +493,6 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
return _loaded;
|
return _loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BitSet getFlushed() {
|
|
||||||
return _flush;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BitSet getDirty() {
|
|
||||||
return _dirty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BitSet getUnloaded(FetchConfiguration fetch) {
|
public BitSet getUnloaded(FetchConfiguration fetch) {
|
||||||
// collect fields to load from data store based on fetch configuration
|
// collect fields to load from data store based on fetch configuration
|
||||||
BitSet fields = getUnloadedInternal(fetch, LOAD_FGS, null);
|
BitSet fields = getUnloadedInternal(fetch, LOAD_FGS, null);
|
||||||
|
@ -946,7 +940,7 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
|
|
||||||
lock();
|
lock();
|
||||||
try {
|
try {
|
||||||
if (_saved == null || !_loaded.get(field) || !_dirty.get(field))
|
if (_saved == null || !_loaded.get(field) || !isFieldDirty(field))
|
||||||
return fetchField(field, false);
|
return fetchField(field, false);
|
||||||
|
|
||||||
// if the field is dirty but we never loaded it, we can't restore it
|
// if the field is dirty but we never loaded it, we can't restore it
|
||||||
|
@ -1060,8 +1054,11 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
boolean needPostUpdate = !(wasNew && !wasFlushed)
|
boolean needPostUpdate = !(wasNew && !wasFlushed)
|
||||||
&& (ImplHelper.getUpdateFields(this) != null);
|
&& (ImplHelper.getUpdateFields(this) != null);
|
||||||
|
|
||||||
// all dirty fields were flushed
|
// all dirty fields were flushed, we are referencing the _dirty BitSet directly here
|
||||||
_flush.or(_dirty);
|
// 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
|
// important to set flushed bit after calling _state.flush so
|
||||||
// that the state can tell whether this is the first flush
|
// that the state can tell whether this is the first flush
|
||||||
|
@ -1108,7 +1105,7 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
void commit() {
|
void commit() {
|
||||||
// release locks before oid updated
|
// release locks before oid updated
|
||||||
releaseLocks();
|
releaseLocks();
|
||||||
|
|
||||||
// update version and oid information
|
// update version and oid information
|
||||||
setVersion(_version);
|
setVersion(_version);
|
||||||
_flags &= ~FLAG_FLUSHED;
|
_flags &= ~FLAG_FLUSHED;
|
||||||
|
@ -1771,7 +1768,7 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
|
|
||||||
// note that the field is in need of flushing again, and tell the
|
// note that the field is in need of flushing again, and tell the
|
||||||
// broker too
|
// broker too
|
||||||
_flush.clear(field);
|
clearFlushField(field);
|
||||||
_broker.setDirty(this, newFlush && !clean);
|
_broker.setDirty(this, newFlush && !clean);
|
||||||
|
|
||||||
// save the field for rollback if needed
|
// save the field for rollback if needed
|
||||||
|
@ -1779,9 +1776,9 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
|
|
||||||
// dirty the field and mark loaded; load fetch group if needed
|
// dirty the field and mark loaded; load fetch group if needed
|
||||||
int lockLevel = calculateLockLevel(active, true, null);
|
int lockLevel = calculateLockLevel(active, true, null);
|
||||||
if (!_dirty.get(field)) {
|
if (!isFieldDirty(field)) {
|
||||||
setLoaded(field, true);
|
setLoaded(field, true);
|
||||||
_dirty.set(field);
|
setFieldDirty(field);
|
||||||
|
|
||||||
// make sure the field's fetch group is loaded
|
// make sure the field's fetch group is loaded
|
||||||
if (loadFetchGroup && isPersistent()
|
if (loadFetchGroup && isPersistent()
|
||||||
|
@ -2755,9 +2752,7 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
_flags &= ~FLAG_FLUSHED;
|
_flags &= ~FLAG_FLUSHED;
|
||||||
_flags &= ~FLAG_FLUSHED_DIRTY;
|
_flags &= ~FLAG_FLUSHED_DIRTY;
|
||||||
|
|
||||||
int fmds = _meta.getFields().length;
|
_flush = null;
|
||||||
for (int i = 0; i < fmds; i++)
|
|
||||||
_flush.clear(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2786,14 +2781,13 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
FieldMetaData[] fmds = _meta.getFields();
|
FieldMetaData[] fmds = _meta.getFields();
|
||||||
boolean update = !isNew() || isFlushed();
|
boolean update = !isNew() || isFlushed();
|
||||||
for (int i = 0; i < fmds.length; i++) {
|
for (int i = 0; i < fmds.length; i++) {
|
||||||
if (val && (!update
|
if (val && (!update || fmds[i].getUpdateStrategy() != UpdateStrategies.IGNORE))
|
||||||
|| fmds[i].getUpdateStrategy() != UpdateStrategies.IGNORE))
|
setFieldDirty(i);
|
||||||
_dirty.set(i);
|
|
||||||
else if (!val) {
|
else if (!val) {
|
||||||
// we never consider clean fields flushed; this also takes
|
// we never consider clean fields flushed; this also takes
|
||||||
// care of clearing the flushed fields on commit/rollback
|
// care of clearing the flushed fields on commit/rollback
|
||||||
_flush.clear(i);
|
clearFlushField(i);
|
||||||
_dirty.clear(i);
|
clearDirty(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2856,8 +2850,7 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
// record a saved field manager even if no field is currently loaded
|
// record a saved field manager even if no field is currently loaded
|
||||||
// as existence of a SaveFieldManager is critical for a dirty check
|
// as existence of a SaveFieldManager is critical for a dirty check
|
||||||
if (_saved == null)
|
if (_saved == null)
|
||||||
_saved = new SaveFieldManager(this, getPersistenceCapable(),
|
_saved = new SaveFieldManager(this, getPersistenceCapable(), getDirty());
|
||||||
_dirty);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2880,7 +2873,7 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
// save the old field value anyway
|
// save the old field value anyway
|
||||||
if (_saved == null) {
|
if (_saved == null) {
|
||||||
if (_loaded.get(field))
|
if (_loaded.get(field))
|
||||||
_saved = new SaveFieldManager(this, null, _dirty);
|
_saved = new SaveFieldManager(this, null, getDirty());
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2961,7 +2954,7 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
for (FieldMetaData fmd : _meta.getProxyFields()) {
|
for (FieldMetaData fmd : _meta.getProxyFields()) {
|
||||||
int index = fmd.getIndex();
|
int index = fmd.getIndex();
|
||||||
// only reload if dirty
|
// only reload if dirty
|
||||||
if (_loaded.get(index) && _dirty.get(index)) {
|
if (_loaded.get(index) && isFieldDirty(index)) {
|
||||||
provideField(_pc, _single, index);
|
provideField(_pc, _single, index);
|
||||||
if (_single.proxy(reset, replaceNull)) {
|
if (_single.proxy(reset, replaceNull)) {
|
||||||
replaceField(_pc, _single, index);
|
replaceField(_pc, _single, index);
|
||||||
|
@ -3021,8 +3014,7 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
if (!logical)
|
if (!logical)
|
||||||
assignObjectId(false, true);
|
assignObjectId(false, true);
|
||||||
for (int i = 0, len = _meta.getFields().length; i < len; i++) {
|
for (int i = 0, len = _meta.getFields().length; i < len; i++) {
|
||||||
if ((logical || !assignField(i, true)) && !_flush.get(i)
|
if ((logical || !assignField(i, true)) && !isFieldFlushed(i) && isFieldDirty(i)) {
|
||||||
&& _dirty.get(i)) {
|
|
||||||
provideField(_pc, _single, i);
|
provideField(_pc, _single, i);
|
||||||
if (_single.preFlush(logical, call))
|
if (_single.preFlush(logical, call))
|
||||||
replaceField(_pc, _single, i);
|
replaceField(_pc, _single, i);
|
||||||
|
@ -3472,4 +3464,53 @@ public class StateManagerImpl implements OpenJPAStateManager, Serializable {
|
||||||
public void setBroker(BrokerImpl ctx) {
|
public void setBroker(BrokerImpl ctx) {
|
||||||
_broker = 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue