Anonymous avatar Anonymous committed 04f3c24

Issue number: CACHE-188 and CACHE-244
Obtained from: Christoph Kutzinski
Submitted by: Lars Torunski
Reviewed by: Lars Torunski

Comments (0)

Files changed (4)

 # OSCache build properties
 name=oscache
 fullname=OSCache
-version=2.3.1
+version=2.3.2-dev
 status=integration
-cvs.tag=v2_3_1
+cvs.tag=v2_3_2
 
 # The URL to use for testing the example webapp. Comment this out to disable the webapp tests.
 #test.web.baseURL=http://localhost:7001/oscache-example/
 <?xml-stylesheet type="text/xsl" href="http://www.jayasoft.fr/org/ivyrep/ivy-doc.xsl"?>
 <ivy-module version="1.0">
     <info organisation="opensymphony" module="oscache"
-          revision="2.3.1"
+          revision="2.3.2"
           status="integration"
-          publication="20060617120000">
+          publication="20060620120000">
         <license name="Apache" url="http://www.apache.org/licenses/LICENSE-2.0.txt"/>
         <ivyauthor name="opensymphony" url="http://www.opensymphony.com/"/>
 

src/java/com/opensymphony/oscache/base/algorithm/AbstractConcurrentReadCache.java

     /**
      * Persistence listener.
      */
-    protected PersistenceListener persistenceListener = null;
+    protected transient PersistenceListener persistenceListener = null;
 
     /**
      * Use memory cache or not.
         if (groupEntries == null) {
             // Not in the map, try the persistence layer
             groupEntries = persistRetrieveGroup(groupName);
-        } 
+        }
 
         return groupEntries;
     }
             synchronized (this) { // because remove() isn't synchronized
 
                 while (size() > maxEntries) {
-                    remove(removeItem(), false);
+                    remove(removeItem(), false, false);
                 }
             }
         } else {
      */
     /** OpenSymphony BEGIN */
     public Object remove(Object key) {
-        return remove(key, true);
+        return remove(key, true, false);
+    }
+
+    /**
+     * Like <code>remove(Object)</code>, but ensures that the entry will be removed from the persistent store, too,
+     * even if overflowPersistence or unlimitedDiskcache are true.
+     *
+     * @param key
+     * @return
+     */
+    public Object removeForce(Object key) {
+      return remove(key, true, true);
     }
 
     /**
                     };
         }
     }
-    
+
     /**
      * Get ref to group.
      * CACHE-127 Synchronized copying of the group entry set since
-     * the new HashSet(Collection c) constructor uses the iterator.  
-     * This may slow things down but it is better than a 
+     * the new HashSet(Collection c) constructor uses the iterator.
+     * This may slow things down but it is better than a
      * ConcurrentModificationException.  We might have to revisit the
      * code if performance is too adversely impacted.
      **/
     protected synchronized final Set getGroupForReading(String groupName) {
-    	Set group = (Set) getGroupsForReading().get(groupName);
+        Set group = (Set) getGroupsForReading().get(groupName);
         if (group == null) return null;
         return new HashSet(group);
     }
