use of org.datanucleus.cache.CachedPC in project datanucleus-core by datanucleus.
the class ExecutionContextImpl method getObjectFromLevel2Cache.
/**
* Convenience method to access an object in the Level 2 cache.
* @param id Id of the object
* @return Persistable object (with connected ObjectProvider).
*/
protected Object getObjectFromLevel2Cache(Object id) {
Object pc = null;
if (l2CacheEnabled) {
if (!nucCtx.isClassWithIdentityCacheable(id)) {
return null;
}
String cacheRetrieveMode = getLevel2CacheRetrieveMode();
if ("bypass".equalsIgnoreCase(cacheRetrieveMode)) {
// Cache retrieval currently turned off
return null;
}
Level2Cache l2Cache = nucCtx.getLevel2Cache();
CachedPC cachedPC = l2Cache.get(id);
if (cachedPC != null) {
// Create active version of cached object with ObjectProvider connected and same id
ObjectProvider op = nucCtx.getObjectProviderFactory().newForCachedPC(this, id, cachedPC);
// Object in P_CLEAN state
pc = op.getObject();
if (NucleusLogger.CACHE.isDebugEnabled()) {
NucleusLogger.CACHE.debug(Localiser.msg("004006", IdentityUtils.getPersistableIdentityForId(id), StringUtils.intArrayToString(cachedPC.getLoadedFieldNumbers()), cachedPC.getVersion(), StringUtils.toJVMIDString(pc)));
}
if (tx.isActive() && tx.getOptimistic()) {
// Optimistic txns, so return as P_NONTRANS (as per JDO spec)
op.makeNontransactional();
} else if (!tx.isActive() && getApiAdapter().isTransactional(pc)) {
// Non-tx context, so return as P_NONTRANS (as per JDO spec)
op.makeNontransactional();
}
return pc;
}
if (NucleusLogger.CACHE.isDebugEnabled()) {
NucleusLogger.CACHE.debug(Localiser.msg("004005", IdentityUtils.getPersistableIdentityForId(id)));
}
}
return null;
}
use of org.datanucleus.cache.CachedPC in project datanucleus-core by datanucleus.
the class ExecutionContextImpl method getObjectFromLevel2CacheForUnique.
/**
* Convenience method to access the identity that corresponds to a unique key, in the Level 2 cache.
* @param uniKey The CacheUniqueKey to use in lookups
* @return Identity of the associated object
*/
protected Object getObjectFromLevel2CacheForUnique(CacheUniqueKey uniKey) {
Object pc = null;
if (l2CacheEnabled) {
String cacheRetrieveMode = getLevel2CacheRetrieveMode();
if ("bypass".equalsIgnoreCase(cacheRetrieveMode)) {
// Cache retrieval currently turned off
return null;
}
Level2Cache l2Cache = nucCtx.getLevel2Cache();
CachedPC cachedPC = l2Cache.getUnique(uniKey);
if (cachedPC != null) {
Object id = cachedPC.getId();
// Create active version of cached object with ObjectProvider connected and same id
ObjectProvider op = nucCtx.getObjectProviderFactory().newForCachedPC(this, id, cachedPC);
// Object in P_CLEAN state
pc = op.getObject();
if (NucleusLogger.CACHE.isDebugEnabled()) {
NucleusLogger.CACHE.debug(Localiser.msg("004006", IdentityUtils.getPersistableIdentityForId(id), StringUtils.intArrayToString(cachedPC.getLoadedFieldNumbers()), cachedPC.getVersion(), StringUtils.toJVMIDString(pc)));
}
if (tx.isActive() && tx.getOptimistic()) {
// Optimistic txns, so return as P_NONTRANS (as per JDO spec)
op.makeNontransactional();
} else if (!tx.isActive() && getApiAdapter().isTransactional(pc)) {
// Non-tx context, so return as P_NONTRANS (as per JDO spec)
op.makeNontransactional();
}
return pc;
}
if (NucleusLogger.CACHE.isDebugEnabled()) {
NucleusLogger.CACHE.debug(Localiser.msg("004005", uniKey));
}
}
return null;
}
use of org.datanucleus.cache.CachedPC in project datanucleus-core by datanucleus.
the class ExecutionContextImpl method getL2CacheableObject.
/**
* Convenience method to convert the object managed by the ObjectProvider into a form suitable for caching in an L2 cache.
* @param op ObjectProvider for the object
* @param currentCachedPC Current L2 cached object (if any) to use for updating
* @return The cacheable form of the object
*/
protected CachedPC getL2CacheableObject(ObjectProvider op, CachedPC currentCachedPC) {
CachedPC cachedPC = null;
int[] fieldsToUpdate = null;
if (currentCachedPC != null) {
// Object already L2 cached, create copy of cached object and just update the fields changed here
cachedPC = currentCachedPC.getCopy();
cachedPC.setVersion(op.getTransactionalVersion());
BitSet fieldsToUpdateBitSet = l2CacheTxFieldsToUpdateById.get(op.getInternalObjectId());
if (fieldsToUpdateBitSet != null) {
int num = 0;
for (int i = 0; i < fieldsToUpdateBitSet.length(); i++) {
if (fieldsToUpdateBitSet.get(i)) {
num++;
}
}
fieldsToUpdate = new int[num];
int j = 0;
for (int i = 0; i < fieldsToUpdateBitSet.length(); i++) {
if (fieldsToUpdateBitSet.get(i)) {
fieldsToUpdate[j++] = i;
}
}
}
if (fieldsToUpdate == null || fieldsToUpdate.length == 0) {
return null;
}
if (NucleusLogger.CACHE.isDebugEnabled()) {
int[] loadedFieldNums = cachedPC.getLoadedFieldNumbers();
String fieldNames = (loadedFieldNums == null || loadedFieldNums.length == 0) ? "" : StringUtils.intArrayToString(loadedFieldNums);
NucleusLogger.CACHE.debug(Localiser.msg("004015", StringUtils.toJVMIDString(op.getObject()), op.getInternalObjectId(), fieldNames, cachedPC.getVersion(), StringUtils.intArrayToString(fieldsToUpdate)));
}
} else {
// Not yet cached
int[] loadedFieldNumbers = op.getLoadedFieldNumbers();
if (loadedFieldNumbers == null || loadedFieldNumbers.length == 0) {
// No point caching an object with no loaded fields!
return null;
}
cachedPC = new CachedPC(op.getObject().getClass(), op.getLoadedFields(), op.getTransactionalVersion(), op.getInternalObjectId());
fieldsToUpdate = loadedFieldNumbers;
if (NucleusLogger.CACHE.isDebugEnabled()) {
int[] loadedFieldNums = cachedPC.getLoadedFieldNumbers();
String fieldNames = (loadedFieldNums == null || loadedFieldNums.length == 0) ? "" : StringUtils.intArrayToString(loadedFieldNums);
NucleusLogger.CACHE.debug(Localiser.msg("004003", StringUtils.toJVMIDString(op.getObject()), op.getInternalObjectId(), fieldNames, cachedPC.getVersion()));
}
}
// Set the fields in the CachedPC
op.provideFields(fieldsToUpdate, new L2CachePopulateFieldManager(op, cachedPC));
return cachedPC;
}
use of org.datanucleus.cache.CachedPC in project datanucleus-core by datanucleus.
the class ExecutionContextImpl method putObjectIntoLevel2CacheInternal.
/**
* Convenience method to add/update an object in the L2 cache.
* @param op ObjectProvider of the object to add.
* @param updateIfPresent Whether to update the L2 cache if it is present
*/
protected void putObjectIntoLevel2CacheInternal(ObjectProvider op, boolean updateIfPresent) {
Object id = op.getInternalObjectId();
if (id == null || id instanceof IdentityReference) {
return;
}
Level2Cache l2Cache = nucCtx.getLevel2Cache();
if (!updateIfPresent && l2Cache.containsOid(id)) {
// Already present and not wanting to update
return;
}
CachedPC currentCachedPC = l2Cache.get(id);
CachedPC cachedPC = getL2CacheableObject(op, currentCachedPC);
if (cachedPC != null) {
l2Cache.put(id, cachedPC);
}
if (op.getClassMetaData().getUniqueMetaData() != null) {
// Cache against any unique keys defined for this object
List<UniqueMetaData> unimds = op.getClassMetaData().getUniqueMetaData();
if (unimds != null && !unimds.isEmpty()) {
for (UniqueMetaData unimd : unimds) {
CacheUniqueKey uniKey = getCacheUniqueKeyForObjectProvider(op, unimd);
if (uniKey != null) {
l2Cache.putUnique(uniKey, cachedPC);
}
}
}
}
}
use of org.datanucleus.cache.CachedPC in project datanucleus-core by datanucleus.
the class ExecutionContextImpl method getObjectsFromLevel2Cache.
/**
* Convenience method to access a collection of objects from the Level 2 cache.
* @param ids Collection of ids to retrieve
* @return Map of persistable objects (with connected ObjectProvider) keyed by their id if found in the L2 cache
*/
protected Map getObjectsFromLevel2Cache(Collection ids) {
if (l2CacheEnabled) {
// TODO Restrict to only those ids that are cacheable
Level2Cache l2Cache = nucCtx.getLevel2Cache();
Map<Object, CachedPC> cachedPCs = l2Cache.getAll(ids);
Map pcsById = new HashMap(cachedPCs.size());
for (Map.Entry<Object, CachedPC> entry : cachedPCs.entrySet()) {
Object id = entry.getKey();
CachedPC cachedPC = entry.getValue();
if (cachedPC != null) {
// Create active version of cached object with ObjectProvider connected and same id
ObjectProvider op = nucCtx.getObjectProviderFactory().newForCachedPC(this, id, cachedPC);
// Object in P_CLEAN state
Object pc = op.getObject();
if (NucleusLogger.CACHE.isDebugEnabled()) {
NucleusLogger.CACHE.debug(Localiser.msg("004006", IdentityUtils.getPersistableIdentityForId(id), StringUtils.intArrayToString(cachedPC.getLoadedFieldNumbers()), cachedPC.getVersion(), StringUtils.toJVMIDString(pc)));
}
if (tx.isActive() && tx.getOptimistic()) {
// Optimistic txns, so return as P_NONTRANS (as per JDO spec)
op.makeNontransactional();
} else if (!tx.isActive() && getApiAdapter().isTransactional(pc)) {
// Non-tx context, so return as P_NONTRANS (as per JDO spec)
op.makeNontransactional();
}
pcsById.put(id, pc);
} else {
if (NucleusLogger.CACHE.isDebugEnabled()) {
NucleusLogger.CACHE.debug(Localiser.msg("004005", IdentityUtils.getPersistableIdentityForId(id)));
}
}
}
return pcsById;
}
return null;
}
Aggregations