Search in sources :

Example 11 with Level2Cache

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

the class CacheTest method testL2CacheAfterReadApplicationIdentity.

/**
 * Test for storage of an object in the L2 cache from a query or from getObjectById.
 */
public void testL2CacheAfterReadApplicationIdentity() {
    Properties userProps = new Properties();
    userProps.setProperty(PropertyNames.PROPERTY_CACHE_L1_TYPE, "weak");
    userProps.setProperty(PropertyNames.PROPERTY_CACHE_L2_TYPE, "weak");
    PersistenceManagerFactory cachePMF = getPMF(1, userProps);
    try {
        // Create some data we can use for access
        PersistenceManager pm = cachePMF.getPersistenceManager();
        Transaction tx = pm.currentTransaction();
        try {
            DataStoreCache l2Cache = cachePMF.getDataStoreCache();
            l2Cache.pinAll(true, Vote.class);
            tx.begin();
            Vote vote1 = new Vote(1, "Vote 1");
            pm.makePersistent(vote1);
            Vote vote2 = new Vote(2, "Vote 2");
            pm.makePersistent(vote2);
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            fail("Error persisting basic data necessary to run optimistic L2 test");
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
            pm.close();
        }
        Level2Cache l2Cache = ((JDODataStoreCache) cachePMF.getDataStoreCache()).getLevel2Cache();
        assertEquals("Incorrect number of pinned objects", 2, l2Cache.getNumberOfPinnedObjects());
        assertEquals("Incorrect number of unpinned objects", 0, l2Cache.getNumberOfUnpinnedObjects());
        l2Cache.evictAll();
        assertEquals("Incorrect number of pinned objects after evict", 0, l2Cache.getNumberOfPinnedObjects());
        assertEquals("Incorrect number of unpinned objects after evict", 0, l2Cache.getNumberOfUnpinnedObjects());
        // Try getObjectById
        pm = cachePMF.getPersistenceManager();
        tx = pm.currentTransaction();
        try {
            tx.begin();
            Vote vote1 = pm.getObjectById(Vote.class, 1);
            Vote vote2 = pm.getObjectById(Vote.class, 2);
            assertNotNull(vote1);
            assertNotNull(vote2);
            assertEquals("Incorrect number of pinned objects after getObjectById", 2, l2Cache.getNumberOfPinnedObjects());
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            fail("Error updating object that was retrieved from the L2 cache : " + e.getMessage());
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
            pm.close();
        }
        assertEquals("Incorrect number of pinned objects", 2, l2Cache.getNumberOfPinnedObjects());
        assertEquals("Incorrect number of unpinned objects", 0, l2Cache.getNumberOfUnpinnedObjects());
        l2Cache.evictAll();
        assertEquals("Incorrect number of pinned objects after evict", 0, l2Cache.getNumberOfPinnedObjects());
        assertEquals("Incorrect number of unpinned objects after evict", 0, l2Cache.getNumberOfUnpinnedObjects());
        // Try Query
        pm = cachePMF.getPersistenceManager();
        tx = pm.currentTransaction();
        try {
            tx.begin();
            Query query = pm.newQuery(Vote.class);
            Collection votes = (Collection) query.execute();
            Iterator iter = votes.iterator();
            while (iter.hasNext()) {
                iter.next();
            }
            assertEquals("Incorrect number of pinned objects after Query", 2, l2Cache.getNumberOfPinnedObjects());
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            fail("Error retrieving object from the L2 cache : " + e.getMessage());
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
            pm.close();
        }
    } finally {
        clean(cachePMF, Vote.class);
        cachePMF.close();
    }
}
Also used : Vote(org.jpox.samples.models.voting.Vote) Transaction(javax.jdo.Transaction) Query(javax.jdo.Query) PersistenceManager(javax.jdo.PersistenceManager) Level2Cache(org.datanucleus.cache.Level2Cache) JDODataStoreCache(org.datanucleus.api.jdo.JDODataStoreCache) Iterator(java.util.Iterator) Collection(java.util.Collection) PersistenceManagerFactory(javax.jdo.PersistenceManagerFactory) JDOPersistenceManagerFactory(org.datanucleus.api.jdo.JDOPersistenceManagerFactory) Properties(java.util.Properties) JDODataStoreCache(org.datanucleus.api.jdo.JDODataStoreCache) DataStoreCache(javax.jdo.datastore.DataStoreCache) JDOObjectNotFoundException(javax.jdo.JDOObjectNotFoundException)