-    
+
     /**
      * Get ref to groups.
      * The reference and the cells it
                 return null;
             } else if ((key == e.key) || ((e.hash == hash) && key.equals(e.key))) {
                 Object oldValue = e.value;
+                if (persistenceListener != null && (oldValue == NULL)) {
+                  oldValue = persistRetrieve(key);
+                }
+
                 e.value = null;
                 count--;
 
                 /** OpenSymphony BEGIN */
                 if (!unlimitedDiskCache && !overflowPersistence) {
                     persistRemove(e.key);
+                    // If we have a CacheEntry, update the groups
+                    if (oldValue instanceof CacheEntry) {
+                      CacheEntry oldEntry = (CacheEntry)oldValue;
+                      removeGroupMappings(oldEntry.getKey(),
+                          oldEntry.getGroups(), true);
+                }
+                } else {
+                  // only remove from memory groups
+                  if (oldValue instanceof CacheEntry) {
+                    CacheEntry oldEntry = (CacheEntry)oldValue;
+                    removeGroupMappings(oldEntry.getKey(),
+                        oldEntry.getGroups(), false);
+                  }
                 }
 
                 if (overflowPersistence && ((size() + 1) >= maxEntries)) {
                     persistStore(key, oldValue);
+                    // add key to persistent groups but NOT to the memory groups
+                    if (oldValue instanceof CacheEntry) {
+                      CacheEntry oldEntry = (CacheEntry)oldValue;
+                      addGroupMappings(oldEntry.getKey(), oldEntry.getGroups(), true, false);
+                    }
                 }
 
                 if (invokeAlgorithm) {
      * @param newGroups the set of groups we want to add this cache entry to.
      * @param persist A flag to indicate whether the keys should be added to
      * the persistent cache layer.
+     * @param memory A flag to indicate whether the key should be added to
+     * the memory groups (important for overflow-to-disk)
      */
-    private void addGroupMappings(String key, Set newGroups, boolean persist) {
+    private void addGroupMappings(String key, Set newGroups, boolean persist, boolean memory) {
         // Add this CacheEntry to the groups that it is now a member of
         for (Iterator it = newGroups.iterator(); it.hasNext();) {
             String groupName = (String) it.next();
 
             // Update the in-memory groups
-            if (memoryCaching) {
+            if (memoryCaching && memory) {
                 if (groups == null) {
                     groups = new HashMap();
                 }
 
                     // Remove an item if the cache is full
                     if (size() >= maxEntries) {
-                        remove(removeItem(), false);
+                        remove(removeItem(), false, false);
                     }
 
                     if (first == tab[index]) {
         }
     }
 
-    private synchronized Object remove(Object key, boolean invokeAlgorithm)
+    private synchronized Object remove(Object key, boolean invokeAlgorithm, boolean forcePersist)
     /* Previous code
     public Object remove(Object key) */
 
                     tab = table;
 
                     Object oldValue = e.value;
+                    if (persistenceListener != null && (oldValue == NULL)) {
+                      oldValue = persistRetrieve(key);
+                    }
 
                     // re-find under synch if wrong list
                     if ((first != tab[index]) || (oldValue == null)) {
                     count--;
 
                     /** OpenSymphony BEGIN */
-                    if (!unlimitedDiskCache && !overflowPersistence) {
+                    if (forcePersist || (!unlimitedDiskCache && !overflowPersistence)) {
                         persistRemove(e.key);
+                        // If we have a CacheEntry, update the group lookups
+                        if (oldValue instanceof CacheEntry) {
+                          CacheEntry oldEntry = (CacheEntry)oldValue;
+                            removeGroupMappings(oldEntry.getKey(),
+                                oldEntry.getGroups(), true);
+                    }
+                    } else {
+                      // only remove from memory groups
+                      if (oldValue instanceof CacheEntry) {
+                        CacheEntry oldEntry = (CacheEntry)oldValue;
+                        removeGroupMappings(oldEntry.getKey(),
+                            oldEntry.getGroups(), false);
+                      }
                     }
 
-                    if (overflowPersistence && ((size() + 1) >= maxEntries)) {
+                    if (!forcePersist && overflowPersistence && ((size() + 1) >= maxEntries)) {
                         persistStore(key, oldValue);
+                        // add key to persistent groups but NOT to the memory groups
+                        if (oldValue instanceof CacheEntry) {
+                          CacheEntry oldEntry = (CacheEntry)oldValue;
+                          addGroupMappings(oldEntry.getKey(), oldEntry.getGroups(), true, false);
+                        }
                     }
 
                     if (invokeAlgorithm) {
 
     /**
      * Remove this CacheEntry from the groups it no longer belongs to.
-     *  We have to treat the memory and disk group mappings seperately so they remain
+     * We have to treat the memory and disk group mappings separately so they remain
      * valid for their corresponding memory/disk caches. (eg if mem is limited
      * to 100 entries and disk is unlimited, the group mappings will be
      * different).
      * from the persistent cache layer.
      */
     private void removeGroupMappings(String key, Set oldGroups, boolean persist) {
+        if (oldGroups == null) {
+          return;
+        }
+
         for (Iterator it = oldGroups.iterator(); it.hasNext();) {
             String groupName = (String) it.next();
 
                 }
             }
 
-            addGroupMappings(newValue.getKey(), addToGroups, persist);
+            addGroupMappings(newValue.getKey(), addToGroups, persist, true);
         }
     }
 

src/test/java/com/opensymphony/oscache/base/algorithm/TestAbstractCache.java

      * See CACHE-188 and maybe CACHE-244
      */
     public void testGroups() {
-    	/* TODO uncomment for 2.3.2 and for fixing issues CACHE-188 and maybe CACHE-244
       String KEY = "testkey";
       String KEY2 = "testkey2";
       String GROUP_NAME = "group1";
         e.printStackTrace();
         fail("Excpetion was thrown");
       }
-      */
     }
 
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.