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;
}
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);
}
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);
}
}
}
}
}
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())));
}
}
}
}
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();
}
}
Aggregations