This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jcs.git

commit bf59a1a5f88ebf606cf5e65e0d1fa7b3c0dd52c2
Author: Thomas Vandahl <[email protected]>
AuthorDate: Tue Sep 8 21:38:16 2026 +0200

    Update MemoryElementDescriptor in-place
---
 .../AbstractDoubleLinkedListMemoryCache.java       | 44 ++++++++++++++--------
 .../jcs4/engine/memory/AbstractMemoryCache.java    | 33 ++++++++--------
 .../jcs4/engine/memory/fifo/FIFOMemoryCache.java   | 14 +------
 .../jcs4/engine/memory/lru/LHMLRUMemoryCache.java  |  4 +-
 .../jcs4/engine/memory/lru/LRUMemoryCache.java     | 12 ------
 .../jcs4/engine/memory/mru/MRUMemoryCache.java     | 14 -------
 .../memory/soft/SoftReferenceMemoryCache.java      |  4 +-
 .../memory/util/MemoryElementDescriptor.java       | 10 +++++
 .../jcs4/utils/struct/DoubleLinkedList.java        | 17 ++++++---
 .../jcs4/utils/struct/DoubleLinkedListNode.java    |  2 +-
 10 files changed, 72 insertions(+), 82 deletions(-)

diff --git 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/AbstractDoubleLinkedListMemoryCache.java
 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/AbstractDoubleLinkedListMemoryCache.java
index f255cc61..555ef4cb 100644
--- 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/AbstractDoubleLinkedListMemoryCache.java
+++ 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/AbstractDoubleLinkedListMemoryCache.java
@@ -90,14 +90,21 @@ public abstract class 
AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
      * @param list the node list
      * @param me the current cache element
      */
-    protected abstract void 
adjustListForGet(DoubleLinkedList<MemoryElementDescriptor<K, V>> list, 
MemoryElementDescriptor<K, V> me);
+    protected abstract void 
adjustListForGet(DoubleLinkedList<MemoryElementDescriptor<K, V>> list,
+            MemoryElementDescriptor<K, V> me);
 
     /**
-     * Children implement this to control the cache expiration algorithm
+     * Puts an item to the head of the list. Moves any pre-existing entries of 
the same
+     * key to the head of the linked list and adds this one first.
      *
+     * @param list the node list
      * @param me the current cache element
      */
-    protected abstract void adjustListForUpdate(MemoryElementDescriptor<K, V> 
me);
+    protected void 
adjustListForUpdate(DoubleLinkedList<MemoryElementDescriptor<K, V>> list,
+            MemoryElementDescriptor<K, V> me)
+    {
+        list.makeFirst(me);
+    }
 
     /**
      * This is called by super initialize.
@@ -168,23 +175,12 @@ public abstract class 
AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
      * (guarded by the lock)
      *
      * @param newNode The memory element descriptor of the current cache 
element
-     * @param oldNode The memory element descriptor of the previous cache 
element
      * @throws IOException if spooling operation fails
      */
     @Override
-    protected void lockedUpdateElement(MemoryElementDescriptor<K, V> newNode,
-            MemoryElementDescriptor<K, V> oldNode) throws IOException
+    protected void lockedUpdateElement(MemoryElementDescriptor<K, V> newNode) 
throws IOException
     {
-        adjustListForUpdate(newNode);
-
-        // If the node was the same as an existing node, remove it.
-        if (oldNode != null && 
newNode.getCacheElement().key().equals(oldNode.getCacheElement().key()))
-        {
-            list.remove(oldNode);
-        }
-
-        // If we are over the max spool some
-        spoolIfNeeded();
+        adjustListForUpdate(list, newNode);
     }
 
     /**
@@ -236,6 +232,22 @@ public abstract class 
AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract
         return freed;
     }
 
+    /**
+     * Puts an item to the cache.
+     *
+     * @param ce Description of the Parameter
+     * @throws IOException Description of the Exception
+     */
+    @Override
+    public void update( ICacheElement<K, V> ce )
+        throws IOException
+    {
+        super.update(ce);
+
+        // If we are over the max spool some
+        spoolIfNeeded();
+    }
+
     /**
      * If the max size has been reached, spool.
      * (guarded by the lock)
diff --git 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/AbstractMemoryCache.java
 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/AbstractMemoryCache.java
index 799b420f..be04c76d 100644
--- 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/AbstractMemoryCache.java
+++ 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/AbstractMemoryCache.java
@@ -267,32 +267,28 @@ public abstract class AbstractMemoryCache<K, V>
     @Override
     public ICacheElement<K, V> getQuiet( final K key )
     {
-        ICacheElement<K, V> ce = null;
+        MemoryElementDescriptor<K, V> me = null;
 
         lock.readLock().lock();
         try
         {
-            final MemoryElementDescriptor<K, V> me = map.get( key );
-            if ( me != null )
-            {
-                ce = me.getCacheElement();
-            }
+            me = map.get( key );
         }
         finally
         {
             lock.readLock().unlock();
         }
 
-        if (ce == null)
+        if (me == null)
         {
             log.debug("{0}: MemoryCache quiet miss for {1}", 
this::getCacheName, () -> key);
+            return null;
         }
         else
         {
             log.debug("{0}: MemoryCache quiet hit for {1}", 
this::getCacheName, () -> key);
+            return me.getCacheElement();
         }
-
-        return ce;
     }
 
     /**
@@ -372,11 +368,9 @@ public abstract class AbstractMemoryCache<K, V>
      * (guarded by the lock)
      *
      * @param newNode The memory element descriptor of the current cache 
element
-     * @param oldNode The memory element descriptor of the previous cache 
element
      * @throws IOException if spooling operation fails
      */
