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 4bd184b854a62e5dafbe3ed07439216c386acdd2 Author: Thomas Vandahl <[email protected]> AuthorDate: Sat Sep 5 12:22:39 2026 +0200 Make DoubleLinkedList Iterable --- .../AbstractDoubleLinkedListMemoryCache.java | 10 +-- .../jcs4/utils/struct/DoubleLinkedList.java | 56 ++++++++++--- .../utils/struct/DoubleLinkedListDumpUnitTest.java | 32 ++------ .../utils/struct/DoubleLinkedListUnitTest.java | 91 ++++++++++++++-------- 4 files changed, 112 insertions(+), 77 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 57ff21aa..351aa928 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 @@ -331,7 +331,7 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract private void dumpCacheEntries() { log.trace("dumpingCacheEntries"); - for (MemoryElementDescriptor<K, V> me = list.getFirst(); me != null; me = (MemoryElementDescriptor<K, V>) me.next) + for (MemoryElementDescriptor<K, V> me : list) { log.trace("dumpCacheEntries> key={0}, val={1}", me.getCacheElement().key(), me.getCacheElement().value()); @@ -350,7 +350,7 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract + "contains {2} elements", getCacheName(), getSize(), list.size()); log.trace("verifycache: checking linked list by key "); - for (MemoryElementDescriptor<K, V> li = list.getFirst(); li != null; li = (MemoryElementDescriptor<K, V>) li.next) + for (MemoryElementDescriptor<K, V> li : list) { final K key = li.getCacheElement().key(); if (!mapView.containsKey(key)) @@ -377,7 +377,7 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract } log.trace("verifycache: checking linked list by value "); - for (MemoryElementDescriptor<K, V> li = list.getFirst(); li != null; li = (MemoryElementDescriptor<K, V>) li.next) + for (MemoryElementDescriptor<K, V> li : list) { if (!mapView.containsValue(li)) { @@ -392,7 +392,7 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract { found = false; - for (MemoryElementDescriptor<K, V> li = list.getFirst(); li != null; li = (MemoryElementDescriptor<K, V>) li.next) + for (MemoryElementDescriptor<K, V> li : list) { if (val.equals(li.getCacheElement().key())) { @@ -428,7 +428,7 @@ public abstract class AbstractDoubleLinkedListMemoryCache<K, V> extends Abstract boolean found = false; // go through the linked list looking for the key - for (MemoryElementDescriptor<K, V> li = list.getFirst(); li != null; li = (MemoryElementDescriptor<K, V>) li.next) + for (MemoryElementDescriptor<K, V> li : list) { if (li.getCacheElement().key() == key) { 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 c76b2f6d..6216d0ab 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 @@ -1,5 +1,7 @@ package org.apache.commons.jcs4.utils.struct; +import java.util.Iterator; + /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -48,8 +50,9 @@ import org.apache.commons.jcs4.log.Log; * @see java.util.concurrent.locks.ReentrantLock * @see org.apache.commons.jcs4.engine.memory.AbstractDoubleLinkedListMemoryCache */ -@SuppressWarnings({"unchecked", "rawtypes"}) // Don't know how to resolve this with generics +@SuppressWarnings({"unchecked"}) // Don't know how to resolve this with generics public class DoubleLinkedList<T extends DoubleLinkedListNode> + implements Iterable<T> { /** The logger */ private static final Log log = Log.getLog( DoubleLinkedList.class ); @@ -68,8 +71,8 @@ public class DoubleLinkedList<T extends DoubleLinkedListNode> */ public DoubleLinkedList() { - this.first = (T) new DoubleLinkedListNode<T>(null); - this.last = (T) new DoubleLinkedListNode<T>(null); + this.first = (T) new DoubleLinkedListNode(); + this.last = (T) new DoubleLinkedListNode(); this.first.next = this.last; this.last.prev = this.first; } @@ -111,9 +114,9 @@ public class DoubleLinkedList<T extends DoubleLinkedListNode> if ( log.isDebugEnabled() ) { log.debug( "dumping Entries" ); - for (T me = (T) first.next; me != last; me = (T) me.next) + for (T me : this) { - log.debug( "dump Entries> payload= \"{0}\"", me.getPayload() ); + log.debug( "dump Entries> \"{0}\"", me ); } } } @@ -125,7 +128,7 @@ public class DoubleLinkedList<T extends DoubleLinkedListNode> */ public T getFirst() { - log.trace( "returning first node" ); + log.debug( "returning first node" ); return (T) first.next; } @@ -136,7 +139,7 @@ public class DoubleLinkedList<T extends DoubleLinkedListNode> */ public T getLast() { - log.trace( "returning last node" ); + log.debug( "returning last node" ); return (T) last.prev; } @@ -178,7 +181,7 @@ public class DoubleLinkedList<T extends DoubleLinkedListNode> */ public boolean remove(final T me) { - log.trace("removing node"); + log.debug("removing node"); me.prev.next = me.next; me.next.prev = me.prev; me.prev = me.next = null; @@ -192,11 +195,13 @@ public class DoubleLinkedList<T extends DoubleLinkedListNode> */ public void removeAll() { - for (T me = (T) first.next; me != null;) + T me = getFirst(); + while (me.next != null) { - me.prev = null; - me.next = null; + T toRemove = me; me = (T) me.next; + toRemove.prev = null; + toRemove.next = null; } first.next = last; last.prev = first; @@ -210,7 +215,7 @@ public class DoubleLinkedList<T extends DoubleLinkedListNode> */ public T removeLast() { - log.trace("removing last node"); + log.debug("removing last node"); final T temp = (T) last.prev; if (last != first) { @@ -228,4 +233,31 @@ public class DoubleLinkedList<T extends DoubleLinkedListNode> { return size; } + + /** + * Return an iterator over this list + * + * @return the iterator + */ + @Override + public Iterator<T> iterator() + { + return new Iterator<>() + { + private T runner = first; + + @Override + public boolean hasNext() + { + return runner.next != null && runner.next != last; + } + + @Override + public T next() + { + runner = (T) runner.next; + return runner; + } + }; + } } diff --git a/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedListDumpUnitTest.java b/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedListDumpUnitTest.java index 80ec44aa..92044dcf 100644 --- a/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedListDumpUnitTest.java +++ b/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedListDumpUnitTest.java @@ -1,24 +1,5 @@ package org.apache.commons.jcs4.utils.struct; -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.StringWriter; @@ -37,13 +18,10 @@ class DoubleLinkedListDumpUnitTest final StringWriter stringWriter = new StringWriter(); TestLogConfigurationUtil.configureLogger( stringWriter, DoubleLinkedList.class.getName() ); - final DoubleLinkedList<DoubleLinkedListNode<String>> list = new DoubleLinkedList<>(); - - final String payload1 = "payload1"; - final DoubleLinkedListNode<String> node1 = new DoubleLinkedListNode<>( payload1 ); + final DoubleLinkedList<DoubleLinkedListNode> list = new DoubleLinkedList<>(); - final String payload2 = "payload2"; - final DoubleLinkedListNode<String> node2 = new DoubleLinkedListNode<>( payload2 ); + final DoubleLinkedListNode node1 = new DoubleLinkedListNode(); + final DoubleLinkedListNode node2 = new DoubleLinkedListNode(); list.addLast( node1 ); list.addLast( node2 ); @@ -53,7 +31,7 @@ class DoubleLinkedListDumpUnitTest final String result = stringWriter.toString(); // VERIFY - assertTrue( result.indexOf( payload1 ) != -1, "Missing node in log dump" ); - assertTrue( result.indexOf( payload2 ) != -1, "Missing node in log dump" ); + assertTrue(result.indexOf(node1.toString()) != -1, "Missing node in log dump"); + assertTrue(result.indexOf(node2.toString()) != -1, "Missing node in log dump"); } } diff --git a/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedListUnitTest.java b/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedListUnitTest.java index ec1deee9..f9840050 100644 --- a/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedListUnitTest.java +++ b/commons-jcs4-core/src/test/java/org/apache/commons/jcs4/utils/struct/DoubleLinkedListUnitTest.java @@ -20,6 +20,7 @@ package org.apache.commons.jcs4.utils.struct; */ import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import org.junit.jupiter.api.Test; @@ -31,10 +32,9 @@ class DoubleLinkedListUnitTest void testAddLast_Empty() { // SETUP - final DoubleLinkedList<DoubleLinkedListNode<String>> list = new DoubleLinkedList<>(); + final DoubleLinkedList<DoubleLinkedListNode> list = new DoubleLinkedList<>(); - final String payload1 = "payload1"; - final DoubleLinkedListNode<String> node1 = new DoubleLinkedListNode<>( payload1 ); + final DoubleLinkedListNode node1 = new DoubleLinkedListNode(); // WO WORK list.addLast( node1 ); @@ -48,13 +48,10 @@ class DoubleLinkedListUnitTest void testAddLast_NotEmpty() { // SETUP - final DoubleLinkedList<DoubleLinkedListNode<String>> list = new DoubleLinkedList<>(); + final DoubleLinkedList<DoubleLinkedListNode> list = new DoubleLinkedList<>(); - final String payload1 = "payload1"; - final DoubleLinkedListNode<String> node1 = new DoubleLinkedListNode<>( payload1 ); - - final String payload2 = "payload2"; - final DoubleLinkedListNode<String> node2 = new DoubleLinkedListNode<>( payload2 ); + final DoubleLinkedListNode node1 = new DoubleLinkedListNode(); + final DoubleLinkedListNode node2 = new DoubleLinkedListNode(); // WO WORK list.addLast( node1 ); @@ -69,10 +66,9 @@ class DoubleLinkedListUnitTest void testMakeLast_wasAlone() { // SETUP - final DoubleLinkedList<DoubleLinkedListNode<String>> list = new DoubleLinkedList<>(); + final DoubleLinkedList<DoubleLinkedListNode> list = new DoubleLinkedList<>(); - final String payload1 = "payload1"; - final DoubleLinkedListNode<String> node1 = new DoubleLinkedListNode<>( payload1 ); + final DoubleLinkedListNode node1 = new DoubleLinkedListNode(); list.addFirst( node1 ); @@ -90,13 +86,10 @@ class DoubleLinkedListUnitTest void testMakeLast_wasFirst() { // SETUP - final DoubleLinkedList<DoubleLinkedListNode<String>> list = new DoubleLinkedList<>(); - - final String payload1 = "payload1"; - final DoubleLinkedListNode<String> node1 = new DoubleLinkedListNode<>( payload1 ); + final DoubleLinkedList<DoubleLinkedListNode> list = new DoubleLinkedList<>(); - final String payload2 = "payload2"; - final DoubleLinkedListNode<String> node2 = new DoubleLinkedListNode<>( payload2 ); + final DoubleLinkedListNode node1 = new DoubleLinkedListNode(); + final DoubleLinkedListNode node2 = new DoubleLinkedListNode(); list.addFirst( node2 ); list.addFirst( node1 ); @@ -115,16 +108,11 @@ class DoubleLinkedListUnitTest void testMakeLast_wasInMiddle() { // SETUP - final DoubleLinkedList<DoubleLinkedListNode<String>> list = new DoubleLinkedList<>(); - - final String payload1 = "payload1"; - final DoubleLinkedListNode<String> node1 = new DoubleLinkedListNode<>( payload1 ); - - final String payload2 = "payload2"; - final DoubleLinkedListNode<String> node2 = new DoubleLinkedListNode<>( payload2 ); + final DoubleLinkedList<DoubleLinkedListNode> list = new DoubleLinkedList<>(); - final String payload3 = "payload3"; - final DoubleLinkedListNode<String> node3 = new DoubleLinkedListNode<>( payload3 ); + final DoubleLinkedListNode node1 = new DoubleLinkedListNode(); + final DoubleLinkedListNode node2 = new DoubleLinkedListNode(); + final DoubleLinkedListNode node3 = new DoubleLinkedListNode(); list.addFirst( node2 ); list.addFirst( node1 ); @@ -144,13 +132,10 @@ class DoubleLinkedListUnitTest void testMakeLast_wasLast() { // SETUP - final DoubleLinkedList<DoubleLinkedListNode<String>> list = new DoubleLinkedList<>(); + final DoubleLinkedList<DoubleLinkedListNode> list = new DoubleLinkedList<>(); - final String payload1 = "payload1"; - final DoubleLinkedListNode<String> node1 = new DoubleLinkedListNode<>( payload1 ); - - final String payload2 = "payload2"; - final DoubleLinkedListNode<String> node2 = new DoubleLinkedListNode<>( payload2 ); + final DoubleLinkedListNode node1 = new DoubleLinkedListNode(); + final DoubleLinkedListNode node2 = new DoubleLinkedListNode(); list.addFirst( node1 ); list.addFirst( node2 ); @@ -163,4 +148,44 @@ class DoubleLinkedListUnitTest assertEquals( node1, list.getLast(), "Wrong last" ); assertEquals( node2, list.getFirst(), "Wrong first" ); } + + /** Verify that remove and removeAll work. */ + @Test + void testRemove() + { + // SETUP + final DoubleLinkedList<DoubleLinkedListNode> list = new DoubleLinkedList<>(); + + final DoubleLinkedListNode node1 = new DoubleLinkedListNode(); + final DoubleLinkedListNode node2 = new DoubleLinkedListNode(); + + list.addFirst( node1 ); + list.addFirst( node2 ); + assertEquals( 2, list.size(), "Wrong size" ); + + // DO WORK + list.remove( node1 ); + + // VERIFY + assertEquals( 1, list.size(), "Wrong size" ); + assertEquals( node2, list.getLast(), "Wrong last" ); + assertEquals( node2, list.getFirst(), "Wrong first" ); + + list.addFirst( node1 ); + assertEquals( 2, list.size(), "Wrong size" ); + assertEquals( node1, list.getFirst(), "Wrong first" ); + assertEquals( node2, list.getLast(), "Wrong last" ); + + // DO WORK + list.removeAll(); + + // VERIFY + assertEquals( 0, list.size(), "Wrong size" ); + assertEquals( list.getFirst().prev, list.getLast(), "Wrong last" ); + assertEquals( list.getLast().next, list.getFirst(), "Wrong first" ); + assertNull(node1.next, "node1.next should be null"); + assertNull(node1.prev, "node1.prev should be null"); + assertNull(node2.next, "node2.next should be null"); + assertNull(node2.prev, "node2.prev should be null"); + } }
