Search in sources :

Example 6 with CachedPC

use of org.datanucleus.cache.CachedPC in project tests by datanucleus.

the class CacheTest method testRelationshipCachingWhenNontransactional.

public void testRelationshipCachingWhenNontransactional() throws Exception {
    try {
        PersistenceManager pm = pmf.getPersistenceManager();
        Transaction tx = pm.currentTransaction();
        // Create sample data
        Object acctId = null;
        try {
            tx.begin();
            LoginAccount acct = new LoginAccount("Barney", "Rubble", "brubble", "bambam");
            pm.makePersistent(acct);
            acctId = JDOHelper.getObjectId(acct);
            tx.commit();
        } catch (Exception e) {
            LOG.error(e);
            fail("Exception thrown while creating 1-1 unidirectional relationship data : " + e.getMessage());
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
            pm.close();
        }
        // Make sure the object isn't in the cache following persistence
        pmf.getDataStoreCache().evictAll();
        pmf.getDataStoreCache().pinAll(true, LoginAccount.class);
        pmf.getDataStoreCache().pinAll(true, Login.class);
        // Retrieve the record and check the data
        pm = pmf.getPersistenceManager();
        try {
            LOG.info(">> CacheTest fetching LoginAccount(1)");
            LoginAccount acct = (LoginAccount) pm.getObjectById(acctId);
            assertTrue("LoginAccount \"firstName\" is incorrect", acct.getFirstName().equals("Barney"));
            assertTrue("LoginAccount \"lastName\" is incorrect", acct.getLastName().equals("Rubble"));
            LOG.info(">> CacheTest fetching Login(1)");
            // Access the login field to make sure it is read. Should get L2 cached now
            Login login = acct.getLogin();
            assertEquals("Login \"login\" is incorrect", login.getUserName(), "brubble");
            assertEquals("Login \"password\" is incorrect", login.getPassword(), "bambam");
        } catch (Exception e) {
            LOG.error(e);
            fail("Exception thrown while interrogating 1-1 unidirectional relationship data : " + e.getMessage());
        } finally {
            pm.close();
        }
        // login account is in the cache now after the last getObjectById
        LOG.info(">> CacheTest fetching LoginAccount(non-tx)");
        CachedPC cpc = ((JDOPersistenceManagerFactory) pmf).getNucleusContext().getLevel2Cache().get(acctId);
        assertTrue("LoginAccount is not cached", cpc != null);
        assertTrue("LoginAccount \"login\" is not cached", cpc.getFieldValue(2) != null);
        // Retrieve the record and check the data
        pm = pmf.getPersistenceManager();
        try {
            LoginAccount acct = (LoginAccount) pm.getObjectById(acctId);
            String[] loadedFields = NucleusJDOHelper.getLoadedFields(acct, pm);
            LOG.info(">> loadedFields=" + StringUtils.objectArrayToString(loadedFields));
            LOG.info(">> Accessing field login");
            Login login = acct.getLogin();
            LOG.info(">> login=" + login);
        } finally {
            pm.close();
        }
    } finally {
        clean(LoginAccount.class);
    }
}
Also used : Transaction(javax.jdo.Transaction) PersistenceManager(javax.jdo.PersistenceManager) LoginAccount(org.jpox.samples.one_one.unidir.LoginAccount) CachedPC(org.datanucleus.cache.CachedPC) Login(org.jpox.samples.one_one.unidir.Login) JDOPersistenceManagerFactory(org.datanucleus.api.jdo.JDOPersistenceManagerFactory) JDOObjectNotFoundException(javax.jdo.JDOObjectNotFoundException)

Example 7 with CachedPC

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

Example 8 with CachedPC

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

CachedPC (org.datanucleus.cache.CachedPC)8 Level2Cache (org.datanucleus.cache.Level2Cache)6 ObjectProvider (org.datanucleus.state.ObjectProvider)4 HashMap (java.util.HashMap)2 CacheUniqueKey (org.datanucleus.cache.CacheUniqueKey)2 L2CachePopulateFieldManager (org.datanucleus.cache.L2CachePopulateFieldManager)2 IdentityReference (org.datanucleus.identity.IdentityReference)2 UniqueMetaData (org.datanucleus.metadata.UniqueMetaData)2 ConcurrentReferenceHashMap (org.datanucleus.util.ConcurrentReferenceHashMap)2 BitSet (java.util.BitSet)1 Map (java.util.Map)1 JDOObjectNotFoundException (javax.jdo.JDOObjectNotFoundException)1 PersistenceManager (javax.jdo.PersistenceManager)1 Transaction (javax.jdo.Transaction)1 JDOPersistenceManagerFactory (org.datanucleus.api.jdo.JDOPersistenceManagerFactory)1 Persistable (org.datanucleus.enhancement.Persistable)1 Login (org.jpox.samples.one_one.unidir.Login)1 LoginAccount (org.jpox.samples.one_one.unidir.LoginAccount)1