From c5d2d2c217eb54bcc495c67777e439f5d856e2bd Mon Sep 17 00:00:00 2001 From: "Kevin W. Sutter" Date: Fri, 30 Mar 2012 21:26:31 +0000 Subject: [PATCH] OPENJPA-2151. Optimizations to StateManagerImpl.initialize and FieldMetaData access. git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1307622 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/openjpa/kernel/ECleanState.java | 3 +- .../org/apache/openjpa/kernel/ECopyState.java | 3 +- .../apache/openjpa/kernel/EDirtyState.java | 3 +- .../apache/openjpa/kernel/ENonTransState.java | 8 ++- .../apache/openjpa/kernel/HollowState.java | 3 +- .../org/apache/openjpa/kernel/PCState.java | 2 +- .../apache/openjpa/kernel/PCleanState.java | 6 +- .../apache/openjpa/kernel/PDeletedState.java | 3 +- .../apache/openjpa/kernel/PDirtyState.java | 3 +- .../PNewFlushedDeletedFlushedState.java | 3 +- .../openjpa/kernel/PNewProvisionalState.java | 3 +- .../org/apache/openjpa/kernel/PNewState.java | 6 +- .../openjpa/kernel/PNonTransDirtyState.java | 3 +- .../openjpa/kernel/PNonTransNewState.java | 3 +- .../apache/openjpa/kernel/PNonTransState.java | 6 +- .../openjpa/kernel/StateManagerImpl.java | 35 ++++-------- .../apache/openjpa/kernel/TCleanState.java | 8 ++- .../apache/openjpa/kernel/TDirtyState.java | 3 +- .../apache/openjpa/kernel/TLoadedState.java | 3 +- .../apache/openjpa/kernel/TransientState.java | 3 +- .../apache/openjpa/meta/ClassMetaData.java | 56 ++++++++++++++++++- 21 files changed, 120 insertions(+), 46 deletions(-) diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECleanState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECleanState.java index 2d2f209d3..1f0e5da7f 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECleanState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECleanState.java @@ -30,7 +30,8 @@ package org.apache.openjpa.kernel; class ECleanState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { context.setDirty(false); } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECopyState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECopyState.java index 1df96b664..5ffc13adf 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECopyState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ECopyState.java @@ -29,7 +29,8 @@ package org.apache.openjpa.kernel; class ECopyState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { // no need to save fields, because this transition doesn't happen // until the flush process begins context.setLoaded(true); diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/EDirtyState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/EDirtyState.java index 136e66d17..8a2a59db3 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/EDirtyState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/EDirtyState.java @@ -29,7 +29,8 @@ package org.apache.openjpa.kernel; class EDirtyState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { context.saveFields(false); } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ENonTransState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ENonTransState.java index 345d09c79..e914dc70d 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ENonTransState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ENonTransState.java @@ -30,10 +30,14 @@ package org.apache.openjpa.kernel; class ENonTransState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { + if (previous == null) + return; + // spec says all proxies to second class objects should be reset context.proxyFields(true, true); - + context.setDirty(false); context.clearSavedFields(); } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/HollowState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/HollowState.java index 54c9f9f5d..36d142561 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/HollowState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/HollowState.java @@ -32,7 +32,8 @@ package org.apache.openjpa.kernel; class HollowState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { context.clearFields(); context.clearSavedFields(); context.setDirty(false); diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCState.java index 3e703ed46..61220c6bd 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCState.java @@ -161,7 +161,7 @@ public class PCState /** * Called when this state is first assigned to the given state manager. */ - void initialize(StateManagerImpl context) { + void initialize(StateManagerImpl context, PCState previousState) { } /** diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCleanState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCleanState.java index 65681e451..f2f9389d5 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCleanState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PCleanState.java @@ -29,7 +29,11 @@ package org.apache.openjpa.kernel; class PCleanState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { + if (previous == null) + return; + context.setDirty(false); } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PDeletedState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PDeletedState.java index 068fc9373..fd9b1e2cb 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PDeletedState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PDeletedState.java @@ -29,7 +29,8 @@ package org.apache.openjpa.kernel; class PDeletedState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { context.saveFields(false); } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PDirtyState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PDirtyState.java index 77bc22717..6f1f038e3 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PDirtyState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PDirtyState.java @@ -29,7 +29,8 @@ package org.apache.openjpa.kernel; class PDirtyState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { context.saveFields(false); } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNewFlushedDeletedFlushedState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNewFlushedDeletedFlushedState.java index f85bb51b7..baa0f7626 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNewFlushedDeletedFlushedState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNewFlushedDeletedFlushedState.java @@ -29,7 +29,8 @@ package org.apache.openjpa.kernel; class PNewFlushedDeletedFlushedState extends PNewFlushedDeletedState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { } PCState persist(StateManagerImpl context) { diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNewProvisionalState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNewProvisionalState.java index 56bd34181..fcab4bef8 100755 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNewProvisionalState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNewProvisionalState.java @@ -30,7 +30,8 @@ package org.apache.openjpa.kernel; class PNewProvisionalState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { context.setLoaded(true); context.setDirty(true); context.saveFields(false); diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNewState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNewState.java index 1d885348b..9cfebe0ac 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNewState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNewState.java @@ -29,7 +29,11 @@ package org.apache.openjpa.kernel; class PNewState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { + if (previous == null) + return; + context.setLoaded(true); context.setDirty(true); context.saveFields(false); diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNonTransDirtyState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNonTransDirtyState.java index fb2432c4f..f67a3e172 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNonTransDirtyState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNonTransDirtyState.java @@ -30,7 +30,8 @@ package org.apache.openjpa.kernel; class PNonTransDirtyState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { context.saveFields(false); } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNonTransNewState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNonTransNewState.java index d5a84f7d5..189891072 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNonTransNewState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNonTransNewState.java @@ -28,7 +28,8 @@ package org.apache.openjpa.kernel; class PNonTransNewState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { context.setLoaded(true); context.setDirty(true); } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNonTransState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNonTransState.java index 3d074b801..0963dfeef 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNonTransState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/PNonTransState.java @@ -37,7 +37,11 @@ class PNonTransState private static final Localizer _loc = Localizer.forPackage (PNonTransState.class); - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { + if (previous == null) + return; + // spec says all proxies to second class objects should be reset context.proxyFields(true, false); diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java index 9a034e9fc..6ca663ce9 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StateManagerImpl.java @@ -291,7 +291,7 @@ public class StateManagerImpl else _broker.removeFromTransaction(this); - _state.initialize(this); + _state.initialize(this, prev); if (_state.isDeleted() && !wasDeleted) fireLifecycleEvent(LifecycleEvent.AFTER_DELETE); } finally { @@ -356,27 +356,16 @@ public class StateManagerImpl _flush = new BitSet(fmds.length); _dirty = new BitSet(fmds.length); - for (int i = 0; i < fmds.length; i++) { - // mark primary key and non-persistent fields as loaded - if (fmds[i].isPrimaryKey() - || fmds[i].getManagement() != fmds[i].MANAGE_PERSISTENT) - _loaded.set(i); - - if (_meta.getIdentityType() == ClassMetaData.ID_APPLICATION) { - String mappedByIdValue = fmds[i].getMappedByIdValue(); - if (mappedByIdValue != null) { - if (!ApplicationIds.isIdSet(_id, _meta, mappedByIdValue)) { - if (_mappedByIdFields == null) - _mappedByIdFields = new ArrayList(); - _mappedByIdFields.add(fmds[i]); - } - } - } - // record whether there are any managed inverse fields - if (_broker.getInverseManager() != null - && fmds[i].getInverseMetaDatas().length > 0) - _flags |= FLAG_INVERSES; + // mark primary key and non-persistent fields as loaded + for(int i : _meta.getPkAndNonPersistentManagedFmdIndexes()){ + _loaded.set(i); } + + _mappedByIdFields = _meta.getMappyedByIdFields(); + + // record whether there are any managed inverse fields + if (_broker.getInverseManager() != null && _meta.hasInverseManagedFields()) + _flags |= FLAG_INVERSES; pc.pcSetDetachedState(null); _pc = pc; @@ -1592,12 +1581,12 @@ public class StateManagerImpl public void accessingField(int field) { // possibly change state - try { + try { // If this field is loaded, and not a PK field allow pass through // TODO -- what about version fields? Could probably UT this if(_loaded.get(field) && !_meta.getField(field).isPrimaryKey()) return; - + beforeRead(field); beforeAccessField(field); } catch (RuntimeException re) { diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TCleanState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TCleanState.java index 1001e0cf2..a3de3d821 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TCleanState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TCleanState.java @@ -30,11 +30,15 @@ package org.apache.openjpa.kernel; class TCleanState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { + if (previous == null) + return; + // need to replace the second class objects with proxies that // listen for dirtying so we can track changes to these objects context.proxyFields(true, false); - + context.clearSavedFields(); context.setLoaded(true); context.setDirty(false); diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TDirtyState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TDirtyState.java index 5d14a3239..f1ef36be6 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TDirtyState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TDirtyState.java @@ -29,7 +29,8 @@ package org.apache.openjpa.kernel; class TDirtyState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { context.saveFields(false); context.setLoaded(true); context.setDirty(true); diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TLoadedState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TLoadedState.java index 25f680626..c510a87f1 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TLoadedState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TLoadedState.java @@ -31,7 +31,8 @@ package org.apache.openjpa.kernel; class TLoadedState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { context.setLoaded(true); } diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TransientState.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TransientState.java index c50ab5552..9dac4962f 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TransientState.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/TransientState.java @@ -30,7 +30,8 @@ package org.apache.openjpa.kernel; class TransientState extends PCState { - void initialize(StateManagerImpl context) { + @Override + void initialize(StateManagerImpl context, PCState previous) { // mark r/w ok, remove from management context.unproxyFields(); context.getPersistenceCapable().pcReplaceStateManager(null); diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java index 5f52a9bc2..97a3ff551 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/ClassMetaData.java @@ -219,7 +219,11 @@ public class ClassMetaData private boolean _abstract = false; private Boolean _hasAbstractPKField = null; private Boolean _hasPKFieldsFromAbstractClass = null; - + private int[] _pkAndNonPersistentManagedFmdIndexes = null; + private Boolean inverseManagedFields = null; + private List _mappedByIdFields; + private boolean _mappedByIdFieldsSet = false; + /** * Constructor. Supply described type and repository. */ @@ -2763,5 +2767,53 @@ public class ClassMetaData public String getSourceName(){ return _srcName; } -} + + public int[] getPkAndNonPersistentManagedFmdIndexes() { + if (_pkAndNonPersistentManagedFmdIndexes == null) { + List ids = new ArrayList(); + for (FieldMetaData fmd : getFields()) { + if (fmd.isPrimaryKey() || fmd.getManagement() != FieldMetaData.MANAGE_PERSISTENT) { + ids.add(fmd.getIndex()); + } + } + int idsSize = ids.size(); + _pkAndNonPersistentManagedFmdIndexes = new int[idsSize]; + for(int i = 0; i 0){ + inverseManagedFields = Boolean.TRUE; + break; + } + } + } + return inverseManagedFields.booleanValue(); + } + + public List getMappyedByIdFields() { + if (!_mappedByIdFieldsSet) { + List fmdArray = null; + for (FieldMetaData fmd : getFields()) { + if (getIdentityType() == ClassMetaData.ID_APPLICATION) { + String mappedByIdValue = fmd.getMappedByIdValue(); + if (mappedByIdValue != null) { + if (fmdArray == null) { + fmdArray = new ArrayList(); + } + fmdArray.add(fmd); + } + } + } + _mappedByIdFields = fmdArray; + _mappedByIdFieldsSet = true; + } + return _mappedByIdFields; + } +}