use of org.datanucleus.cache.L2CacheRetrieveFieldManager in project datanucleus-core by datanucleus.
the class StateManagerImpl method initialiseForCachedPC.
/**
* Initialise the ObjectProvider, assigning the specified id to the object.
* This is used when getting objects out of the L2 Cache, where they have no ObjectProvider
* assigned, and returning them as associated with a particular ExecutionContext.
* @param cachedPC The cached PC object
* @param id Id to assign to the Persistable object
*/
public void initialiseForCachedPC(CachedPC<Persistable> cachedPC, Object id) {
// Create a new copy of the input object type, performing the majority of the initialisation
initialiseForHollow(id, null, cachedPC.getObjectClass());
myLC = myEC.getNucleusContext().getApiAdapter().getLifeCycleState(LifeCycleState.P_CLEAN);
persistenceFlags = Persistable.READ_OK;
int[] fieldsToLoad = ClassUtils.getFlagsSetTo(cachedPC.getLoadedFields(), myFP.getMemberNumbers(), true);
if (fieldsToLoad != null) {
// Put this object in L1 cache for easy referencing
myEC.putObjectIntoLevel1Cache(this);
L2CacheRetrieveFieldManager l2RetFM = new L2CacheRetrieveFieldManager(this, cachedPC);
this.replaceFields(fieldsToLoad, l2RetFM);
for (int i = 0; i < fieldsToLoad.length; i++) {
loadedFields[fieldsToLoad[i]] = true;
}
int[] fieldsNotLoaded = l2RetFM.getFieldsNotLoaded();
if (fieldsNotLoaded != null) {
for (int i = 0; i < fieldsNotLoaded.length; i++) {
loadedFields[fieldsNotLoaded[i]] = false;
}
}
}
if (cachedPC.getVersion() != null) {
// Make sure we start from the same version as was cached
setVersion(cachedPC.getVersion());
}
// Make sure any SCO fields are wrapped
replaceAllLoadedSCOFieldsWithWrappers();
if (myEC.getTransaction().isActive()) {
myEC.enlistInTransaction(this);
}
if (areFieldsLoaded(myFP.getMemberNumbers())) {
// Should we call postLoad when getting the object out of the L2 cache ? Seems incorrect IMHO
postLoad();
}
}
use of org.datanucleus.cache.L2CacheRetrieveFieldManager in project datanucleus-core by datanucleus.
the class StateManagerImpl method loadFieldsFromLevel2Cache.
/**
* Convenience method to retrieve field values from an L2 cached object if they are loaded in that object.
* If the object is not in the L2 cache then just returns, and similarly if the required fields aren't available.
* @param fieldNumbers Numbers of fields to load from the L2 cache
* @return The fields that couldn't be loaded
*/
protected int[] loadFieldsFromLevel2Cache(int[] fieldNumbers) {
// Only continue if there are fields, and not being deleted/flushed etc
if (fieldNumbers == null || fieldNumbers.length == 0 || myEC.isFlushing() || myLC.isDeleted() || isDeleting() || getExecutionContext().getTransaction().isCommitting()) {
return fieldNumbers;
}
// TODO Drop this check when we're confident that this doesn't affect some use-cases
if (!myEC.getNucleusContext().getConfiguration().getBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_LOADFIELDS, true)) {
return fieldNumbers;
}
Level2Cache l2cache = myEC.getNucleusContext().getLevel2Cache();
if (l2cache != null && myEC.getNucleusContext().isClassCacheable(cmd)) {
CachedPC<Persistable> cachedPC = l2cache.get(myID);
if (cachedPC != null) {
int[] cacheFieldsToLoad = ClassUtils.getFlagsSetTo(cachedPC.getLoadedFields(), fieldNumbers, true);
if (cacheFieldsToLoad != null && cacheFieldsToLoad.length > 0) {
if (NucleusLogger.CACHE.isDebugEnabled()) {
NucleusLogger.CACHE.debug(Localiser.msg("026034", StringUtils.toJVMIDString(getObject()), myID, StringUtils.intArrayToString(cacheFieldsToLoad)));
}
L2CacheRetrieveFieldManager l2RetFM = new L2CacheRetrieveFieldManager(this, cachedPC);
this.replaceFields(cacheFieldsToLoad, l2RetFM);
int[] fieldsNotLoaded = l2RetFM.getFieldsNotLoaded();
if (fieldsNotLoaded != null) {
for (int i = 0; i < fieldsNotLoaded.length; i++) {
loadedFields[fieldsNotLoaded[i]] = false;
}
}
}
}
}
return ClassUtils.getFlagsSetTo(loadedFields, fieldNumbers, false);
}
Aggregations