-    protected abstract void lockedUpdateElement(MemoryElementDescriptor<K, V> 
newNode,
-            MemoryElementDescriptor<K, V> oldNode) throws IOException;
+    protected abstract void lockedUpdateElement(MemoryElementDescriptor<K, V> 
newNode) throws IOException;
 
     /**
      * Removes all cached items from the cache control structures.
@@ -539,13 +533,22 @@ public abstract class AbstractMemoryCache<K, V>
         throws IOException
     {
         putCnt.incrementAndGet();
-        final MemoryElementDescriptor<K, V> newNode = wrap(ce);
 
         lock.writeLock().lock();
         try
         {
-            final MemoryElementDescriptor<K, V> oldNode = map.put(ce.key(), 
newNode);
-            lockedUpdateElement(newNode, oldNode);
+            final MemoryElementDescriptor<K, V> newNode = 
map.compute(ce.key(), (k, v) -> {
+                if (v == null)
+                {
+                    return wrap(ce);
+                }
+                else
+                {
+                    v.setCacheElement(ce);
+                    return v;
+                }
+            });
+            lockedUpdateElement(newNode);
         }
         finally
         {
diff --git 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/fifo/FIFOMemoryCache.java
 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/fifo/FIFOMemoryCache.java
index 07e556eb..4bec7a17 100644
--- 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/fifo/FIFOMemoryCache.java
+++ 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/fifo/FIFOMemoryCache.java
@@ -44,16 +44,4 @@ public class FIFOMemoryCache<K, V>
     {
         // DO NOTHING
     }
-
-    /**
-     * Puts an item to the cache. Removes any pre-existing entries of the same 
key from the linked
-     * list and adds this one first.
-     *
-     * @param me The cache element, or entry wrapper
-     */
-    @Override
-    protected void adjustListForUpdate(final MemoryElementDescriptor<K, V> me)
-    {
-        addFirst(me);
-    }
-}
+}
\ No newline at end of file
diff --git 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/lru/LHMLRUMemoryCache.java
 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/lru/LHMLRUMemoryCache.java
index 08c7082a..51fedea7 100644
--- 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/lru/LHMLRUMemoryCache.java
+++ 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/lru/LHMLRUMemoryCache.java
@@ -127,11 +127,9 @@ public class LHMLRUMemoryCache<K, V>
      * (guarded by the lock)
      *
      * @param newNode The memory element descriptor of the current cache 
element
-     * @param oldNode The memory element descriptor of the previous cache 
element
      */
     @Override
-    protected void lockedUpdateElement(MemoryElementDescriptor<K, V> newNode,
-            MemoryElementDescriptor<K, V> oldNode)
+    protected void lockedUpdateElement(MemoryElementDescriptor<K, V> newNode)
     {
         // empty
     }
diff --git 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/lru/LRUMemoryCache.java
 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/lru/LRUMemoryCache.java
index 6bc6cf39..ec383492 100644
--- 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/lru/LRUMemoryCache.java
+++ 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/lru/LRUMemoryCache.java
@@ -52,16 +52,4 @@ public class LRUMemoryCache<K, V>
     {
         list.makeFirst( me );
     }