Example 12 with Level2Cache

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

the class StateManagerImpl method loadFieldsFromLevel2Cache.

/**
 * Convenience method to retrieve field values from an L2 cached object if they are loaded in that object.
 * If the object is not in the L2 cache then just returns, and similarly if the required fields aren't available.
 * @param fieldNumbers Numbers of fields to load from the L2 cache
 * @return The fields that couldn't be loaded
 */
protected int[] loadFieldsFromLevel2Cache(int[] fieldNumbers) {
    // Only continue if there are fields, and not being deleted/flushed etc
    if (fieldNumbers == null || fieldNumbers.length == 0 || myEC.isFlushing() || myLC.isDeleted() || isDeleting() || getExecutionContext().getTransaction().isCommitting()) {
        return fieldNumbers;
    }
    // TODO Drop this check when we're confident that this doesn't affect some use-cases
    if (!myEC.getNucleusContext().getConfiguration().getBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_LOADFIELDS, true)) {
        return fieldNumbers;
    }
    Level2Cache l2cache = myEC.getNucleusContext().getLevel2Cache();
    if (l2cache != null && myEC.getNucleusContext().isClassCacheable(cmd)) {
        CachedPC<Persistable> cachedPC = l2cache.get(myID);
        if (cachedPC != null) {
            int[] cacheFieldsToLoad = ClassUtils.getFlagsSetTo(cachedPC.getLoadedFields(), fieldNumbers, true);
            if (cacheFieldsToLoad != null && cacheFieldsToLoad.length > 0) {
                if (NucleusLogger.CACHE.isDebugEnabled()) {
                    NucleusLogger.CACHE.debug(Localiser.msg("026034", StringUtils.toJVMIDString(getObject()), myID, StringUtils.intArrayToString(cacheFieldsToLoad)));
                }
                L2CacheRetrieveFieldManager l2RetFM = new L2CacheRetrieveFieldManager(this, cachedPC);
                this.replaceFields(cacheFieldsToLoad, l2RetFM);
                int[] fieldsNotLoaded = l2RetFM.getFieldsNotLoaded();
                if (fieldsNotLoaded != null) {
                    for (int i = 0; i < fieldsNotLoaded.length; i++) {
                        loadedFields[fieldsNotLoaded[i]] = false;
                    }
                }
            }
        }
    }
    return ClassUtils.getFlagsSetTo(loadedFields, fieldNumbers, false);
}
Also used : L2CacheRetrieveFieldManager(org.datanucleus.cache.L2CacheRetrieveFieldManager) Persistable(org.datanucleus.enhancement.Persistable) Level2Cache(org.datanucleus.cache.Level2Cache)

Example 13 with Level2Cache

use of org.datanucleus.cache.Level2Cache 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 14 with Level2Cache

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

Example 15 with Level2Cache

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

the class CacheTest method testL2LoadedFields.

/**
 * Test to check the retrieval of an object from the L2 cache and the observance of its loaded fields.
 */
