Search in sources :

Example 1 with L2CachePopulateFieldManager

use of org.datanucleus.cache.L2CachePopulateFieldManager 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;
}
Also used : CachedPC(org.datanucleus.cache.CachedPC) BitSet(java.util.BitSet) L2CachePopulateFieldManager(org.datanucleus.cache.L2CachePopulateFieldManager)

Example 2 with L2CachePopulateFieldManager

use of org.datanucleus.cache.L2CachePopulateFieldManager in project datanucleus-core by datanucleus.

the class StateManagerImpl method updateLevel2CacheForFields.

/**
 * Convenience method to update a Level2 cached version of this object if cacheable
 * and has not been modified during this transaction.
 * @param fieldNumbers Numbers of fields to update in L2 cached object
 */
protected void updateLevel2CacheForFields(int[] fieldNumbers) {
    String updateMode = (String) myEC.getProperty(PropertyNames.PROPERTY_CACHE_L2_UPDATE_MODE);
    if (updateMode != null && updateMode.equalsIgnoreCase("commit-only")) {
        return;
    }
    if (fieldNumbers == null || fieldNumbers.length == 0) {
        return;
    }
    Level2Cache l2cache = myEC.getNucleusContext().getLevel2Cache();
    if (l2cache != null && myEC.getNucleusContext().isClassCacheable(cmd) && !myEC.isObjectModifiedInTransaction(myID)) {
        CachedPC<Persistable> cachedPC = l2cache.get(myID);
        if (cachedPC != null) {
            // This originally just updated the L2 cache for fields where the L2 cache didn't have a value for that field, like this
            /*
                int[] cacheFieldsToLoad = ClassUtils.getFlagsSetTo(cachedPC.getLoadedFields(), fieldNumbers, false);
                if (cacheFieldsToLoad == null || cacheFieldsToLoad.length == 0)
                {
                    return;
                }
                */
            int[] cacheFieldsToLoad = fieldNumbers;
            CachedPC copyCachedPC = cachedPC.getCopy();
            if (NucleusLogger.CACHE.isDebugEnabled()) {
                NucleusLogger.CACHE.debug(Localiser.msg("026033", StringUtils.toJVMIDString(getObject()), myID, StringUtils.intArrayToString(cacheFieldsToLoad)));
            }
            provideFields(cacheFieldsToLoad, new L2CachePopulateFieldManager(this, copyCachedPC));
            // Replace the current L2 cached object with this one
            myEC.getNucleusContext().getLevel2Cache().put(getInternalObjectId(), copyCachedPC);
        }
    }
}
Also used : Persistable(org.datanucleus.enhancement.Persistable) Level2Cache(org.datanucleus.cache.Level2Cache) CachedPC(org.datanucleus.cache.CachedPC) L2CachePopulateFieldManager(org.datanucleus.cache.L2CachePopulateFieldManager)

Aggregations

CachedPC (org.datanucleus.cache.CachedPC)2 L2CachePopulateFieldManager (org.datanucleus.cache.L2CachePopulateFieldManager)2 BitSet (java.util.BitSet)1 Level2Cache (org.datanucleus.cache.Level2Cache)1 Persistable (org.datanucleus.enhancement.Persistable)1