More streaming, less arrays
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskCache.java
index 4cec8d0..4866b43 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/auxiliary/disk/indexed/IndexedDiskCache.java
@@ -357,26 +357,22 @@
log.debug("{0}: Performing inital consistency check", logCacheName);
boolean isOk = true;
- long fileLength = 0;
try
{
- fileLength = dataFile.length();
+ final long fileLength = dataFile.length();
- for (final Map.Entry<K, IndexedDiskElementDescriptor> e : keyHash.entrySet())
+ final IndexedDiskElementDescriptor corruptDed = keyHash.values().stream()
+ .filter(ded -> ded.pos + IndexedDisk.HEADER_SIZE_BYTES + ded.len > fileLength)
+ .findFirst()
+ .orElse(null);
+
+ if (corruptDed != null)
{
- final IndexedDiskElementDescriptor ded = e.getValue();
-
- isOk = ded.pos + IndexedDisk.HEADER_SIZE_BYTES + ded.len <= fileLength;
-
- if (!isOk)
- {
- log.warn("{0}: The dataFile is corrupted!\n raf.length() = {1}\n ded.pos = {2}",
- logCacheName, fileLength, ded.pos);
- break;
- }
+ isOk = false;
+ log.warn("{0}: The dataFile is corrupted!\n raf.length() = {1}\n ded.pos = {2}",
+ logCacheName, fileLength, corruptDed.pos);
}
-
- if (isOk && checkForDedOverlaps)
+ else if (checkForDedOverlaps)
{
isOk = checkForDedOverlaps(createPositionSortedDescriptorList());
}
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/auxiliary/lateral/LateralCacheNoWaitFacade.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/auxiliary/lateral/LateralCacheNoWaitFacade.java
index a64bb5f..7d86610 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/auxiliary/lateral/LateralCacheNoWaitFacade.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/auxiliary/lateral/LateralCacheNoWaitFacade.java
@@ -27,8 +27,8 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
import java.util.stream.Collectors;
import org.apache.commons.jcs3.auxiliary.AbstractAuxiliaryCache;
@@ -56,9 +56,18 @@
/** The logger */
private static final Log log = LogManager.getLog( LateralCacheNoWaitFacade.class );
- /** The queuing facade to the client. */
+ /**
+ * The queuing facade to the client.
+ * @deprecated Should not have been public in the first place
+ */
+ @Deprecated
public LateralCacheNoWait<K, V>[] noWaits;
+ /**
+ * The queuing facade to the client.
+ */
+ private final CopyOnWriteArraySet<LateralCacheNoWait<K, V>> noWaitSet;
+
/** The region name */
private final String cacheName;
@@ -82,11 +91,22 @@
log.debug( "CONSTRUCTING NO WAIT FACADE" );
this.listener = listener;
this.noWaits = noWaits;
+ this.noWaitSet = new CopyOnWriteArraySet<>(Arrays.asList(noWaits));
this.cacheName = cattr.getCacheName();
this.lateralCacheAttributes = cattr;
}
/**
+ * Return the size of the no wait list (for testing)
+ *
+ * @return the noWait list size.
+ */
+ protected int getNoWaitSize()
+ {
+ return noWaitSet.size();
+ }
+
+ /**
* Tells you if the no wait is in the list or not.
* <p>
* @param noWait
@@ -94,12 +114,7 @@
*/
public boolean containsNoWait( final LateralCacheNoWait<K, V> noWait )
{
- final Optional<LateralCacheNoWait<K, V>> optional = Arrays.stream(noWaits)
- // we know noWait isn't null
- .filter(nw -> noWait.equals( nw ))
- .findFirst();
-
- return optional.isPresent();
+ return noWaitSet.contains(noWait);
}
/**
@@ -108,6 +123,7 @@
* @param noWait
* @return true if it wasn't already contained
*/
+ @SuppressWarnings("unchecked") // No generic arrays in Java
public synchronized boolean addNoWait( final LateralCacheNoWait<K, V> noWait )
{
if ( noWait == null )
@@ -115,22 +131,15 @@
return false;
}
- if ( containsNoWait( noWait ) )
+ final boolean added = noWaitSet.add(noWait);
+
+ if (!added)
{
log.debug( "No Wait already contained, [{0}]", noWait );
return false;
}
- @SuppressWarnings("unchecked") // No generic arrays in java
- final
- LateralCacheNoWait<K, V>[] newArray = new LateralCacheNoWait[noWaits.length + 1];
-
- System.arraycopy( noWaits, 0, newArray, 0, noWaits.length );
-
- // set the last position to the new noWait
- newArray[noWaits.length] = noWait;
-
- noWaits = newArray;
+ noWaits = noWaitSet.toArray(new LateralCacheNoWait[0]);
return true;
}
@@ -141,6 +150,7 @@
* @param noWait
* @return true if it was already in the array
*/
+ @SuppressWarnings("unchecked") // No generic arrays in java
public synchronized boolean removeNoWait( final LateralCacheNoWait<K, V> noWait )
{
if ( noWait == null )
@@ -148,48 +158,31 @@
return false;
}
- int position = -1;
- for ( int i = 0; i < noWaits.length; i++ )
- {
- // we know noWait isn't null
- if ( noWait.equals( noWaits[i] ) )
- {
- position = i;
- break;
- }
- }
+ final boolean contained = noWaitSet.remove(noWait);
- if ( position == -1 )
+ if (!contained)
{
return false;
}
- @SuppressWarnings("unchecked") // No generic arrays in java
- final
- LateralCacheNoWait<K, V>[] newArray = new LateralCacheNoWait[noWaits.length - 1];
-
- System.arraycopy( noWaits, 0, newArray, 0, position );
- if ( noWaits.length != position )
- {
- System.arraycopy( noWaits, position + 1, newArray, position, noWaits.length - position - 1 );
- }
- noWaits = newArray;
+ noWaits = noWaitSet.toArray(new LateralCacheNoWait[0]);
return true;
}
/**
- * @param ce
+ * Update the cache element in all lateral caches
+ * @param ce the cache element
* @throws IOException
*/
@Override
public void update( final ICacheElement<K, V> ce )
throws IOException
{
- log.debug( "updating through lateral cache facade, noWaits.length = {0}",
- noWaits.length );
+ log.debug("updating through lateral cache facade, noWaits.length = {0}",
+ () -> noWaitSet.size());
- for (final LateralCacheNoWait<K, V> nw : noWaits)
+ for (final LateralCacheNoWait<K, V> nw : noWaitSet)
{
nw.update( ce );
}
@@ -204,17 +197,11 @@
@Override
public ICacheElement<K, V> get( final K key )
{
- final Optional<ICacheElement<K, V>> optional = Arrays.stream(noWaits)
- .map(nw -> nw.get( key ))
+ return noWaitSet.stream()
+ .map(nw -> nw.get(key))
.filter(obj -> obj != null)
- .findFirst();
-
- if (optional.isPresent())
- {
- return optional.get();
- }
-
- return null;
+ .findFirst()
+ .orElse(null);
}
/**
@@ -227,7 +214,7 @@
@Override
public Map<K, ICacheElement<K, V>> getMultiple(final Set<K> keys)
{
- if ( keys != null && !keys.isEmpty() )
+ if (keys != null && !keys.isEmpty())
{
final Map<K, ICacheElement<K, V>> elements = keys.stream()
.collect(Collectors.toMap(
@@ -254,12 +241,11 @@
@Override
public Map<K, ICacheElement<K, V>> getMatching(final String pattern)
{
- final Map<K, ICacheElement<K, V>> elements = new HashMap<>();
- for (final LateralCacheNoWait<K, V> nw : noWaits)
- {
- elements.putAll( nw.getMatching( pattern ) );
- }
- return elements;
+ return noWaitSet.stream()
+ .flatMap(nw -> nw.getMatching(pattern).entrySet().stream())
+ .collect(Collectors.toMap(
+ Entry::getKey,
+ Entry::getValue));
}
/**
@@ -271,15 +257,12 @@
public Set<K> getKeySet() throws IOException
{
final HashSet<K> allKeys = new HashSet<>();
- for (final LateralCacheNoWait<K, V> nw : noWaits)
+ for (final LateralCacheNoWait<K, V> nw : noWaitSet)
{
- if ( nw != null )
+ final Set<K> keys = nw.getKeySet();
+ if (keys != null)
{
- final Set<K> keys = nw.getKeySet();
- if (keys != null)
- {
- allKeys.addAll( keys );
- }
+ allKeys.addAll(keys);
}
}
return allKeys;
@@ -294,7 +277,7 @@
@Override
public boolean remove( final K key )
{
- Arrays.stream(noWaits).forEach(nw -> nw.remove( key ));
+ noWaitSet.forEach(nw -> nw.remove( key ));
return false;
}
@@ -304,7 +287,7 @@
@Override
public void removeAll()
{
- Arrays.stream(noWaits).forEach(LateralCacheNoWait::removeAll);
+ noWaitSet.forEach(LateralCacheNoWait::removeAll);
}
/** Adds a dispose request to the lateral cache. */
@@ -319,7 +302,7 @@
listener = null;
}
- Arrays.stream(noWaits).forEach(LateralCacheNoWait::dispose);
+ noWaitSet.forEach(LateralCacheNoWait::dispose);
}
finally
{
@@ -373,12 +356,12 @@
return CacheStatus.DISPOSED;
}
- if (noWaits.length == 0 || listener != null)
+ if (noWaitSet.isEmpty() || listener != null)
{
return CacheStatus.ALIVE;
}
- final List<CacheStatus> statii = Arrays.stream(noWaits)
+ final List<CacheStatus> statii = noWaitSet.stream()
.map(LateralCacheNoWait::getStatus)
.collect(Collectors.toList());
@@ -448,19 +431,13 @@
final ArrayList<IStatElement<?>> elems = new ArrayList<>();
- if ( noWaits != null )
+ if (noWaitSet != null)
{
- elems.add(new StatElement<>( "Number of No Waits", Integer.valueOf(noWaits.length) ) );
+ elems.add(new StatElement<>("Number of No Waits", Integer.valueOf(noWaitSet.size())));
- for ( final LateralCacheNoWait<K, V> lcnw : noWaits )
- {
- if ( lcnw != null )
- {
- // get the stats from the super too
- final IStats sStats = lcnw.getStatistics();
- elems.addAll(sStats.getStatElements());
- }
- }
+ elems.addAll(noWaitSet.stream()
+ .flatMap(lcnw -> lcnw.getStatistics().getStatElements().stream())
+ .collect(Collectors.toList()));
}
stats.setStatElements( elems );
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/auxiliary/lateral/socket/tcp/LateralTCPListener.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/auxiliary/lateral/socket/tcp/LateralTCPListener.java
index 8f457f8..32111f8 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/auxiliary/lateral/socket/tcp/LateralTCPListener.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/auxiliary/lateral/socket/tcp/LateralTCPListener.java
@@ -471,17 +471,11 @@
{
try
{
- while ( true )
+ // Check to see if we've been asked to exit, and exit
+ while ( !terminated.get() )
{
log.debug( "Waiting for clients to connect " );
- // Check to see if we've been asked to exit, and exit
- if (terminated.get())
- {
- log.debug("Thread terminated, exiting gracefully");
- break;
- }
-
try
{
final Socket socket = serverSocket.accept();
@@ -499,6 +493,7 @@
}
}
+ log.debug("Thread terminated, exiting gracefully");
serverSocket.close();
}
catch ( final IOException e )
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/engine/control/CompositeCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/engine/control/CompositeCache.java
index 011fce1..70d9b6f 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/engine/control/CompositeCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/engine/control/CompositeCache.java
@@ -21,11 +21,15 @@
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
+import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -82,8 +86,7 @@
private IElementEventQueue elementEventQ;
/** Auxiliary caches. */
- @SuppressWarnings("unchecked") // OK because this is an empty array
- private AuxiliaryCache<K, V>[] auxCaches = new AuxiliaryCache[0];
+ private CopyOnWriteArrayList<AuxiliaryCache<K, V>> auxCaches = new CopyOnWriteArrayList<>();
/** is this alive? */
private final AtomicBoolean alive;
@@ -186,12 +189,27 @@
/**
* This sets the list of auxiliary caches for this region.
+ * It filters out null caches
* <p>
* @param auxCaches
*/
+ public void setAuxCaches(final List<AuxiliaryCache<K, V>> auxCaches)
+ {
+ this.auxCaches = auxCaches.stream()
+ .filter(aux -> aux != null)
+ .collect(Collectors.toCollection(CopyOnWriteArrayList::new));
+ }
+
+ /**
+ * This sets the list of auxiliary caches for this region.
+ * <p>
+ * @param auxCaches
+ * @deprecated Use List method
+ */
+ @Deprecated
public void setAuxCaches(final AuxiliaryCache<K, V>[] auxCaches)
{
- this.auxCaches = auxCaches;
+ setAuxCaches(Arrays.asList(auxCaches));
}
/**
@@ -199,12 +217,25 @@
* <p>
* @return an array of auxiliary caches, may be empty, never null
*/
- public AuxiliaryCache<K, V>[] getAuxCaches()
+ public List<AuxiliaryCache<K, V>> getAuxCacheList()
{
return this.auxCaches;
}
/**
+ * Get the list of auxiliary caches for this region.
+ * <p>
+ * @return an array of auxiliary caches, may be empty, never null
+ * @deprecated Use List method
+ */
+ @SuppressWarnings("unchecked") // No generic arrays in Java
+ @Deprecated
+ public AuxiliaryCache<K, V>[] getAuxCaches()
+ {
+ return getAuxCacheList().toArray(new AuxiliaryCache[0]);
+ }
+
+ /**
* Standard update method.
* <p>
* @param ce
@@ -286,7 +317,7 @@
// more can be added if future auxiliary caches don't fit the model
// You could run a database cache as either a remote or a local disk.
// The types would describe the purpose.
- if (auxCaches.length > 0)
+ if (!auxCaches.isEmpty())
{
log.debug("Updating auxiliary caches");
}
@@ -385,7 +416,7 @@
// SPOOL TO DISK.
for (final ICache<K, V> aux : auxCaches)
{
- if (aux != null && aux.getCacheType() == CacheType.DISK_CACHE)
+ if (aux.getCacheType() == CacheType.DISK_CACHE)
{
diskAvailable = true;
@@ -496,56 +527,53 @@
// caches, even if not local look in disk auxiliaries
for (final AuxiliaryCache<K, V> aux : auxCaches)
{
- if (aux != null)
+ final CacheType cacheType = aux.getCacheType();
+
+ if (!localOnly || cacheType == CacheType.DISK_CACHE)
{
- final CacheType cacheType = aux.getCacheType();
+ log.debug("Attempting to get from aux [{0}] which is of type: {1}",
+ () -> aux.getCacheName(), () -> cacheType);
- if (!localOnly || cacheType == CacheType.DISK_CACHE)
+ try
{
- log.debug("Attempting to get from aux [{0}] which is of type: {1}",
- () -> aux.getCacheName(), () -> cacheType);
+ element = aux.get(key);
+ }
+ catch (final IOException e)
+ {
+ log.error("Error getting from aux", e);
+ }
+ }
- try
- {
- element = aux.get(key);
- }
- catch (final IOException e)
- {
- log.error("Error getting from aux", e);
- }
+ log.debug("Got CacheElement: {0}", element);
+
+ // Item found in one of the auxiliary caches.
+ if (element != null)
+ {
+ if (isExpired(element))
+ {
+ log.debug("{0} - Aux cache[{1}] hit, but element expired.",
+ () -> cacheAttr.getCacheName(), () -> aux.getCacheName());
+
+ // This will tell the remotes to remove the item
+ // based on the element's expiration policy. The elements attributes
+ // associated with the item when it created govern its behavior
+ // everywhere.
+ doExpires(element);
+ element = null;
+ }
+ else
+ {
+ log.debug("{0} - Aux cache[{1}] hit.",
+ () -> cacheAttr.getCacheName(), () -> aux.getCacheName());
+
+ // Update counters
+ hitCountAux.incrementAndGet();
+ copyAuxiliaryRetrievedItemToMemory(element);
}
- log.debug("Got CacheElement: {0}", element);
+ found = true;
- // Item found in one of the auxiliary caches.
- if (element != null)
- {
- if (isExpired(element))
- {
- log.debug("{0} - Aux cache[{1}] hit, but element expired.",
- () -> cacheAttr.getCacheName(), () -> aux.getCacheName());
-
- // This will tell the remotes to remove the item
- // based on the element's expiration policy. The elements attributes
- // associated with the item when it created govern its behavior
- // everywhere.
- doExpires(element);
- element = null;
- }
- else
- {
- log.debug("{0} - Aux cache[{1}] hit.",
- () -> cacheAttr.getCacheName(), () -> aux.getCacheName());
-
- // Update counters
- hitCountAux.incrementAndGet();
- copyAuxiliaryRetrievedItemToMemory(element);
- }
-
- found = true;
-
- break;
- }
+ break;
}
}
}
@@ -699,41 +727,38 @@
for (final AuxiliaryCache<K, V> aux : auxCaches)
{
- if (aux != null)
+ final Map<K, ICacheElement<K, V>> elementsFromAuxiliary =
+ new HashMap<>();
+
+ final CacheType cacheType = aux.getCacheType();
+
+ if (!localOnly || cacheType == CacheType.DISK_CACHE)
{
- final Map<K, ICacheElement<K, V>> elementsFromAuxiliary =
- new HashMap<>();
+ log.debug("Attempting to get from aux [{0}] which is of type: {1}",
+ () -> aux.getCacheName(), () -> cacheType);
- final CacheType cacheType = aux.getCacheType();
-
- if (!localOnly || cacheType == CacheType.DISK_CACHE)
+ try
{
- log.debug("Attempting to get from aux [{0}] which is of type: {1}",
- () -> aux.getCacheName(), () -> cacheType);
-
- try
- {
- elementsFromAuxiliary.putAll(aux.getMultiple(remainingKeys));
- }
- catch (final IOException e)
- {
- log.error("Error getting from aux", e);
- }
+ elementsFromAuxiliary.putAll(aux.getMultiple(remainingKeys));
}
-
- log.debug("Got CacheElements: {0}", elementsFromAuxiliary);
-
- processRetrievedElements(aux, elementsFromAuxiliary);
- elements.putAll(elementsFromAuxiliary);
-
- if (elements.size() == keys.size())
+ catch (final IOException e)
{
- break;
+ log.error("Error getting from aux", e);
}
- else
- {
- remainingKeys = pruneKeysFound(keys, elements);
- }
+ }
+
+ log.debug("Got CacheElements: {0}", elementsFromAuxiliary);
+
+ processRetrievedElements(aux, elementsFromAuxiliary);
+ elements.putAll(elementsFromAuxiliary);
+
+ if (elements.size() == keys.size())
+ {
+ break;
+ }
+ else
+ {
+ remainingKeys = pruneKeysFound(keys, elements);
}
}
@@ -840,36 +865,33 @@
{
final Map<K, ICacheElement<K, V>> elements = new HashMap<>();
- for (int i = auxCaches.length - 1; i >= 0; i--)
+ for (ListIterator<AuxiliaryCache<K, V>> i = auxCaches.listIterator(auxCaches.size()); i.hasPrevious();)
{
- final AuxiliaryCache<K, V> aux = auxCaches[i];
+ final AuxiliaryCache<K, V> aux = i.previous();
- if (aux != null)
+ final Map<K, ICacheElement<K, V>> elementsFromAuxiliary =
+ new HashMap<>();
+
+ final CacheType cacheType = aux.getCacheType();
+
+ if (!localOnly || cacheType == CacheType.DISK_CACHE)
{
- final Map<K, ICacheElement<K, V>> elementsFromAuxiliary =
- new HashMap<>();
+ log.debug("Attempting to get from aux [{0}] which is of type: {1}",
+ () -> aux.getCacheName(), () -> cacheType);
- final CacheType cacheType = aux.getCacheType();
-
- if (!localOnly || cacheType == CacheType.DISK_CACHE)
+ try
{
- log.debug("Attempting to get from aux [{0}] which is of type: {1}",
- () -> aux.getCacheName(), () -> cacheType);
-
- try
- {
- elementsFromAuxiliary.putAll(aux.getMatching(pattern));
- }
- catch (final IOException e)
- {
- log.error("Error getting from aux", e);
- }
-
- log.debug("Got CacheElements: {0}", elementsFromAuxiliary);
-
- processRetrievedElements(aux, elementsFromAuxiliary);
- elements.putAll(elementsFromAuxiliary);
+ elementsFromAuxiliary.putAll(aux.getMatching(pattern));
}
+ catch (final IOException e)
+ {
+ log.error("Error getting from aux", e);
+ }
+
+ log.debug("Got CacheElements: {0}", elementsFromAuxiliary);
+
+ processRetrievedElements(aux, elementsFromAuxiliary);
+ elements.putAll(elementsFromAuxiliary);
}
}
@@ -982,26 +1004,19 @@
*/
public Set<K> getKeySet(final boolean localOnly)
{
- final HashSet<K> allKeys = new HashSet<>(memCache.getKeySet());
-
- for (final AuxiliaryCache<K, V> aux : auxCaches)
- {
- if (aux != null)
- {
- if(!localOnly || aux.getCacheType() == CacheType.DISK_CACHE)
+ return Stream.concat(memCache.getKeySet().stream(), auxCaches.stream()
+ .filter(aux -> !localOnly || aux.getCacheType() == CacheType.DISK_CACHE)
+ .flatMap(aux -> {
+ try
{
- try
- {
- allKeys.addAll(aux.getKeySet());
- }
- catch (final IOException e)
- {
- // ignore
- }
+ return aux.getKeySet().stream();
}
- }
- }
- return allKeys;
+ catch (final IOException e)
+ {
+ return Stream.of();
+ }
+ }))
+ .collect(Collectors.toSet());
}
/**
@@ -1142,10 +1157,9 @@
}
// Removes from all auxiliary disk caches.
- for (final ICache<K, V> aux : auxCaches)
- {
- if (aux != null && (aux.getCacheType() == CacheType.DISK_CACHE || !localOnly))
- {
+ auxCaches.stream()
+ .filter(aux -> aux.getCacheType() == CacheType.DISK_CACHE || !localOnly)
+ .forEach(aux -> {
try
{
log.debug("Removing All keys from cacheType {0}",
@@ -1155,10 +1169,9 @@
}
catch (final IOException ex)
{
- log.error("Failure removing all from aux", ex);
+ log.error("Failure removing all from aux " + aux, ex);
}
- }
- }
+ });
}
/**
@@ -1274,16 +1287,15 @@
*/
public void save()
{
- if (alive.compareAndSet(true, false) == false)
+ if (!alive.get())
{
return;
}
- for (final ICache<K, V> aux : auxCaches)
- {
- try
- {
- if (aux.getStatus() == CacheStatus.ALIVE)
+ auxCaches.stream()
+ .filter(aux -> aux.getStatus() == CacheStatus.ALIVE)
+ .forEach(aux -> {
+ try
{
for (final K key : memCache.getKeySet())
{
@@ -1295,12 +1307,11 @@
}
}
}
- }
- catch (final IOException ex)
- {
- log.error("Failure saving aux caches.", ex);
- }
- }
+ catch (final IOException ex)
+ {
+ log.error("Failure saving aux caches.", ex);
+ }
+ });
log.debug("Called save for [{0}]", () -> cacheAttr.getCacheName());
}
@@ -1369,15 +1380,12 @@
stats.setStatElements(elems);
// memory + aux, memory is not considered an auxiliary internally
- final int total = auxCaches.length + 1;
- final ArrayList<IStats> auxStats = new ArrayList<>(total);
+ final ArrayList<IStats> auxStats = new ArrayList<>(auxCaches.size() + 1);
auxStats.add(getMemoryCache().getStatistics());
-
- for (final AuxiliaryCache<K, V> aux : auxCaches)
- {
- auxStats.add(aux.getStatistics());
- }
+ auxStats.addAll(auxCaches.stream()
+ .map(AuxiliaryCache::getStatistics)
+ .collect(Collectors.toList()));
// store the auxiliary stats
stats.setAuxiliaryCacheStats(auxStats);
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/engine/control/CompositeCacheConfigurator.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/engine/control/CompositeCacheConfigurator.java
index 5ecae58..f50ed6b 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/engine/control/CompositeCacheConfigurator.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/engine/control/CompositeCacheConfigurator.java
@@ -267,10 +267,7 @@
}
// Associate the auxiliaries with the cache
- @SuppressWarnings("unchecked") // No generic arrays in java
- final
- AuxiliaryCache<K, V>[] auxArray = auxList.toArray( new AuxiliaryCache[0] );
- cache.setAuxCaches( auxArray );
+ cache.setAuxCaches(auxList);
}
// Return the new cache
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/engine/memory/AbstractDoubleLinkedListMemoryCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/engine/memory/AbstractDoubleLinkedListMemoryCache.java
index 422530d..ca533ff 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/engine/memory/AbstractDoubleLinkedListMemoryCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/engine/memory/AbstractDoubleLinkedListMemoryCache.java
@@ -162,14 +162,7 @@
try
{
- for (int i = 0; i < chunkSizeCorrected; i++)
- {
- final ICacheElement<K, V> lastElement = spoolLastElement();
- if (lastElement == null)
- {
- break;
- }
- }
+ freeElements(chunkSizeCorrected);
// If this is out of the sync block it can detect a mismatch
// where there is none.
@@ -197,10 +190,9 @@
* @param numberToFree
* @return the number that were removed. if you ask to free 5, but there are only 3, you will
* get 3.
- * @throws IOException
*/
@Override
- public int freeElements(final int numberToFree) throws IOException
+ public int freeElements(final int numberToFree)
{
int freed = 0;
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/utils/discovery/UDPDiscoveryService.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/utils/discovery/UDPDiscoveryService.java
index fcb301a..bbe4b4e 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/utils/discovery/UDPDiscoveryService.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/utils/discovery/UDPDiscoveryService.java
@@ -24,6 +24,8 @@
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
@@ -65,7 +67,7 @@
private AtomicBoolean shutdown = new AtomicBoolean(false);
/** This is a set of services that have been discovered. */
- private final Set<DiscoveredService> discoveredServices = new CopyOnWriteArraySet<>();
+ private final ConcurrentMap<Integer, DiscoveredService> discoveredServices = new ConcurrentHashMap<>();
/** This a list of regions that are configured to use discovery. */
private final Set<String> cacheNames = new CopyOnWriteArraySet<>();
@@ -260,9 +262,7 @@
*/
public void removeDiscoveredService( final DiscoveredService service )
{
- final boolean contained = getDiscoveredServices().remove( service );
-
- if ( contained )
+ if (discoveredServices.remove(service.hashCode()) != null)
{
log.info( "Removing {0}", service );
}
@@ -277,39 +277,29 @@
*/
protected void addOrUpdateService( final DiscoveredService discoveredService )
{
- final Set<DiscoveredService> discoveredServices = getDiscoveredServices();
- // Since this is a set we can add it over an over.
// We want to replace the old one, since we may add info that is not part of the equals.
// The equals method on the object being added is intentionally restricted.
- if ( !discoveredServices.contains( discoveredService ) )
- {
- log.info( "Set does not contain service. I discovered {0}", discoveredService );
- log.debug( "Adding service in the set {0}", discoveredService );
- discoveredServices.add( discoveredService );
- }
- else
- {
+ discoveredServices.merge(discoveredService.hashCode(), discoveredService, (oldService, newService) -> {
log.debug( "Set contains service." );
- log.debug( "Updating service in the set {0}", discoveredService );
+ log.debug( "Updating service in the set {0}", newService );
// Update the list of cache names if it has changed.
// need to update the time this sucks. add has no effect convert to a map
- DiscoveredService theOldServiceInformation = discoveredServices.stream()
- .filter(service -> discoveredService.equals(service))
- .findFirst()
- .orElse(null);
-
- if (theOldServiceInformation != null &&
- !theOldServiceInformation.getCacheNames().equals(discoveredService.getCacheNames()))
+ if (!oldService.getCacheNames().equals(newService.getCacheNames()))
{
- log.info( "List of cache names changed for service: {0}",
- discoveredService );
+ log.info( "List of cache names changed for service: {0}", newService );
+
+ // replace it, we want to reset the payload and the last heard from time.
+ return newService;
}
- // replace it, we want to reset the payload and the last heard from time.
- discoveredServices.remove( discoveredService );
- discoveredServices.add( discoveredService );
- }
+ if (oldService.getLastHearFromTime() != newService.getLastHearFromTime())
+ {
+ return newService;
+ }
+
+ return oldService;
+ });
// Always Notify the listeners
// If we don't do this, then if a region using the default config is initialized after notification,
@@ -397,7 +387,7 @@
*/
public Set<DiscoveredService> getDiscoveredServices()
{
- return discoveredServices;
+ return new HashSet<>(discoveredServices.values());
}
/**
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/utils/struct/AbstractLRUMap.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/utils/struct/AbstractLRUMap.java
index b1a247d..53b56b0 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs3/utils/struct/AbstractLRUMap.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs3/utils/struct/AbstractLRUMap.java
@@ -441,19 +441,16 @@
}
log.trace( "verifycache: checking via keysets!" );
- map.forEach((key, value) -> {
- boolean found = false;
-
- for (LRUElementDescriptor<K, V> li2 = list.getFirst(); li2 != null; li2 = (LRUElementDescriptor<K, V>) li2.next )
- {
- if ( key.equals( li2.getKey() ) )
+ map.keySet().stream()
+ .filter(key -> {
+ for (LRUElementDescriptor<K, V> li2 = list.getFirst(); li2 != null; li2 = (LRUElementDescriptor<K, V>) li2.next )
{
- found = true;
- break;
+ if ( key.equals( li2.getKey() ) )
+ {
+ return true;
+ }
}
- }
- if ( !found )
- {
+
log.error( "verifycache: key not found in list : {0}", key );
dumpCacheEntries();
if ( map.containsKey( key ) )
@@ -464,8 +461,10 @@
{
log.error( "verifycache: map does NOT contain key, what the HECK!" );
}
- }
- });
+
+ return false;
+ })
+ .findFirst();
}
/**
diff --git a/commons-jcs-core/src/test/java/org/apache/commons/jcs3/auxiliary/lateral/LateralCacheNoWaitFacadeUnitTest.java b/commons-jcs-core/src/test/java/org/apache/commons/jcs3/auxiliary/lateral/LateralCacheNoWaitFacadeUnitTest.java
index 02eb6f8..a8e6133 100644
--- a/commons-jcs-core/src/test/java/org/apache/commons/jcs3/auxiliary/lateral/LateralCacheNoWaitFacadeUnitTest.java
+++ b/commons-jcs-core/src/test/java/org/apache/commons/jcs3/auxiliary/lateral/LateralCacheNoWaitFacadeUnitTest.java
@@ -56,7 +56,7 @@
facade.removeNoWait( noWait );
// VERIFY
- assertEquals( "Should have 0", 0, facade.noWaits.length );
+ assertEquals( "Should have 0", 0, facade.getNoWaitSize() );
assertFalse( "Should not be in the list. ", facade.containsNoWait( noWait ) );
}
@@ -83,7 +83,7 @@
facade.addNoWait( noWait2 );
// VERIFY
- assertEquals( "Should have 2", 2, facade.noWaits.length );
+ assertEquals( "Should have 2", 2, facade.getNoWaitSize() );
assertTrue( "Should be in the list.", facade.containsNoWait( noWait ) );
assertTrue( "Should be in the list.", facade.containsNoWait( noWait2 ) );
@@ -91,7 +91,7 @@
facade.removeNoWait( noWait );
// VERIFY
- assertEquals( "Should only have 1", 1, facade.noWaits.length );
+ assertEquals( "Should only have 1", 1, facade.getNoWaitSize() );
assertFalse( "Should not be in the list. ", facade.containsNoWait( noWait ) );
assertTrue( "Should be in the list.", facade.containsNoWait( noWait2 ) );
}
@@ -119,7 +119,7 @@
// VERIFY
assertTrue( "Should be in the list.", facade.containsNoWait( noWait ) );
- assertEquals( "Should only have 1", 1, facade.noWaits.length );
+ assertEquals( "Should only have 1", 1, facade.getNoWaitSize() );
}
/**
diff --git a/commons-jcs-core/src/test/java/org/apache/commons/jcs3/engine/control/CompositeCacheDiskUsageUnitTest.java b/commons-jcs-core/src/test/java/org/apache/commons/jcs3/engine/control/CompositeCacheDiskUsageUnitTest.java
index 3117f25..d4aab45 100644
--- a/commons-jcs-core/src/test/java/org/apache/commons/jcs3/engine/control/CompositeCacheDiskUsageUnitTest.java
+++ b/commons-jcs-core/src/test/java/org/apache/commons/jcs3/engine/control/CompositeCacheDiskUsageUnitTest.java
@@ -20,6 +20,7 @@
*/
import java.io.IOException;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -29,17 +30,16 @@
import org.apache.commons.jcs3.access.CacheAccess;
import org.apache.commons.jcs3.access.exception.CacheException;
import org.apache.commons.jcs3.auxiliary.AbstractAuxiliaryCache;
-import org.apache.commons.jcs3.auxiliary.AuxiliaryCache;
import org.apache.commons.jcs3.auxiliary.AuxiliaryCacheAttributes;
import org.apache.commons.jcs3.engine.CacheElement;
import org.apache.commons.jcs3.engine.CacheStatus;
import org.apache.commons.jcs3.engine.CompositeCacheAttributes;
import org.apache.commons.jcs3.engine.ElementAttributes;
import org.apache.commons.jcs3.engine.behavior.ICacheElement;
+import org.apache.commons.jcs3.engine.behavior.ICacheType.CacheType;
import org.apache.commons.jcs3.engine.behavior.ICompositeCacheAttributes;
import org.apache.commons.jcs3.engine.behavior.IElementAttributes;
import org.apache.commons.jcs3.engine.behavior.IElementSerializer;
-import org.apache.commons.jcs3.engine.behavior.ICacheType.CacheType;
import org.apache.commons.jcs3.engine.logging.behavior.ICacheEventLogger;
import org.apache.commons.jcs3.engine.stats.behavior.IStats;
@@ -107,11 +107,7 @@
final MockAuxCache<String, String> mock = new MockAuxCache<>();
mock.cacheType = CacheType.DISK_CACHE;
-
- @SuppressWarnings("unchecked")
- final
- AuxiliaryCache<String, String>[] auxArray = new AuxiliaryCache[] { mock };
- cache.setAuxCaches( auxArray );
+ cache.setAuxCaches(Arrays.asList(mock));
final ICacheElement<String, String> inputElement = new CacheElement<>( CACHE_NAME, "key", "value" );
@@ -140,11 +136,7 @@
final MockAuxCache<String, String> mock = new MockAuxCache<>();
mock.cacheType = CacheType.DISK_CACHE;
-
- @SuppressWarnings("unchecked")
- final
- AuxiliaryCache<String, String>[] auxArray = new AuxiliaryCache[] { mock };
- cache.setAuxCaches( auxArray );
+ cache.setAuxCaches(Arrays.asList(mock));
final ICacheElement<String, String> inputElement = new CacheElement<>( CACHE_NAME, "key", "value" );
@@ -177,11 +169,7 @@
final MockAuxCache<String, String> mock = new MockAuxCache<>();
mock.cacheType = CacheType.DISK_CACHE;
-
- @SuppressWarnings("unchecked")
- final
- AuxiliaryCache<String, String>[] auxArray = new AuxiliaryCache[] { mock };
- cache.setAuxCaches( auxArray );
+ cache.setAuxCaches(Arrays.asList(mock));
final ICacheElement<String, String> inputElement = new CacheElement<>( CACHE_NAME, "key", "value" );
@@ -216,11 +204,7 @@
final MockAuxCache<String, String> mock = new MockAuxCache<>();
mock.cacheType = CacheType.DISK_CACHE;
-
- @SuppressWarnings("unchecked")
- final
- AuxiliaryCache<String, String>[] auxArray = new AuxiliaryCache[] { mock };
- cache.setAuxCaches( auxArray );
+ cache.setAuxCaches(Arrays.asList(mock));
final ICacheElement<String, String> inputElement = new CacheElement<>( CACHE_NAME, "key", "value" );
@@ -255,11 +239,7 @@
final MockAuxCache<String, String> mock = new MockAuxCache<>();
mock.cacheType = CacheType.DISK_CACHE;
-
- @SuppressWarnings("unchecked")
- final
- AuxiliaryCache<String, String>[] auxArray = new AuxiliaryCache[] { mock };
- cache.setAuxCaches( auxArray );
+ cache.setAuxCaches(Arrays.asList(mock));
final ICacheElement<String, String> inputElement = new CacheElement<>( CACHE_NAME, "key", "value" );
@@ -295,11 +275,7 @@
final MockAuxCache<String, String> mockLateral = new MockAuxCache<>();
mockLateral.cacheType = CacheType.LATERAL_CACHE;
-
- @SuppressWarnings("unchecked")
- final
- AuxiliaryCache<String, String>[] auxArray = new AuxiliaryCache[] { mock, mockLateral };
- cache.setAuxCaches( auxArray );
+ cache.setAuxCaches(Arrays.asList(mock, mockLateral));
final ICacheElement<String, String> inputElement = new CacheElement<>( CACHE_NAME, "key", "value" );
diff --git a/commons-jcs-core/src/test/java/org/apache/commons/jcs3/engine/control/CompositeCacheUnitTest.java b/commons-jcs-core/src/test/java/org/apache/commons/jcs3/engine/control/CompositeCacheUnitTest.java
index 78931e2..6da9fd8 100644
--- a/commons-jcs-core/src/test/java/org/apache/commons/jcs3/engine/control/CompositeCacheUnitTest.java
+++ b/commons-jcs-core/src/test/java/org/apache/commons/jcs3/engine/control/CompositeCacheUnitTest.java
@@ -1,5 +1,19 @@
package org.apache.commons.jcs3.engine.control;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Map;
+
+import org.apache.commons.jcs3.auxiliary.MockAuxiliaryCache;
+import org.apache.commons.jcs3.engine.CacheElement;
+import org.apache.commons.jcs3.engine.CompositeCacheAttributes;
+import org.apache.commons.jcs3.engine.ElementAttributes;
+import org.apache.commons.jcs3.engine.behavior.ICacheElement;
+import org.apache.commons.jcs3.engine.behavior.ICacheType.CacheType;
+import org.apache.commons.jcs3.engine.behavior.ICompositeCacheAttributes;
+import org.apache.commons.jcs3.engine.behavior.IElementAttributes;
+import org.apache.commons.jcs3.engine.memory.MockMemoryCache;
+
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -21,19 +35,6 @@
import junit.framework.TestCase;
-import org.apache.commons.jcs3.auxiliary.MockAuxiliaryCache;
-import org.apache.commons.jcs3.engine.memory.MockMemoryCache;
-import org.apache.commons.jcs3.auxiliary.AuxiliaryCache;
-import org.apache.commons.jcs3.engine.CacheElement;
-import org.apache.commons.jcs3.engine.CompositeCacheAttributes;
-import org.apache.commons.jcs3.engine.ElementAttributes;
-import org.apache.commons.jcs3.engine.behavior.ICacheElement;
-import org.apache.commons.jcs3.engine.behavior.ICompositeCacheAttributes;
-import org.apache.commons.jcs3.engine.behavior.IElementAttributes;
-import org.apache.commons.jcs3.engine.behavior.ICacheType.CacheType;
-import java.io.IOException;
-import java.util.Map;
-
/**
* Tests that directly engage the composite cache.
* <p>
@@ -63,10 +64,7 @@
final MockAuxiliaryCache<String, Integer> diskMock = new MockAuxiliaryCache<>();
diskMock.cacheType = CacheType.DISK_CACHE;
- @SuppressWarnings("unchecked")
- final
- AuxiliaryCache<String, Integer>[] aux = new AuxiliaryCache[] { diskMock };
- cache.setAuxCaches( aux );
+ cache.setAuxCaches(Arrays.asList(diskMock));
// DO WORK
final int numToInsert = 10;
@@ -104,10 +102,7 @@
final MockAuxiliaryCache<String, Integer> diskMock = new MockAuxiliaryCache<>();
diskMock.cacheType = CacheType.REMOTE_CACHE;
- @SuppressWarnings("unchecked")
- final
- AuxiliaryCache<String, Integer>[] aux = new AuxiliaryCache[] { diskMock };
- cache.setAuxCaches( aux );
+ cache.setAuxCaches(Arrays.asList(diskMock));
// DO WORK
final int numToInsert = 10;
@@ -148,10 +143,7 @@
final MockAuxiliaryCache<String, Integer> diskMock = new MockAuxiliaryCache<>();
diskMock.cacheType = CacheType.DISK_CACHE;
- @SuppressWarnings("unchecked")
- final
- AuxiliaryCache<String, Integer>[] aux = new AuxiliaryCache[] { diskMock };
- cache.setAuxCaches( aux );
+ cache.setAuxCaches(Arrays.asList(diskMock));
// DO WORK
final int numToInsertPrefix1 = 10;
@@ -201,10 +193,7 @@
final MockAuxiliaryCache<String, Integer> diskMock = new MockAuxiliaryCache<>();
diskMock.cacheType = CacheType.DISK_CACHE;
- @SuppressWarnings("unchecked")
- final
- AuxiliaryCache<String, Integer>[] aux = new AuxiliaryCache[] { diskMock };
- cache.setAuxCaches( aux );
+ cache.setAuxCaches(Arrays.asList(diskMock));
// DO WORK
cache.getMatching( "junk" );
@@ -236,10 +225,7 @@
final MockAuxiliaryCache<String, Integer> diskMock = new MockAuxiliaryCache<>();
diskMock.cacheType = CacheType.REMOTE_CACHE;
- @SuppressWarnings("unchecked")
- final
- AuxiliaryCache<String, Integer>[] aux = new AuxiliaryCache[] { diskMock };
- cache.setAuxCaches( aux );
+ cache.setAuxCaches(Arrays.asList(diskMock));
// DO WORK
cache.getMatching( "junk" );