public void testL2LoadedFields() {
    Properties userProps = new Properties();
    userProps.setProperty(PropertyNames.PROPERTY_CACHE_L1_TYPE, "soft");
    userProps.setProperty(PropertyNames.PROPERTY_CACHE_L2_TYPE, "weak");
    PersistenceManagerFactory cachePMF = getPMF(1, userProps);
    try {
        // Create a PM and add an object
        Object id = null;
        PersistenceManager pm = cachePMF.getPersistenceManager();
        Transaction tx = pm.currentTransaction();
        try {
            tx.begin();
            Person p1 = new Person(102, "George", "Bush", "george.bush@whitehouse.gov");
            pm.makePersistent(p1);
            id = pm.getObjectId(p1);
            tx.commit();
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
            pm.close();
        }
        // Clear the L2 cache so we dont have this object
        Level2Cache l2Cache = ((JDODataStoreCache) cachePMF.getDataStoreCache()).getLevel2Cache();
        l2Cache.evictAll();
        // Pin all Person objects
        l2Cache.pinAll(Person.class, false);
        // Retrieve the object with just some fields
        PersistenceManager pm1 = cachePMF.getPersistenceManager();
        tx = pm1.currentTransaction();
        pm1.getFetchPlan().setGroup("groupA");
        try {
            // Load the Person object - will only have firstName, lastName loaded.
            // Will be added to L2 cache, so pin it
            tx.begin();
            pm1.getObjectById(id);
            // George Bush will now be pinned since all Person objects are pinned
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            fail("Exception thrown while retrieving object to store in L2 cache with only few fields : " + e.getMessage());
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
        }
        // Object should now be in L2 cache
        // Retrieve the object with all fields and check an unretrieved field
        PersistenceManager pm2 = cachePMF.getPersistenceManager();
        tx = pm2.currentTransaction();
        try {
            tx.begin();
            Person p1 = (Person) pm2.getObjectById(id);
            assertTrue("Additional field of L2 cached object hasn't been retrieved correctly (wasnt in original FetchPlan)", p1.getEmailAddress() != null);
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            fail("Exception thrown while retrieving object from L2 cache : " + e.getMessage());
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
        }
        pm1.close();
        pm2.close();
    } finally {
        // Clean out created data
        clean(cachePMF, Person.class);
        cachePMF.close();
    }
}
Also used : Transaction(javax.jdo.Transaction) PersistenceManager(javax.jdo.PersistenceManager) Level2Cache(org.datanucleus.cache.Level2Cache) JDODataStoreCache(org.datanucleus.api.jdo.JDODataStoreCache) PersistenceManagerFactory(javax.jdo.PersistenceManagerFactory) JDOPersistenceManagerFactory(org.datanucleus.api.jdo.JDOPersistenceManagerFactory) Properties(java.util.Properties) Person(org.jpox.samples.models.company.Person) JDOObjectNotFoundException(javax.jdo.JDOObjectNotFoundException)

Aggregations

Level2Cache (org.datanucleus.cache.Level2Cache)16 Properties (java.util.Properties)8 JDOObjectNotFoundException (javax.jdo.JDOObjectNotFoundException)8 PersistenceManager (javax.jdo.PersistenceManager)8 PersistenceManagerFactory (javax.jdo.PersistenceManagerFactory)8 Transaction (javax.jdo.Transaction)8 JDODataStoreCache (org.datanucleus.api.jdo.JDODataStoreCache)8 JDOPersistenceManagerFactory (org.datanucleus.api.jdo.JDOPersistenceManagerFactory)8 DataStoreCache (javax.jdo.datastore.DataStoreCache)6 CachedPC (org.datanucleus.cache.CachedPC)6 ObjectProvider (org.datanucleus.state.ObjectProvider)4 Employee (org.jpox.samples.models.company.Employee)4 Manager (org.jpox.samples.models.company.Manager)3 HashMap (java.util.HashMap)2 Iterator (java.util.Iterator)2 Query (javax.jdo.Query)2 CacheUniqueKey (org.datanucleus.cache.CacheUniqueKey)2 Persistable (org.datanucleus.enhancement.Persistable)2 IdentityReference (org.datanucleus.identity.IdentityReference)2 UniqueMetaData (org.datanucleus.metadata.UniqueMetaData)2