Search in sources :

Example 1 with IdentityReference

use of org.datanucleus.identity.IdentityReference 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);
                }
            }
        }
    }
}
Also used : IdentityReference(org.datanucleus.identity.IdentityReference) Level2Cache(org.datanucleus.cache.Level2Cache) CachedPC(org.datanucleus.cache.CachedPC) UniqueMetaData(org.datanucleus.metadata.UniqueMetaData) CacheUniqueKey(org.datanucleus.cache.CacheUniqueKey)

Example 2 with IdentityReference

use of org.datanucleus.identity.IdentityReference in project datanucleus-core by datanucleus.

the class ExecutionContextImpl method performLevel2CacheUpdateAtCommit.

/**
 * Method invoked during commit() to perform updates to the L2 cache.
 * <ul>
 * <li>Any objects modified during the current transaction will be added/updated in the L2 cache.</li>
 * <li>Any objects that aren't modified but have been enlisted will be added to the L2 cache.</li>
 * <li>Any objects that are modified but no longer enlisted (due to garbage collection) will be
 * removed from the L2 cache (to avoid giving out old data).</li>
 * </ul>
 */
private void performLevel2CacheUpdateAtCommit() {
    if (l2CacheTxIds == null) {
        return;
    }
    String cacheStoreMode = getLevel2CacheStoreMode();
    if ("bypass".equalsIgnoreCase(cacheStoreMode)) {
        // L2 cache storage turned off right now
        return;
    }
    // Process all modified objects adding/updating/removing from L2 cache as appropriate
    Set<ObjectProvider> opsToCache = null;
    Set<Object> idsToRemove = null;
    for (Object id : l2CacheTxIds) {
        ObjectProvider op = enlistedOPCache.get(id);
        if (op == null) {
            // Modified object either no longer enlisted (GCed) OR is an embedded object without own identity. Remove from L2 if present
            if (NucleusLogger.CACHE.isDebugEnabled()) {
                if (nucCtx.getLevel2Cache().containsOid(id)) {
                    NucleusLogger.CACHE.debug(Localiser.msg("004014", id));
                }
            }
            if (idsToRemove == null) {
                idsToRemove = new HashSet<Object>();
            }
            idsToRemove.add(id);
        } else {
            // Modified object still enlisted so cacheable
            Object obj = op.getObject();
            Object objID = getApiAdapter().getIdForObject(obj);
            if (objID == null || objID instanceof IdentityReference) {
            // Must be embedded
            } else if (getApiAdapter().isDeleted(obj)) {
                // Object has been deleted so remove from L2 cache
                if (NucleusLogger.CACHE.isDebugEnabled()) {
                    NucleusLogger.CACHE.debug(Localiser.msg("004007", StringUtils.toJVMIDString(obj), op.getInternalObjectId()));
                }
                if (idsToRemove == null) {
                    idsToRemove = new HashSet<Object>();
                }
                idsToRemove.add(objID);
            } else if (!getApiAdapter().isDetached(obj)) {
                // Object has been added/modified so update in L2 cache
                if (opsToCache == null) {
                    opsToCache = new HashSet<>();
                }
                opsToCache.add(op);
                if (l2CacheObjectsToEvictUponRollback == null) {
                    l2CacheObjectsToEvictUponRollback = new LinkedList<Object>();
                }
                l2CacheObjectsToEvictUponRollback.add(id);
            }
        }
    }
    if (idsToRemove != null && !idsToRemove.isEmpty()) {
        // Bulk evict from L2 cache
        nucCtx.getLevel2Cache().evictAll(idsToRemove);
    }
    if (opsToCache != null && !opsToCache.isEmpty()) {
        // Bulk put into L2 cache of required ObjectProviders
        putObjectsIntoLevel2Cache(opsToCache);
    }
    l2CacheTxIds.clear();
    l2CacheTxFieldsToUpdateById.clear();
}
Also used : IdentityReference(org.datanucleus.identity.IdentityReference) ObjectProvider(org.datanucleus.state.ObjectProvider) HashSet(java.util.HashSet)