-
-    /**
-     * Puts an item to the cache. Removes any pre-existing entries of the same 
key from the linked
-     * list and adds this one first.
-     *
-     * @param me The cache element, or entry wrapper
-     */
-    @Override
-    protected void adjustListForUpdate(final MemoryElementDescriptor<K, V> me)
-    {
-        addFirst(me);
-    }
 }
diff --git 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/mru/MRUMemoryCache.java
 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/mru/MRUMemoryCache.java
index a6eca64a..6e5264dc 100644
--- 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/mru/MRUMemoryCache.java
+++ 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/mru/MRUMemoryCache.java
@@ -45,18 +45,4 @@ public class MRUMemoryCache<K, V>
     {
         list.makeLast( me );
     }
-
-    /**
-     * Adds the item to the front of the list. A put doesn't count as a usage.
-     * <p>
-     * It's not clear if the put operation should be different. Perhaps this 
should remove the oldest
-     * if full, and then put.
-     *
-     * @param me The cache element, or entry wrapper
-     */
-    @Override
-    protected void adjustListForUpdate(final MemoryElementDescriptor<K, V> me)
-    {
-        addFirst(me);
-    }
 }
diff --git 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/soft/SoftReferenceMemoryCache.java
 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/soft/SoftReferenceMemoryCache.java
index 4225db08..3910eb1f 100644
--- 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/soft/SoftReferenceMemoryCache.java
+++ 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/soft/SoftReferenceMemoryCache.java
@@ -173,11 +173,9 @@ public class SoftReferenceMemoryCache<K, V> extends 
AbstractMemoryCache<K, V>
      * (guarded by the lock)
      *
      * @param newNode The memory element descriptor of the current cache 
element
-     * @param oldNode The memory element descriptor of the previous cache 
element
      */
     @Override
-    protected void lockedUpdateElement(MemoryElementDescriptor<K, V> newNode,
-            MemoryElementDescriptor<K, V> oldNode)
+    protected void lockedUpdateElement(MemoryElementDescriptor<K, V> newNode)
     {
         final ICacheElement<K, V> val = newNode.getCacheElement();
         val.elementAttributes().setLastAccessTimeNow();
diff --git 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/util/MemoryElementDescriptor.java
 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/util/MemoryElementDescriptor.java
index 13c6fe29..ec8cf803 100644
--- 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/util/MemoryElementDescriptor.java
+++ 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/engine/memory/util/MemoryElementDescriptor.java
@@ -52,4 +52,14 @@ public class MemoryElementDescriptor<K, V>
     {
         return cacheElement;
     }
+
+    /**
+     * Sets a new cache element
+     *
+     * @param The ce
+     */
+    public void setCacheElement(ICacheElement<K, V> cacheElement)
+    {
+        this.cacheElement = cacheElement;
+    }
 }
diff --git 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedList.java
 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedList.java
index 6216d0ab..72a28129 100644
--- 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedList.java
+++ 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedList.java
@@ -150,8 +150,11 @@ public class DoubleLinkedList<T extends 
DoubleLinkedListNode>
      */
     public void makeFirst(final T ln)
     {
-        ln.prev.next = ln.next;
-        ln.next.prev = ln.prev;
+        if (ln.prev != null)
+        {
+            ln.prev.next = ln.next;
+            ln.next.prev = ln.prev;
+        }
         ln.prev = first;
         ln.next = first.next;
         first.next.prev = ln;
@@ -165,8 +168,11 @@ public class DoubleLinkedList<T extends 
DoubleLinkedListNode>
      */
     public void makeLast(final T ln)
     {
-        ln.prev.next = ln.next;
-        ln.next.prev = ln.prev;
+        if (ln.prev != null)
+        {
+            ln.prev.next = ln.next;
+            ln.next.prev = ln.prev;
+        }
         ln.next = last;
         ln.prev = last.prev;
         last.prev.next = ln;
@@ -220,8 +226,9 @@ public class DoubleLinkedList<T extends 
DoubleLinkedListNode>
         if (last != first)
         {
             remove(temp);
+            return temp;
         }
-        return temp;
+        return null;
     }
 
     /**
diff --git 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedListNode.java
 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedListNode.java
index 2aafc938..55612a72 100644
--- 
a/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedListNode.java
+++ 
b/commons-jcs4-core/src/main/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedListNode.java
@@ -36,5 +36,5 @@ public class DoubleLinkedListNode
     private static final long serialVersionUID = -1114934407695836097L;
 
     /** Double Linked list references */
-    public DoubleLinkedListNode prev, next;
+    public volatile DoubleLinkedListNode prev, next;
 }

Reply via email to