Search in sources :

Example 1 with CacheUniqueKey

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

the class ExecutionContextImpl method getCacheUniqueKeyForObjectProvider.

/**
 * Method to return a CacheUniqueKey to use when caching the object managed by the supplied ObjectProvider for the specified unique key.
 * @param op The ObjectProvider
 * @param unimd The unique key that this key will relate to
 * @return The CacheUniqueKey, or null if any member of the unique key is null, or if the unique key is not defined on members
 */
private CacheUniqueKey getCacheUniqueKeyForObjectProvider(ObjectProvider op, UniqueMetaData unimd) {
    boolean nonNullMembers = true;
    if (unimd.getNumberOfMembers() > 0) {
        Object[] fieldVals = new Object[unimd.getNumberOfMembers()];
        for (int i = 0; i < fieldVals.length; i++) {
            AbstractMemberMetaData mmd = op.getClassMetaData().getMetaDataForMember(unimd.getMemberNames()[i]);
            fieldVals[i] = op.provideField(mmd.getAbsoluteFieldNumber());
            if (fieldVals[i] == null) {
                // One of the unique key fields is null so we don't cache
                nonNullMembers = false;
                break;
            }
        }
        if (nonNullMembers) {
            return new CacheUniqueKey(op.getClassMetaData().getFullClassName(), unimd.getMemberNames(), fieldVals);
        }
    }
    return null;
}
Also used : AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) CacheUniqueKey(org.datanucleus.cache.CacheUniqueKey)

Example 2 with CacheUniqueKey

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

the class ExecutionContextImpl method findObjectByUnique.

/* (non-Javadoc)
     * @see org.datanucleus.ExecutionContext#findObjectByUnique(java.lang.Class, java.lang.String[], java.lang.Object[])
     */
@Override
public <T> T findObjectByUnique(Class<T> cls, String[] memberNames, Object[] memberValues) {
    if (cls == null || memberNames == null || memberNames.length == 0 || memberValues == null || memberValues.length == 0) {
        throw new NucleusUserException(Localiser.msg("010053", cls, StringUtils.objectArrayToString(memberNames), StringUtils.objectArrayToString(memberValues)));
    }
    // Check class and member existence
    AbstractClassMetaData cmd = getMetaDataManager().getMetaDataForClass(cls, clr);
    if (cmd == null) {
        throw new NucleusUserException(Localiser.msg("010052", cls.getName()));
    }
    for (String memberName : memberNames) {
        AbstractMemberMetaData mmd = cmd.getMetaDataForMember(memberName);
        if (mmd == null) {
            throw new NucleusUserException("Attempt to find object using unique key of class " + cmd.getFullClassName() + " but field " + memberName + " doesnt exist!");
        }
    }
    // Check whether this is cached against the unique key
    CacheUniqueKey uniKey = new CacheUniqueKey(cls.getName(), memberNames, memberValues);
    ObjectProvider op = cache.getUnique(uniKey);
    if (op == null && l2CacheEnabled) {
        if (NucleusLogger.CACHE.isDebugEnabled()) {
            NucleusLogger.CACHE.debug(Localiser.msg("003007", uniKey));
        }
        // Try L2 cache
        Object pc = getObjectFromLevel2CacheForUnique(uniKey);
        if (pc != null) {
            op = findObjectProvider(pc);
        }
    }
    if (op != null) {
        return (T) op.getObject();
    }
    return (T) getStoreManager().getPersistenceHandler().findObjectForUnique(this, cmd, memberNames, memberValues);
}
Also used : NucleusUserException(org.datanucleus.exceptions.NucleusUserException) ObjectProvider(org.datanucleus.state.ObjectProvider) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) AbstractClassMetaData(org.datanucleus.metadata.AbstractClassMetaData) CacheUniqueKey(org.datanucleus.cache.CacheUniqueKey)

Example 3 with CacheUniqueKey

use of org.datanucleus.cache.CacheUniqueKey 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 4 with CacheUniqueKey

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

the class ExecutionContextImpl method putObjectIntoLevel1Cache.

/**
 * Convenience method to add an object to the L1 cache.
 * @param op The ObjectProvider
 */
public void putObjectIntoLevel1Cache(ObjectProvider op) {
    if (cache != null) {
        Object id = op.getInternalObjectId();
        if (id == null || op.getObject() == null) {
            NucleusLogger.CACHE.warn(Localiser.msg("003006"));
            return;
        }
        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) {
                        cache.putUnique(uniKey, op);
                    }
                }
            }
        }
        // Put into Level 1 Cache
        Object oldOP = cache.put(id, op);
        if (NucleusLogger.CACHE.isDebugEnabled()) {
            if (oldOP == null) {
                NucleusLogger.CACHE.debug(Localiser.msg("003004", StringUtils.toJVMIDString(op.getObject()), IdentityUtils.getPersistableIdentityForId(id), StringUtils.booleanArrayToString(op.getLoadedFields())));
            }
        }
    }
}
Also used : UniqueMetaData(org.datanucleus.metadata.UniqueMetaData) CacheUniqueKey(org.datanucleus.cache.CacheUniqueKey)

Example 5 with CacheUniqueKey

use of org.datanucleus.cache.CacheUniqueKey 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

CacheUniqueKey (org.datanucleus.cache.CacheUniqueKey)5 UniqueMetaData (org.datanucleus.metadata.UniqueMetaData)3 CachedPC (org.datanucleus.cache.CachedPC)2 Level2Cache (org.datanucleus.cache.Level2Cache)2 IdentityReference (org.datanucleus.identity.IdentityReference)2 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)2 ObjectProvider (org.datanucleus.state.ObjectProvider)2 HashMap (java.util.HashMap)1 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)1 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)1 ConcurrentReferenceHashMap (org.datanucleus.util.ConcurrentReferenceHashMap)1