Example 3 with IdentityReference

use of org.datanucleus.identity.IdentityReference in project datanucleus-core by datanucleus.

the class ExecutionContextImpl method putObjectsIntoLevel2Cache.

/**
 * Method to put the passed objects into the L2 cache.
 * Performs the "put" in batches
 * @param ops The ObjectProviders whose objects are to be cached
 */
protected void putObjectsIntoLevel2Cache(Set<ObjectProvider> ops) {
    int batchSize = nucCtx.getConfiguration().getIntProperty(PropertyNames.PROPERTY_CACHE_L2_BATCHSIZE);
    Level2Cache l2Cache = nucCtx.getLevel2Cache();
    Map<Object, CachedPC> dataToUpdate = new HashMap<>();
    Map<CacheUniqueKey, CachedPC> dataUniqueToUpdate = new HashMap<>();
    for (ObjectProvider op : ops) {
        Object id = op.getInternalObjectId();
        if (id == null || !nucCtx.isClassCacheable(op.getClassMetaData())) {
            continue;
        }
        CachedPC currentCachedPC = l2Cache.get(id);
        CachedPC cachedPC = getL2CacheableObject(op, currentCachedPC);
        if (cachedPC != null && id != null && !(id instanceof IdentityReference)) {
            // Only cache if something to be cached and has identity
            dataToUpdate.put(id, cachedPC);
            if (dataToUpdate.size() == batchSize) {
                // Put this batch of objects in the L2 cache
                l2Cache.putAll(dataToUpdate);
                dataToUpdate.clear();
            }
        }
        if (op.getClassMetaData().getUniqueMetaData() != null) {
            // Check for any unique keys on this object, and cache against the unique key also
            List<UniqueMetaData> unimds = op.getClassMetaData().getUniqueMetaData();
            if (unimds != null && !unimds.isEmpty()) {
                for (UniqueMetaData unimd : unimds) {
                    CacheUniqueKey uniKey = getCacheUniqueKeyForObjectProvider(op, unimd);
                    if (uniKey != null) {
                        dataUniqueToUpdate.put(uniKey, cachedPC);
                        if (dataUniqueToUpdate.size() == batchSize) {
                            // Put this batch of unique keyed objects in the L2 cache
                            l2Cache.putUniqueAll(dataUniqueToUpdate);
                            dataUniqueToUpdate.clear();
                        }
                    }
                }
            }
        }
    }
    // Put all remaining objects
    if (!dataToUpdate.isEmpty()) {
        l2Cache.putAll(dataToUpdate);
        dataToUpdate.clear();
    }
    if (!dataUniqueToUpdate.isEmpty()) {
        l2Cache.putUniqueAll(dataUniqueToUpdate);
        dataUniqueToUpdate.clear();
    }
}
Also used : IdentityReference(org.datanucleus.identity.IdentityReference) Level2Cache(org.datanucleus.cache.Level2Cache) ConcurrentReferenceHashMap(org.datanucleus.util.ConcurrentReferenceHashMap) HashMap(java.util.HashMap) CachedPC(org.datanucleus.cache.CachedPC) ObjectProvider(org.datanucleus.state.ObjectProvider) UniqueMetaData(org.datanucleus.metadata.UniqueMetaData) CacheUniqueKey(org.datanucleus.cache.CacheUniqueKey)

Aggregations

IdentityReference (org.datanucleus.identity.IdentityReference)3 CacheUniqueKey (org.datanucleus.cache.CacheUniqueKey)2 CachedPC (org.datanucleus.cache.CachedPC)2 Level2Cache (org.datanucleus.cache.Level2Cache)2 UniqueMetaData (org.datanucleus.metadata.UniqueMetaData)2 ObjectProvider (org.datanucleus.state.ObjectProvider)2 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 ConcurrentReferenceHashMap (org.datanucleus.util.ConcurrentReferenceHashMap)1