diff --git a/concurrent-tile-cache/pom.xml b/concurrent-tile-cache/pom.xml index c6f6061d..8e9ca15c 100644 --- a/concurrent-tile-cache/pom.xml +++ b/concurrent-tile-cache/pom.xml @@ -17,26 +17,10 @@ gt-coverage ${geotools.version} - - com.googlecode.concurrentlinkedhashmap - concurrentlinkedhashmap-lru - 1.3.2 - - - com.boundary - high-scale-lib - 1.0.3 - com.google.guava guava ${guava.version} - - - boundary-site - http://maven.boundary.com/artifactory/repo - - diff --git a/concurrent-tile-cache/src/main/java/it/geosolutions/concurrent/ConcurrentTileCache.java b/concurrent-tile-cache/src/main/java/it/geosolutions/concurrent/ConcurrentTileCache.java index dee91556..c00eead9 100644 --- a/concurrent-tile-cache/src/main/java/it/geosolutions/concurrent/ConcurrentTileCache.java +++ b/concurrent-tile-cache/src/main/java/it/geosolutions/concurrent/ConcurrentTileCache.java @@ -105,9 +105,6 @@ public int weigh(Object o, CachedTileImpl cti) { return (int) cti.getTileSize(); } }); - if (diagnosticEnabled) { - builder.removalListener(listener).recordStats(); - } return builder.build(); diff --git a/concurrent-tile-cache/src/main/java/it/geosolutions/concurrent/ConcurrentTileCacheMultiMap.java b/concurrent-tile-cache/src/main/java/it/geosolutions/concurrent/ConcurrentTileCacheMultiMap.java index 559416ae..0f76eaa8 100644 --- a/concurrent-tile-cache/src/main/java/it/geosolutions/concurrent/ConcurrentTileCacheMultiMap.java +++ b/concurrent-tile-cache/src/main/java/it/geosolutions/concurrent/ConcurrentTileCacheMultiMap.java @@ -7,20 +7,36 @@ import java.awt.image.RenderedImage; import java.util.Comparator; import java.util.Iterator; +import java.util.Map; import java.util.Observable; import java.util.Set; import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentSkipListSet; +import java.util.concurrent.atomic.AtomicLong; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.media.jai.TileCache; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; +import com.google.common.cache.RemovalCause; import com.google.common.cache.RemovalListener; import com.google.common.cache.RemovalNotification; import com.google.common.cache.Weigher; import com.sun.media.jai.util.CacheDiagnostics; +/** + * This implementation of the TileCache class uses a Guava Cache and a multimap in order to provide a better concurrency handling. The first object + * contains all the cached tiles while the second one contains the mapping of the tile keys for each image. This class implements + * {@link CacheDiagnostics} in order to get the statistics associated to the {@link TileCache}. The user can define the cache memory capacity, the + * concurrency level (which indicates in how many segments the cache must be divided), the threshold of the total memory to use and a boolean + * indicating if the diagnostic must be enabled. + * + * @author Nicola Lagomarsini GeoSolutions S.A.S. + * + */ public class ConcurrentTileCacheMultiMap extends Observable implements TileCache, CacheDiagnostics { /** The default memory threshold of the cache. */ @@ -43,11 +59,14 @@ public class ConcurrentTileCacheMultiMap extends Observable implements TileCache /** * A concurrent multimap used for mapping the tile keys for each image */ - private Cache> multimap; + private Map> multimap; /** The memory capacity of the cache. */ private long memoryCacheCapacity; + /** The current memory capacity of the cache. */ + private AtomicLong currentCacheCapacity; + /** The concurrency level of the cache. */ private int concurrencyLevel; @@ -58,9 +77,10 @@ public class ConcurrentTileCacheMultiMap extends Observable implements TileCache private volatile boolean diagnosticEnabled = DEFAULT_DIAGNOSTIC; /** - * The listener is used for receiving notification about the removal of a tile + * Logger to use for reporting the informations about the TileCache operations. */ - private final RemovalListener listener; + private final static Logger LOGGER = Logger.getLogger(ConcurrentTileCacheMultiMap.class + .toString()); public ConcurrentTileCacheMultiMap() { this(DEFAULT_MEMORY_CACHE, DEFAULT_DIAGNOSTIC, DEFAULT_MEMORY_THRESHOLD, @@ -77,14 +97,11 @@ public ConcurrentTileCacheMultiMap(long memoryCacheCapacity, boolean diagnostic, this.memoryCacheCapacity = memoryCacheCapacity; this.concurrencyLevel = concurrencyLevel; - // Listener creation - listener = createListener(diagnostic); - // cache creation cacheObject = buildCache(); // multimap creation - multimap = CacheBuilder.newBuilder().concurrencyLevel(concurrencyLevel).build(); + multimap = new ConcurrentHashMap>(); } /** Add a new tile to the cache */ @@ -96,35 +113,42 @@ public void add(RenderedImage owner, int tileX, int tileY, Raster data) { public void add(RenderedImage owner, int tileX, int tileY, Raster data, Object tileCacheMetric) { // This tile is not in the cache; create a new CachedTileImpl. // else just update. - Object key = CachedTileImpl.hashKey(owner, tileX, tileY); + // Key associated to the image Object imageKey = CachedTileImpl.hashKey(owner); + // old tile CachedTileImpl cti; // create a new tile CachedTileImpl cti_new = new CachedTileImpl(owner, tileX, tileY, data, tileCacheMetric); - // if the tile is already cached if (diagnosticEnabled) { - cti = (CachedTileImpl) cacheObject.asMap().put(key, cti_new); - synchronized (this) { + // if the tile is already cached + cti = (CachedTileImpl) cacheObject.asMap().putIfAbsent(cti_new.key, cti_new); + synchronized (cacheObject) { if (cti != null) { cti.updateTileTimeStamp(); cti.setAction(Actions.SUBSTITUTION_FROM_ADD); setChanged(); notifyObservers(cti); } + // Update Cache Memory Size + currentCacheCapacity.addAndGet(cti_new.getTileSize()); + // Update the tile action in order to notify it to the observers cti_new.setAction(Actions.ADDITION); setChanged(); notifyObservers(cti_new); - updateMultiMap(key, imageKey); + updateMultiMap(cti_new.key, imageKey); } } else { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Added new Tile Image key " + imageKey); + } // new tile insertion - cacheObject.put(key, cti_new); + cacheObject.asMap().putIfAbsent(cti_new.key, cti_new); // Atomically adds a new Map if needed and then adds a new tile inside the MultiMap. - updateMultiMap(key, imageKey); + updateMultiMap(cti_new.key, imageKey); } } @@ -133,7 +157,7 @@ public void remove(RenderedImage owner, int tileX, int tileY) { // Calculation of the tile key Object key = CachedTileImpl.hashKey(owner, tileX, tileY); // remove operation - removeTileFromKey(key); + removeTileByKey(key); } /** Retrieves the selected tile from the cache */ @@ -155,14 +179,20 @@ public Raster[] getTiles(RenderedImage owner) { // Calculation of the key associated to the image Object imageKey = CachedTileImpl.hashKey(owner); - Set keys = multimap.getIfPresent(imageKey); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Getting image Tiles Image key " + imageKey); + } + // Selection of the tile keys for the image + Set keys = multimap.get(imageKey); + // If no key is found then a null object is returned if (keys == null || keys.isEmpty()) { return tilesData; } + // Else it is created an iterator on the tile keys Iterator it = keys.iterator(); - + // Another check on the iterator if (it.hasNext()) { // arbitrarily set a temporary vector size Vector tempData = new Vector(10, 20); @@ -170,6 +200,7 @@ public Raster[] getTiles(RenderedImage owner) { // cache... while (it.hasNext()) { Object key = it.next(); + // get the tile from the key Raster rasterTile = getTileFromKey(key); // ...then add to the vector if present @@ -177,7 +208,7 @@ public Raster[] getTiles(RenderedImage owner) { tempData.add(rasterTile); } } - + // Vector size int tmpsize = tempData.size(); if (tmpsize > 0) { tilesData = (Raster[]) tempData.toArray(new Raster[tmpsize]); @@ -195,23 +226,25 @@ public void removeTiles(RenderedImage owner) { Object imageKey = CachedTileImpl.hashKey(owner); if (diagnosticEnabled) { - synchronized (this) { - Set keys = multimap.getIfPresent(imageKey); + synchronized (cacheObject) { + // Selection of the keys associated to the image and removal of each of them + Set keys = multimap.get(imageKey); if (keys != null) { Iterator it = keys.iterator(); while (it.hasNext()) { Object key = it.next(); - removeTileFromKey(key); + removeTileByKey(key); } } } } else { // Get the keys associated to the image and remove them - Set keys = multimap.getIfPresent(imageKey); + Set keys = multimap.get(imageKey); if (keys != null) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Removing image Tiles Image key " + imageKey); + } cacheObject.invalidateAll(keys); - // Then remove the multimap - multimap.invalidate(imageKey); } } } @@ -221,6 +254,9 @@ public void removeTiles(RenderedImage owner) { */ public void addTiles(RenderedImage owner, Point[] tileIndices, Raster[] tiles, Object tileCacheMetric) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Addeding Tiles"); + } // cycle through the array for adding tiles for (int i = 0; i < tileIndices.length; i++) { int tileX = tileIndices[i].x; @@ -237,6 +273,10 @@ public void addTiles(RenderedImage owner, Point[] tileIndices, Raster[] tiles, public Raster[] getTiles(RenderedImage owner, Point[] tileIndices) { // instantiation of the array Raster[] tilesData = new Raster[tileIndices.length]; + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Getting Tiles at the selected positions"); + } // cycle through the array for getting tiles for (int i = 0; i < tilesData.length; i++) { int tileX = tileIndices[i].x; @@ -257,31 +297,38 @@ public Raster[] getTiles(RenderedImage owner, Point[] tileIndices) { } /** Removes all tiles present in the cache without checking for the image owner */ - public synchronized void flush() { - // It is necessary to clear all the elements - // from the old cache. - if (diagnosticEnabled) { - // Creation of an iterator for accessing to every tile in the cache - Iterator keys = cacheObject.asMap().keySet().iterator(); - // cycle across the cache for removing and updating every tile - while (keys.hasNext()) { - Object key = keys.next(); - CachedTileImpl cti = (CachedTileImpl) cacheObject.asMap().remove(key); + public void flush() { + synchronized (cacheObject) { + // It is necessary to clear all the elements + // from the old cache. + if (diagnosticEnabled) { + // Creation of an iterator for accessing to every tile in the cache + Iterator keys = cacheObject.asMap().keySet().iterator(); + // cycle across the cache for removing and updating every tile + while (keys.hasNext()) { + Object key = keys.next(); + CachedTileImpl cti = (CachedTileImpl) cacheObject.asMap().remove(key); - // diagnosticEnabled + // diagnosticEnabled - cti.setAction(Actions.REMOVAL_FROM_FLUSH); - setChanged(); - notifyObservers(cti); + cti.setAction(Actions.REMOVAL_FROM_FLUSH); + setChanged(); + notifyObservers(cti); + } + } else { + // Invalidation of all the keys of the cache + cacheObject.invalidateAll(); } - } else { - cacheObject.invalidateAll(); - } - // multimap creation - multimap = CacheBuilder.newBuilder().concurrencyLevel(concurrencyLevel).build(); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Flushing cache"); + } - cacheObject = buildCache(); + // Cache creation + cacheObject = buildCache(); + // multimap creation + multimap = new ConcurrentHashMap>(); + } } /** @@ -291,7 +338,6 @@ public synchronized void flush() { */ public void memoryControl() { throw new UnsupportedOperationException("Memory Control not supported"); - } /** @@ -313,15 +359,16 @@ public int getTileCapacity() { } /** Sets the cache memory capacity and then flush and rebuild the cache */ - public synchronized void setMemoryCapacity(long memoryCacheCapacity) { - if (memoryCacheCapacity < 0) { - throw new IllegalArgumentException("Memory capacity too small"); - } else { - this.memoryCacheCapacity = memoryCacheCapacity; - flush(); - + public void setMemoryCapacity(long memoryCacheCapacity) { + synchronized (cacheObject) { + if (memoryCacheCapacity < 0) { + throw new IllegalArgumentException("Memory capacity too small"); + } else { + this.memoryCacheCapacity = memoryCacheCapacity; + // The flush is done in order to rebuild the cache with the new settings + flush(); + } } - } /** Retrieve the cache memory capacity */ @@ -330,15 +377,17 @@ public long getMemoryCapacity() { } /** Sets the cache memory threshold and then flush and rebuild the cache */ - public synchronized void setMemoryThreshold(float mt) { - if (mt < 0.0F || mt > 1.0F) { - throw new IllegalArgumentException("Memory threshold should be between 0 and 1"); - } else { - memoryCacheThreshold = mt; - flush(); + public void setMemoryThreshold(float mt) { + synchronized (cacheObject) { + if (mt < 0.0F || mt > 1.0F) { + throw new IllegalArgumentException("Memory threshold should be between 0 and 1"); + } else { + memoryCacheThreshold = mt; + // The flush is done in order to rebuild the cache with the new settings + flush(); + } } - } /** Retrieve the cache memory threshold */ @@ -347,15 +396,17 @@ public float getMemoryThreshold() { } /** Sets the cache ConcurrencyLevel and then flush and rebuild the cache */ - public synchronized void setConcurrencyLevel(int concurrency) { - if (concurrency < 1) { - throw new IllegalArgumentException("ConcurrencyLevel must be at least 1"); - } else { - concurrencyLevel = concurrency; - flush(); + public void setConcurrencyLevel(int concurrency) { + synchronized (cacheObject) { + if (concurrency < 1) { + throw new IllegalArgumentException("ConcurrencyLevel must be at least 1"); + } else { + concurrencyLevel = concurrency; + // The flush is done in order to rebuild the cache with the new settings + flush(); + } } - } /** Retrieve the cache concurrency level */ @@ -383,17 +434,21 @@ public Comparator getTileComparator() { } /** Disables diagnosticEnabled for the observers */ - public synchronized void disableDiagnostics() { - diagnosticEnabled = false; - flush(); - + public void disableDiagnostics() { + synchronized (cacheObject) { + diagnosticEnabled = false; + // The flush is done in order to rebuild the cache with the new settings + flush(); + } } /** Enables diagnosticEnabled for the observers */ - public synchronized void enableDiagnostics() { - diagnosticEnabled = true; - flush(); - + public void enableDiagnostics() { + synchronized (cacheObject) { + diagnosticEnabled = true; + // The flush is done in order to rebuild the cache with the new settings + flush(); + } } /** Retrieves the hit count from the cache statistics */ @@ -405,27 +460,8 @@ public long getCacheHitCount() { } /** Retrieves the current memory size of the cache */ - public synchronized long getCacheMemoryUsed() { - Iterator keys = multimap.asMap().keySet().iterator(); - long memoryUsed = 0; - while (keys.hasNext()) { - Object keyImage = keys.next(); - Set tileKeys = multimap.getIfPresent(keyImage); - if (tileKeys != null) { - int numTiles = tileKeys.size(); - Iterator iterator = tileKeys.iterator(); - if (numTiles > 0) { - CachedTileImpl cti = null; - while (cti == null && iterator.hasNext()) { - cti = cacheObject.getIfPresent(iterator.next()); - } - if (cti != null) { - memoryUsed += (cti.getTileSize() * numTiles); - } - } - } - } - return memoryUsed; + public long getCacheMemoryUsed() { + return currentCacheCapacity.get(); } /** Retrieves the miss count from the cache statistics */ @@ -450,6 +486,12 @@ public void resetCounts() { throw new UnsupportedOperationException("Operation not supported"); } + /** + * Creation of a listener to use for handling the removed tiles + * + * @param diagnostic + * @return + */ private RemovalListener createListener(final boolean diagnostic) { return new RemovalListener() { public void onRemoval(RemovalNotification n) { @@ -458,33 +500,64 @@ public void onRemoval(RemovalNotification n) { // the remove() method if (diagnostic) { - synchronized (this) { + synchronized (cacheObject) { + CachedTileImpl cti = n.getValue(); + // Update of the tile action if (n.wasEvicted()) { - CachedTileImpl cti = n.getValue(); cti.setAction(Actions.REMOVAL_FROM_EVICTION); - removeFromMultiMap(cti); - setChanged(); - notifyObservers(cti); + } else { + cti.setAction(Actions.MANUAL_REMOVAL); } + // Update Cache Memory Size + currentCacheCapacity.addAndGet(-cti.getTileSize()); + // Removal from the multimap + removeTileFromMultiMap(cti); + setChanged(); + notifyObservers(cti); } } else { - if (n.wasEvicted()) { - CachedTileImpl cti = n.getValue(); - removeFromMultiMap(cti); + CachedTileImpl cti = n.getValue(); + if (n.getCause() == RemovalCause.SIZE) { + // Logging if the tile is removed because the size is exceeded + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Removing from MultiMap for size"); + } } + removeTileFromMultiMap(cti); } } }; } - private void removeFromMultiMap(CachedTileImpl cti) { + /** + * Method for removing the tile keys from the multimap. If the KeySet associated to the image is empty, it is removed from the multimap. + * + * @param cti + */ + private void removeTileFromMultiMap(CachedTileImpl cti) { + // Tile key Object key = cti.getKey(); + // Image key Object imageKey = cti.getImageKey(); - Set tileKeys = multimap.getIfPresent(imageKey); + // KeySet associated to the image + Set tileKeys = multimap.get(imageKey); + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Removing tile from MultiMap Image key " + imageKey); + } + if (tileKeys != null) { + // Removal of the keys tileKeys.remove(key); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Removed Tile Image key " + imageKey); + } + // If the KeySet is empty then it is removed from the multimap if (tileKeys.isEmpty()) { - multimap.invalidate(imageKey); + multimap.remove(imageKey); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Removed image SET Image key " + imageKey); + } } } } @@ -498,58 +571,99 @@ public int weigh(Object o, CachedTileImpl cti) { return (int) cti.getTileSize(); } }); - builder.removalListener(listener); - if (diagnosticEnabled) { - builder.recordStats(); + // Setting of the listener + builder.removalListener(createListener(diagnosticEnabled)); + + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Building Cache"); } + // Update of the Memory cache size + currentCacheCapacity = new AtomicLong(0); return builder.build(); } + /** + * Update of the multimap when a tile is added. + * + * @param key + * @param imageKey + */ private void updateMultiMap(Object key, Object imageKey) { - Set tileKeys = multimap.getIfPresent(imageKey); - synchronized (this) { + Set tileKeys = null; + synchronized (cacheObject) { + // Check if the multimap contains the keys for the image + tileKeys = multimap.get(imageKey); if (tileKeys == null) { + // If no key is present then a new KeySet is created and then added to the multimap tileKeys = new ConcurrentSkipListSet(); multimap.put(imageKey, tileKeys); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Created new Set for the image Image key " + imageKey); + } } } + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Added Tile to the set Image key " + imageKey); + } + // Finally the tile key is added. tileKeys.add(key); } - private void removeTileFromKey(Object key) { + /** + * Removes the tile associated to the key. + * + * @param key + */ + private void removeTileByKey(Object key) { // check if the tile is still in cache CachedTileImpl cti = (CachedTileImpl) cacheObject.getIfPresent(key); // if so the tile is deleted (even if another thread write on it) if (cti != null) { if (diagnosticEnabled) { - synchronized (this) { + synchronized (cacheObject) { + // Upgrade the tile action cti.setAction(Actions.ABOUT_TO_REMOVAL); setChanged(); notifyObservers(cti); - + // Removal of the tile cti = (CachedTileImpl) cacheObject.asMap().remove(key); if (cti != null) { + // Upgrade the tile action cti.setAction(Actions.MANUAL_REMOVAL); setChanged(); notifyObservers(cti); } } } else { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Removed Tile Image key " + cti.getImageKey()); + } + // Discard the tile from the cache cacheObject.invalidate(key); } } } + /** + * Gets the tile associated to the key. + * + * @param key + * @return + */ private Raster getTileFromKey(Object key) { Raster tileData = null; // check if the tile is present - CachedTileImpl cti = (CachedTileImpl) cacheObject.getIfPresent(key); + CachedTileImpl cti = (CachedTileImpl) cacheObject.asMap().get(key); + // If not tile is found, null is returned if (cti == null) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Null Tile returned"); + } return null; } if (diagnosticEnabled) { - synchronized (this) { + synchronized (cacheObject) { // Update last-access time for diagnosticEnabled cti.updateTileTimeStamp(); @@ -558,6 +672,9 @@ private Raster getTileFromKey(Object key) { notifyObservers(cti); } } + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Get the selected tile Image key " + cti.getImageKey()); + } // return the selected tile tileData = cti.getTile(); return tileData; diff --git a/concurrent-tile-cache/src/main/java/it/geosolutions/concurrentlinked/ConcurrentCache.java b/concurrent-tile-cache/src/main/java/it/geosolutions/concurrentlinked/ConcurrentCache.java deleted file mode 100644 index 30bfb171..00000000 --- a/concurrent-tile-cache/src/main/java/it/geosolutions/concurrentlinked/ConcurrentCache.java +++ /dev/null @@ -1,440 +0,0 @@ -package it.geosolutions.concurrentlinked; - -import it.geosolutions.concurrent.CachedTileImpl; -import it.geosolutions.concurrent.ConcurrentTileCache.Actions; -import java.awt.Point; -import java.awt.image.Raster; -import java.awt.image.RenderedImage; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.Iterator; -import java.util.Observable; -import java.util.concurrent.ConcurrentHashMap; -import javax.media.jai.TileCache; -import com.sun.media.jai.util.CacheDiagnostics; - -public class ConcurrentCache extends Observable implements TileCache, - CacheDiagnostics { - -/** Default value for memory threshold */ -public static final float DEFAULT_MEMORY_THRESHOLD = 0.75F; - -/** Default value for cache memory */ -public static final long DEFAULT_MEMORY_CACHE = 16L * 1024L * 1024L; - -/** Default boolean for diagnostic mode */ -public static final boolean DEFAULT_DIAGNOSTIC = false; - -/** Default ConcurrentHashMap concurrency level */ -public static final int DEFAULT_CONCURRENCY_LEVEL = 16; - -/** Cache memory capacity */ -private long memoryCacheCapacity = DEFAULT_MEMORY_CACHE; - -/** concurrency level of the ConcurrentHashMap */ -private int concurrencyLevel = DEFAULT_CONCURRENCY_LEVEL; - -/** Cache memory threshold (typically 0.75F) */ -private float memoryCacheThreshold = DEFAULT_MEMORY_THRESHOLD; - -/** The real cache */ -private ConcurrentHashMap cacheObject = new ConcurrentHashMap( - 1000); - -/** - * Current diagnostic mode (enabled or not). This variable is set to volatile - * for visibility - */ -private volatile boolean diagnosticEnabled = DEFAULT_DIAGNOSTIC; - -/** Current number of cache miss */ -private int missNumber; - -/** Current number of cache hits */ -private int hitNumber; - -/* Simple constructor */ -public ConcurrentCache() { - this(DEFAULT_MEMORY_CACHE, DEFAULT_CONCURRENCY_LEVEL, - DEFAULT_MEMORY_THRESHOLD, DEFAULT_DIAGNOSTIC); -} - -/* Parameterized constructor */ -public ConcurrentCache(long memoryCacheCapacity, int concurrencyLevel, - float memoryCacheThreshold, boolean diagnosticEnabled) { - this.concurrencyLevel = concurrencyLevel; - this.memoryCacheCapacity = memoryCacheCapacity; - this.diagnosticEnabled = diagnosticEnabled; - this.memoryCacheThreshold = memoryCacheThreshold; - /* the counters are set to 0 */ - hitNumber = 0; - missNumber = 0; - System.err.println("Using ConcurrentCache"); -} - -public void add(RenderedImage image, int xTile, int yTile, Raster dataTile) { - this.add(image, xTile, yTile, dataTile, null); -} - -/** - * This method adds a new tile in cache and, if diagnostic is enabled, notify - * observers - */ -public void add(RenderedImage image, int xTile, int yTile, Raster dataTile, - Object tileMetric) { - /* Tile key calculation */ - Object key = CachedTileImpl.hashKey(image, xTile, yTile); - /* New tile creation */ - CachedTileImpl newValue = new CachedTileImpl(image, xTile, yTile, dataTile, - tileMetric); - /* If diagnostic is enabled the tile status is changed */ - if (diagnosticEnabled) { - synchronized (this) { - /* Updates the new tile status and notifies the observers */ - newValue.setAction(Actions.ADDITION); - setChanged(); - notifyObservers(newValue); - /* Puts the new value in cache and takes the old one */ - CachedTileImpl oldValue = cacheObject.put(key, newValue); - if (oldValue != null) { - hitNumber++; - /* Update the old tile status and notify the observers */ - oldValue.updateTileTimeStamp(); - oldValue.setAction(Actions.SUBSTITUTION_FROM_ADD); - setChanged(); - notifyObservers(oldValue); - return; - } - } - } else { - /* Simply put the value in cache */ - cacheObject.put(key, newValue); - } -} - -/** This method add an array of tiles at given positions */ -public void addTiles(RenderedImage image, Point[] positions, - Raster[] dataTiles, Object tileMetric) { - for (int i = 0; i < positions.length; i++) { - int xIndex = positions[i].x; - int yIndex = positions[i].y; - add(image, xIndex, yIndex, dataTiles[i], tileMetric); - } -} - -/** - * This method flushes the cache and, if diagnostic is enabled, reset the - * counters and, for every tile, update tile status - */ -public synchronized void flush() { - if (diagnosticEnabled) { - /* - * An iterator of all the key in the cache is used for updating every - * tile and the removing it - */ - CachedTileImpl oldValue; - Iterator iter = cacheObject.keySet().iterator(); - while (iter.hasNext()) { - oldValue = cacheObject.remove(iter.next()); - oldValue.setAction(Actions.REMOVAL_FROM_FLUSH); - oldValue.updateTileTimeStamp(); - setChanged(); - notifyObservers(oldValue); - } - /* Counter reset */ - hitNumber = 0; - missNumber = 0; - } else { - /* Simple cache clearing */ - cacheObject.clear(); - } - -} - -/** This method gets the current cache memory capacity */ -public long getMemoryCapacity() { - return memoryCacheCapacity; -} - -/** This method gets the current cache memory threshold */ -public float getMemoryThreshold() { - return memoryCacheThreshold; -} - -/** - * This method gets a tile raster from his (x,y) tile coordinates and the image - * reference - */ -public Raster getTile(RenderedImage image, int xTile, int yTile) { - /* Key creation */ - Object key = CachedTileImpl.hashKey(image, xTile, yTile); - if (diagnosticEnabled) { - synchronized (this) { - /* - * In diagnostic mode the oldvalue, if present, is updated and - * retrieved - */ - CachedTileImpl oldValue = cacheObject.get(key); - if (oldValue != null) { - /* if the tile is present the hit number is increased */ - hitNumber++; - oldValue.setAction(Actions.UPDATING_TILE_FROM_GETTILE); - oldValue.updateTileTimeStamp(); - /* Observers notifications */ - setChanged(); - notifyObservers(oldValue); - return oldValue.getTile(); - } else { - /* if the tile is not present the miss number is increased */ - missNumber++; - return null; - } - } - } else { - /* The tile is returned if present, else null returned */ - CachedTileImpl oldValue = cacheObject.get(key); - if (oldValue != null) { - return oldValue.getTile(); - } else { - return null; - } - } -} - -/** All the tile of the specific image are returned */ -public Raster[] getTiles(RenderedImage image) { - // instantiation of the result array - Raster[] tilesData = null; - // total number of tiles present in the cache - int tileCount = (int) cacheObject.size(); - - int size = Math.min(image.getNumXTiles() * image.getNumYTiles(), tileCount); - - if (size > 0) { - int minTx = image.getMinTileX(); - int minTy = image.getMinTileY(); - int maxTx = minTx + image.getNumXTiles(); - int maxTy = minTy + image.getNumYTiles(); - - // creates a temporary data arrayList - ArrayList tempData = new ArrayList(); - // every not-null raster is added to the array - for (int y = minTy; y < maxTy; y++) { - for (int x = minTx; x < maxTx; x++) { - - Raster rasterTile = getTile(image, x, y); - - if (rasterTile != null) { - tempData.add(rasterTile); - } - } - } - // the arrayList is then changed in an array - int tmpsize = tempData.size(); - if (tmpsize > 0) { - tilesData = (Raster[]) tempData.toArray(new Raster[tmpsize]); - } - } - - return tilesData; -} - -/** This method returns an array of tiles at the given positions */ -public Raster[] getTiles(RenderedImage image, Point[] positions) { - /* Initialization of an array of rasters */ - Raster[] tileData = new Raster[positions.length]; - if (diagnosticEnabled) { - synchronized (this) { - /* - * If the diagnostic mode is enabled, the tiles are returned from - * the method getTile which updates the tile status - */ - for (int j = 0; j < positions.length; j++) { - int xTile = positions[j].x; - int yTile = positions[j].y; - tileData[j] = getTile(image, xTile, yTile); - } - } - } else { - /* - * Else, they are simply returned by the ConcurrentHashMap.get() - * method - */ - for (int j = 0; j < positions.length; j++) { - int xTile = positions[j].x; - int yTile = positions[j].y; - Object key = CachedTileImpl.hashKey(image, xTile, yTile); - tileData[j] = cacheObject.get(key).getTile(); - } - } - return tileData; -} - -/** This method removes the specified tile and notify it to the observers */ -public void remove(RenderedImage image, int xTile, int yTile) { - /* Tile key calculation */ - Object key = CachedTileImpl.hashKey(image, xTile, yTile); - if (diagnosticEnabled) { - synchronized (this) { - /* - * In diagnostic mode this method check if the old tile was present - * and if so update its status and notify it to the observers, and - * removes it - */ - CachedTileImpl oldValue = cacheObject.get(key); - if (oldValue != null) { - oldValue.updateTileTimeStamp(); - oldValue.setAction(Actions.ABOUT_TO_REMOVAL); - setChanged(); - notifyObservers(oldValue); - cacheObject.remove(key); - oldValue.updateTileTimeStamp(); - oldValue.setAction(Actions.MANUAL_REMOVAL); - setChanged(); - notifyObservers(oldValue); - } - } - } else { - /* The tile is removed without checking if it is present or not */ - cacheObject.remove(key); - } -} - -/** This method removes all the tiles that belong to the specified image */ -public void removeTiles(RenderedImage image) { - /* Image tile coordinates */ - int minTx = image.getMinTileX(); - int minTy = image.getMinTileY(); - int maxTx = minTx + image.getNumXTiles(); - int maxTy = minTy + image.getNumYTiles(); - if (diagnosticEnabled) { - synchronized (this) { - /* - * This method is the same for both the diagnostic or non-diagnostic - * mode the difference is the sincronized block - */ - removeAllImageTiles(image, minTx, maxTx, minTy, maxTy); - } - } else { - removeAllImageTiles(image, minTx, maxTx, minTy, maxTy); - } -} - -/** This method cycles through the image eliminating all of its tiles */ -private void removeAllImageTiles(RenderedImage image, int minX, int maxX, - int minY, int maxY) { - for (int y = minY; y < maxY; y++) { - for (int x = minX; x < maxX; x++) { - remove(image, x, y); - } - } -} - -/** This method sets the memory capacity, then flush and rebuild the cache */ -public synchronized void setMemoryCapacity(long memoryCacheCapacity) { - if (memoryCacheCapacity < 0) { - throw new IllegalArgumentException("Memory capacity too small"); - } else { - this.memoryCacheCapacity = memoryCacheCapacity; - flush(); - } - -} - -/** This method sets the memory threshold, then flush and rebuild the cache */ -public synchronized void setMemoryThreshold(float memoryCacheThreshold) { - if (memoryCacheThreshold < 0 || memoryCacheThreshold > 1) { - throw new IllegalArgumentException( - "Memory threshold must be between 0 and 1"); - } else { - this.memoryCacheThreshold = memoryCacheThreshold; - flush(); - } - -} - -/** - * This method sets the cache ConcurrencyLevel and then flush and rebuild the - * cache - */ -public synchronized void setConcurrencyLevel(int concurrency) { - if (concurrency < 1) { - throw new IllegalArgumentException( - "ConcurrencyLevel must be at least 1"); - } else { - concurrencyLevel = concurrency; - flush(); - - } - -} - -/** Diagnostic is disabled, then the cache is flushed and rebuilt */ -public synchronized void disableDiagnostics() { - this.diagnosticEnabled = false; - flush(); -} - -/** Diagnostic is enabled, then the cache is flushed and rebuilt */ -public synchronized void enableDiagnostics() { - this.diagnosticEnabled = true; - flush(); -} - -/** The counters are set to 0 when the cache is flushed */ -public synchronized void resetCounts() { - flush(); -} - -/** This method returns the number of cache hits */ -public long getCacheHitCount() { - return hitNumber; -} - -/** This method returns the cache weighed size */ -public long getCacheMemoryUsed() { - return -1; -} - -/** This method returns the number of cache miss */ -public long getCacheMissCount() { - return missNumber; -} - -/** This method returns the number of tile present in the cache */ -public long getCacheTileCount() { - return cacheObject.size(); -} - -/** This method returns the cache concurrency level */ -public int getConcurrencyLevel() { - return concurrencyLevel; -} - -/** Not supported */ -public void setTileCapacity(int arg0) { - throw new UnsupportedOperationException("Deprecated Operation"); - -} - -/** Not supported */ -public int getTileCapacity() { - throw new UnsupportedOperationException("Deprecated Operation"); -} - -/** Not supported */ -public Comparator getTileComparator() { - throw new UnsupportedOperationException("Comparator not supported"); -} - -/** Not supported */ -public void setTileComparator(Comparator arg0) { - throw new UnsupportedOperationException("Comparator not supported"); -} - -/** Not supported */ -public void memoryControl() { - throw new UnsupportedOperationException("Memory Control not supported"); -} - -} diff --git a/concurrent-tile-cache/src/main/java/it/geosolutions/concurrentlinked/ConcurrentLinkedCache.java b/concurrent-tile-cache/src/main/java/it/geosolutions/concurrentlinked/ConcurrentLinkedCache.java deleted file mode 100644 index ea45cdb3..00000000 --- a/concurrent-tile-cache/src/main/java/it/geosolutions/concurrentlinked/ConcurrentLinkedCache.java +++ /dev/null @@ -1,486 +0,0 @@ -package it.geosolutions.concurrentlinked; - -import it.geosolutions.concurrent.CachedTileImpl; -import it.geosolutions.concurrent.ConcurrentTileCache.Actions; -import java.awt.Point; -import java.awt.image.Raster; -import java.awt.image.RenderedImage; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.Iterator; -import java.util.Observable; -import javax.media.jai.TileCache; -import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap; -import com.googlecode.concurrentlinkedhashmap.EvictionListener; -import com.googlecode.concurrentlinkedhashmap.Weigher; -import com.sun.media.jai.util.CacheDiagnostics; - -public class ConcurrentLinkedCache extends Observable implements TileCache, - CacheDiagnostics { - -/** Default value for memory threshold */ -public static final float DEFAULT_MEMORY_THRESHOLD = 0.75F; - -/** Default value for cache memory */ -public static final long DEFAULT_MEMORY_CACHE = 16L * 1024L * 1024L; - -/** Default boolean for diagnostic mode */ -public static final boolean DEFAULT_DIAGNOSTIC = false; - -/** Default ConcurrentLinkedHashMap concurrency level */ -public static final int DEFAULT_CONCURRENCY_LEVEL = 16; - -/** The real cache */ -private ConcurrentLinkedHashMap cacheObject; - -/** Cache memory capacity */ -private long memoryCacheCapacity = DEFAULT_MEMORY_CACHE; - -/** concurrency level of the ConcurrentLinkedHashMap */ -private int concurrencyLevel = DEFAULT_CONCURRENCY_LEVEL; - -/** Cache memory threshold (typically 0.75F) */ -private float memoryCacheThreshold = DEFAULT_MEMORY_THRESHOLD; - -/** - * Current diagnostic mode (enabled or not). This variable is set to volatile - * for visibility - */ -private volatile boolean diagnosticEnabled = DEFAULT_DIAGNOSTIC; - -/** Current number of cache miss */ -private int missNumber; - -/** Current number of cache hits */ -private int hitNumber; - -/** - * Eviction listener for catching the tile evicted by the - * ConcurrentLinkedHashMap and, if diagnostic is enabled, the eviction is - * notified to the observer - */ -private EvictionListener listener = new EvictionListener() { - - public void onEviction(Object key, CachedTileImpl oldValue) { - if (diagnosticEnabled) { - synchronized (this) { - oldValue.updateTileTimeStamp(); - oldValue.setAction(Actions.REMOVAL_FROM_EVICTION); - setChanged(); - notifyObservers(oldValue); - } - - } - } - -}; - -/* Simple constructor */ -public ConcurrentLinkedCache() { - this(DEFAULT_MEMORY_CACHE, DEFAULT_CONCURRENCY_LEVEL, - DEFAULT_MEMORY_THRESHOLD, DEFAULT_DIAGNOSTIC); -} - -/* Parameterized constructor */ -public ConcurrentLinkedCache(long memoryCacheCapacity, int concurrencyLevel, - float memoryCacheThreshold, boolean diagnosticEnabled) { - this.concurrencyLevel = concurrencyLevel; - this.memoryCacheCapacity = memoryCacheCapacity; - this.diagnosticEnabled = diagnosticEnabled; - this.memoryCacheThreshold = memoryCacheThreshold; - /* the cache instantiation is done in the buildLinkedCache() method */ - cacheObject = buildLinkedCache(); - /* the counters are set to 0 */ - hitNumber = 0; - missNumber = 0; - System.err.println("Using ConcurrentLinkedCache"); -} - -/** Private method for building the cache */ -private ConcurrentLinkedHashMap buildLinkedCache() { - /* Builder instantiation */ - ConcurrentLinkedHashMap.Builder builder = new ConcurrentLinkedHashMap.Builder(); - builder.concurrencyLevel(concurrencyLevel) - .maximumWeightedCapacity( - (long) (memoryCacheCapacity * memoryCacheThreshold)) - /* The weigher is used for weighing every entry */ - .weigher(new Weigher() { - public int weightOf(CachedTileImpl tile) { - return (int) ((CachedTileImpl) tile).getTileSize(); - } - }); - /* Listener is used only with diagnostic */ - if (diagnosticEnabled) { - builder.listener(listener); - } - /* Cache creation */ - return builder.build(); -} - -public void add(RenderedImage image, int xTile, int yTile, Raster dataTile) { - this.add(image, xTile, yTile, dataTile, null); -} - -/** - * This method adds a new tile in cache and, if diagnostic is enabled, notify - * observers - */ -public void add(RenderedImage image, int xTile, int yTile, Raster dataTile, - Object tileMetric) { - /* Tile key calculation */ - Object key = CachedTileImpl.hashKey(image, xTile, yTile); - /* New tile creation */ - CachedTileImpl newValue = new CachedTileImpl(image, xTile, yTile, dataTile, - tileMetric); - /* If diagnostic is enabled the tile status is changed */ - if (diagnosticEnabled) { - synchronized (this) { - /* Updates the new tile status and notifies the observers */ - newValue.setAction(Actions.ADDITION); - setChanged(); - notifyObservers(newValue); - /* Puts the new value in cache and takes the old one */ - CachedTileImpl oldValue = cacheObject.put(key, newValue); - if (oldValue != null) { - hitNumber++; - /* Update the old tile status and notify the observers */ - oldValue.updateTileTimeStamp(); - oldValue.setAction(Actions.SUBSTITUTION_FROM_ADD); - setChanged(); - notifyObservers(oldValue); - return; - } - } - } else { - /* Simply put the value in cache */ - cacheObject.put(key, newValue); - } -} - -/** This method add an array of tiles at given positions */ -public void addTiles(RenderedImage image, Point[] positions, - Raster[] dataTiles, Object tileMetric) { - for (int i = 0; i < positions.length; i++) { - int xIndex = positions[i].x; - int yIndex = positions[i].y; - add(image, xIndex, yIndex, dataTiles[i], tileMetric); - } -} - -/** - * This method flushes the cache and, if diagnostic is enabled, reset the - * counters and, for every tile, update tile status - */ -public synchronized void flush() { - if (diagnosticEnabled) { - /* - * An iterator of all the key in the cache is used for updating every - * tile and the removing it - */ - CachedTileImpl oldValue; - Iterator iter = cacheObject.keySet().iterator(); - while (iter.hasNext()) { - oldValue = cacheObject.remove(iter.next()); - oldValue.setAction(Actions.REMOVAL_FROM_FLUSH); - oldValue.updateTileTimeStamp(); - setChanged(); - notifyObservers(oldValue); - } - /* Counter reset */ - hitNumber = 0; - missNumber = 0; - } else { - /* Simple cache clearing */ - cacheObject.clear(); - } - /* The cache is rebuilt */ - cacheObject = buildLinkedCache(); -} - -/** This method gets the current cache memory capacity */ -public long getMemoryCapacity() { - return memoryCacheCapacity; -} - -/** This method gets the current cache memory threshold */ -public float getMemoryThreshold() { - return memoryCacheThreshold; -} - -/** - * This method gets a tile raster from his (x,y) tile coordinates and the image - * reference - */ -public Raster getTile(RenderedImage image, int xTile, int yTile) { - /* Key creation */ - Object key = CachedTileImpl.hashKey(image, xTile, yTile); - if (diagnosticEnabled) { - synchronized (this) { - /* - * In diagnostic mode the oldvalue, if present, is updated and - * retrieved - */ - CachedTileImpl oldValue = cacheObject.get(key); - if (oldValue != null) { - /* if the tile is present the hit number is increased */ - hitNumber++; - oldValue.setAction(Actions.UPDATING_TILE_FROM_GETTILE); - oldValue.updateTileTimeStamp(); - /* Observers notifications */ - setChanged(); - notifyObservers(oldValue); - return oldValue.getTile(); - } else { - /* if the tile is not present the miss number is increased */ - missNumber++; - return null; - } - } - } else { - /* The tile is returned if present, else null returned */ - CachedTileImpl oldValue = cacheObject.get(key); - if (oldValue != null) { - return oldValue.getTile(); - } else { - return null; - } - } -} - -/** All the tile of the specific image are returned */ -public Raster[] getTiles(RenderedImage image) { - // instantiation of the result array - Raster[] tilesData = null; - // total number of tiles present in the cache - int tileCount = (int) cacheObject.size(); - - int size = Math.min(image.getNumXTiles() * image.getNumYTiles(), tileCount); - - if (size > 0) { - int minTx = image.getMinTileX(); - int minTy = image.getMinTileY(); - int maxTx = minTx + image.getNumXTiles(); - int maxTy = minTy + image.getNumYTiles(); - - // creates a temporary data arrayList - ArrayList tempData = new ArrayList(); - // every not-null raster is added to the array - for (int y = minTy; y < maxTy; y++) { - for (int x = minTx; x < maxTx; x++) { - - Raster rasterTile = getTile(image, x, y); - - if (rasterTile != null) { - tempData.add(rasterTile); - } - } - } - // the arrayList is then changed in an array - int tmpsize = tempData.size(); - if (tmpsize > 0) { - tilesData = (Raster[]) tempData.toArray(new Raster[tmpsize]); - } - } - - return tilesData; -} - -/** This method returns an array of tiles at the given positions */ -public Raster[] getTiles(RenderedImage image, Point[] positions) { - /* Initialization of an array of rasters */ - Raster[] tileData = new Raster[positions.length]; - if (diagnosticEnabled) { - synchronized (this) { - /* - * If the diagnostic mode is enabled, the tiles are returned from - * the method getTile which updates the tile status - */ - for (int j = 0; j < positions.length; j++) { - int xTile = positions[j].x; - int yTile = positions[j].y; - tileData[j] = getTile(image, xTile, yTile); - } - } - } else { - /* - * Else, they are simply returned by the ConcurrentLinkedHashMap.get() - * method - */ - for (int j = 0; j < positions.length; j++) { - int xTile = positions[j].x; - int yTile = positions[j].y; - Object key = CachedTileImpl.hashKey(image, xTile, yTile); - tileData[j] = cacheObject.get(key).getTile(); - } - } - return tileData; -} - -/** This method removes the specified tile and notify it to the observers */ -public void remove(RenderedImage image, int xTile, int yTile) { - /* Tile key calculation */ - Object key = CachedTileImpl.hashKey(image, xTile, yTile); - if (diagnosticEnabled) { - synchronized (this) { - /* - * In diagnostic mode this method check if the old tile was present - * and if so update its status and notify it to the observers, and - * removes it - */ - CachedTileImpl oldValue = cacheObject.get(key); - if (oldValue != null) { - oldValue.updateTileTimeStamp(); - oldValue.setAction(Actions.ABOUT_TO_REMOVAL); - setChanged(); - notifyObservers(oldValue); - cacheObject.remove(key); - oldValue.updateTileTimeStamp(); - oldValue.setAction(Actions.MANUAL_REMOVAL); - setChanged(); - notifyObservers(oldValue); - } - } - } else { - /* The tile is removed without checking if it is present or not */ - cacheObject.remove(key); - } -} - -/** This method removes all the tiles that belong to the specified image */ -public void removeTiles(RenderedImage image) { - /* Image tile coordinates */ - int minTx = image.getMinTileX(); - int minTy = image.getMinTileY(); - int maxTx = minTx + image.getNumXTiles(); - int maxTy = minTy + image.getNumYTiles(); - if (diagnosticEnabled) { - synchronized (this) { - /* - * This method is the same for both the diagnostic or non-diagnostic - * mode the difference is the sincronized block - */ - removeAllImageTiles(image, minTx, maxTx, minTy, maxTy); - } - } else { - removeAllImageTiles(image, minTx, maxTx, minTy, maxTy); - } -} - -/** This method cycles through the image eliminating all of its tiles */ -private void removeAllImageTiles(RenderedImage image, int minX, int maxX, - int minY, int maxY) { - for (int y = minY; y < maxY; y++) { - for (int x = minX; x < maxX; x++) { - remove(image, x, y); - } - } -} - -/** This method sets the memory capacity, then flush and rebuild the cache */ -public synchronized void setMemoryCapacity(long memoryCacheCapacity) { - if (memoryCacheCapacity < 0) { - throw new IllegalArgumentException("Memory capacity too small"); - } else { - this.memoryCacheCapacity = memoryCacheCapacity; - flush(); - } - -} - -/** This method sets the memory threshold, then flush and rebuild the cache */ -public synchronized void setMemoryThreshold(float memoryCacheThreshold) { - if (memoryCacheThreshold < 0 || memoryCacheThreshold > 1) { - throw new IllegalArgumentException( - "Memory threshold must be between 0 and 1"); - } else { - this.memoryCacheThreshold = memoryCacheThreshold; - flush(); - } - -} - -/** - * This method sets the cache ConcurrencyLevel and then flush and rebuild the - * cache - */ -public synchronized void setConcurrencyLevel(int concurrency) { - if (concurrency < 1) { - throw new IllegalArgumentException( - "ConcurrencyLevel must be at least 1"); - } else { - concurrencyLevel = concurrency; - flush(); - - } - -} - -/** Diagnostic is disabled, then the cache is flushed and rebuilt */ -public synchronized void disableDiagnostics() { - this.diagnosticEnabled = false; - flush(); -} - -/** Diagnostic is enabled, then the cache is flushed and rebuilt */ -public synchronized void enableDiagnostics() { - this.diagnosticEnabled = true; - flush(); -} - -/** The counters are set to 0 when the cache is flushed */ -public synchronized void resetCounts() { - flush(); -} - -/** This method returns the number of cache hits */ -public long getCacheHitCount() { - return hitNumber; -} - -/** This method returns the cache weighed size */ -public long getCacheMemoryUsed() { - return cacheObject.weightedSize(); -} - -/** This method returns the number of cache miss */ -public long getCacheMissCount() { - return missNumber; -} - -/** This method returns the number of tile present in the cache */ -public long getCacheTileCount() { - return cacheObject.size(); -} - -/** This method returns the cache concurrency level */ -public int getConcurrencyLevel() { - return concurrencyLevel; -} - -/** Not supported */ -public void setTileCapacity(int arg0) { - throw new UnsupportedOperationException("Deprecated Operation"); - -} - -/** Not supported */ -public int getTileCapacity() { - throw new UnsupportedOperationException("Deprecated Operation"); -} - -/** Not supported */ -public Comparator getTileComparator() { - throw new UnsupportedOperationException("Comparator not supported"); -} - -/** Not supported */ -public void setTileComparator(Comparator arg0) { - throw new UnsupportedOperationException("Comparator not supported"); -} - -/** Not supported */ -public void memoryControl() { - throw new UnsupportedOperationException("Memory Control not supported"); -} - -} diff --git a/concurrent-tile-cache/src/main/java/it/geosolutions/concurrentlinked/ConcurrentNonBlockingCache.java b/concurrent-tile-cache/src/main/java/it/geosolutions/concurrentlinked/ConcurrentNonBlockingCache.java deleted file mode 100644 index 97a3d705..00000000 --- a/concurrent-tile-cache/src/main/java/it/geosolutions/concurrentlinked/ConcurrentNonBlockingCache.java +++ /dev/null @@ -1,411 +0,0 @@ -package it.geosolutions.concurrentlinked; - -import it.geosolutions.concurrent.CachedTileImpl; -import it.geosolutions.concurrent.ConcurrentTileCache.Actions; - -import java.awt.Point; -import java.awt.image.Raster; -import java.awt.image.RenderedImage; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.Iterator; -import java.util.Observable; -import javax.media.jai.TileCache; -import org.cliffc.high_scale_lib.NonBlockingHashMap; -import com.sun.media.jai.util.CacheDiagnostics; - -public class ConcurrentNonBlockingCache extends Observable implements - TileCache, CacheDiagnostics { - -/** Default value for memory threshold */ -public static final float DEFAULT_MEMORY_THRESHOLD = 0.75F; - -/** Default value for cache memory */ -public static final long DEFAULT_MEMORY_CACHE = 16L * 1024L * 1024L; - -/** Default boolean for diagnostic mode */ -public static final boolean DEFAULT_DIAGNOSTIC = false; - -/** Cache memory capacity */ -private long memoryCacheCapacity = DEFAULT_MEMORY_CACHE; - -/** Cache memory threshold (typically 0.75F) */ -private float memoryCacheThreshold = DEFAULT_MEMORY_THRESHOLD; - -/** The real cache */ -private NonBlockingHashMap cacheObject = new NonBlockingHashMap(1000); - -/** - * Current diagnostic mode (enabled or not). This variable is set to volatile - * for visibility - */ -private volatile boolean diagnosticEnabled = DEFAULT_DIAGNOSTIC; - -/** Current number of cache miss */ -private int missNumber; - -/** Current number of cache hits */ -private int hitNumber; - -/* Simple constructor */ -public ConcurrentNonBlockingCache() { - this(DEFAULT_MEMORY_CACHE, DEFAULT_MEMORY_THRESHOLD, DEFAULT_DIAGNOSTIC); -} - -/* Parameterized constructor */ -public ConcurrentNonBlockingCache(long memoryCacheCapacity, - float memoryCacheThreshold, boolean diagnosticEnabled) { - this.memoryCacheCapacity = memoryCacheCapacity; - this.diagnosticEnabled = diagnosticEnabled; - this.memoryCacheThreshold = memoryCacheThreshold; - /* the counters are set to 0 */ - hitNumber = 0; - missNumber = 0; - System.err.println("Using ConcurrentNonBlockingCache"); -} - -public void add(RenderedImage image, int xTile, int yTile, Raster dataTile) { - this.add(image, xTile, yTile, dataTile, null); -} - -/** - * This method adds a new tile in cache and, if diagnostic is enabled, notify - * observers - */ -public void add(RenderedImage image, int xTile, int yTile, Raster dataTile, - Object tileMetric) { - /* Tile key calculation */ - Object key = CachedTileImpl.hashKey(image, xTile, yTile); - /* New tile creation */ - CachedTileImpl newValue = new CachedTileImpl(image, xTile, yTile, dataTile, - tileMetric); - /* If diagnostic is enabled the tile status is changed */ - if (diagnosticEnabled) { - synchronized (this) { - /* Updates the new tile status and notifies the observers */ - newValue.setAction(Actions.ADDITION); - setChanged(); - notifyObservers(newValue); - /* Puts the new value in cache and takes the old one */ - CachedTileImpl oldValue = cacheObject.put(key, newValue); - if (oldValue != null) { - hitNumber++; - /* Update the old tile status and notify the observers */ - oldValue.updateTileTimeStamp(); - oldValue.setAction(Actions.SUBSTITUTION_FROM_ADD); - setChanged(); - notifyObservers(oldValue); - return; - } - } - } else { - /* Simply put the value in cache */ - cacheObject.put(key, newValue); - } -} - -/** This method add an array of tiles at given positions */ -public void addTiles(RenderedImage image, Point[] positions, - Raster[] dataTiles, Object tileMetric) { - for (int i = 0; i < positions.length; i++) { - int xIndex = positions[i].x; - int yIndex = positions[i].y; - add(image, xIndex, yIndex, dataTiles[i], tileMetric); - } -} - -/** - * This method flushes the cache and, if diagnostic is enabled, reset the - * counters and, for every tile, update tile status - */ -public synchronized void flush() { - if (diagnosticEnabled) { - /* - * An iterator of all the key in the cache is used for updating every - * tile and the removing it - */ - CachedTileImpl oldValue; - Iterator iter = cacheObject.keySet().iterator(); - while (iter.hasNext()) { - oldValue = cacheObject.remove(iter.next()); - oldValue.setAction(Actions.REMOVAL_FROM_FLUSH); - oldValue.updateTileTimeStamp(); - setChanged(); - notifyObservers(oldValue); - } - /* Counter reset */ - hitNumber = 0; - missNumber = 0; - } else { - /* Simple cache clearing */ - cacheObject.clear(); - } -} - -/** This method gets the current cache memory capacity */ -public long getMemoryCapacity() { - return memoryCacheCapacity; -} - -/** This method gets the current cache memory threshold */ -public float getMemoryThreshold() { - return memoryCacheThreshold; -} - -/** - * This method gets a tile raster from his (x,y) tile coordinates and the image - * reference - */ -public Raster getTile(RenderedImage image, int xTile, int yTile) { - /* Key creation */ - Object key = CachedTileImpl.hashKey(image, xTile, yTile); - if (diagnosticEnabled) { - synchronized (this) { - /* - * In diagnostic mode the oldvalue, if present, is updated and - * retrieved - */ - CachedTileImpl oldValue = cacheObject.get(key); - if (oldValue != null) { - /* if the tile is present the hit number is increased */ - hitNumber++; - oldValue.setAction(Actions.UPDATING_TILE_FROM_GETTILE); - oldValue.updateTileTimeStamp(); - /* Observers notifications */ - setChanged(); - notifyObservers(oldValue); - return oldValue.getTile(); - } else { - /* if the tile is not present the miss number is increased */ - missNumber++; - return null; - } - } - } else { - /* The tile is returned if present, else null returned */ - CachedTileImpl oldValue = cacheObject.get(key); - if (oldValue != null) { - return oldValue.getTile(); - } else { - return null; - } - } -} - -/** All the tile of the specific image are returned */ -public Raster[] getTiles(RenderedImage image) { - // instantiation of the result array - Raster[] tilesData = null; - // total number of tiles present in the cache - int tileCount = (int) cacheObject.size(); - - int size = Math.min(image.getNumXTiles() * image.getNumYTiles(), tileCount); - - if (size > 0) { - int minTx = image.getMinTileX(); - int minTy = image.getMinTileY(); - int maxTx = minTx + image.getNumXTiles(); - int maxTy = minTy + image.getNumYTiles(); - - // creates a temporary data arrayList - ArrayList tempData = new ArrayList(); - // every not-null raster is added to the array - for (int y = minTy; y < maxTy; y++) { - for (int x = minTx; x < maxTx; x++) { - - Raster rasterTile = getTile(image, x, y); - - // the arrayList is then changed in an array - if (rasterTile != null) { - tempData.add(rasterTile); - } - } - } - - int tmpsize = tempData.size(); - if (tmpsize > 0) { - tilesData = (Raster[]) tempData.toArray(new Raster[tmpsize]); - } - } - - return tilesData; -} - -/** This method returns an array of tiles at the given positions */ -public Raster[] getTiles(RenderedImage image, Point[] positions) { - /* Initialization of an array of rasters */ - Raster[] tileData = new Raster[positions.length]; - if (diagnosticEnabled) { - synchronized (this) { - /* - * If the diagnostic mode is enabled, the tiles are returned from - * the method getTile which updates the tile status - */ - for (int j = 0; j < positions.length; j++) { - int xTile = positions[j].x; - int yTile = positions[j].y; - tileData[j] = getTile(image, xTile, yTile); - } - } - } else { - /* - * Else, they are simply returned by the NonBlockingHashMap.get() - * method - */ - for (int j = 0; j < positions.length; j++) { - int xTile = positions[j].x; - int yTile = positions[j].y; - Object key = CachedTileImpl.hashKey(image, xTile, yTile); - tileData[j] = cacheObject.get(key).getTile(); - } - } - return tileData; -} - -/** This method removes the specified tile and notify it to the observers */ -public void remove(RenderedImage image, int xTile, int yTile) { - /* Tile key calculation */ - Object key = CachedTileImpl.hashKey(image, xTile, yTile); - if (diagnosticEnabled) { - synchronized (this) { - /* - * In diagnostic mode this method check if the old tile was present - * and if so update its status and notify it to the observers, and - * removes it - */ - CachedTileImpl oldValue = cacheObject.get(key); - if (oldValue != null) { - oldValue.updateTileTimeStamp(); - oldValue.setAction(Actions.ABOUT_TO_REMOVAL); - setChanged(); - notifyObservers(oldValue); - cacheObject.remove(key); - oldValue.updateTileTimeStamp(); - oldValue.setAction(Actions.MANUAL_REMOVAL); - setChanged(); - notifyObservers(oldValue); - } - } - } else { - /* The tile is removed without checking if it is present or not */ - cacheObject.remove(key); - } -} - -/** This method removes all the tiles that belong to the specified image */ -public void removeTiles(RenderedImage image) { - /* Image tile coordinates */ - int minTx = image.getMinTileX(); - int minTy = image.getMinTileY(); - int maxTx = minTx + image.getNumXTiles(); - int maxTy = minTy + image.getNumYTiles(); - if (diagnosticEnabled) { - synchronized (this) { - /* - * This method is the same for both the diagnostic or non-diagnostic - * mode the difference is the sincronized block - */ - removeAllImageTiles(image, minTx, maxTx, minTy, maxTy); - } - } else { - removeAllImageTiles(image, minTx, maxTx, minTy, maxTy); - } -} - -/** This method cycles through the image eliminating all of its tiles */ -private void removeAllImageTiles(RenderedImage image, int minX, int maxX, - int minY, int maxY) { - for (int y = minY; y < maxY; y++) { - for (int x = minX; x < maxX; x++) { - remove(image, x, y); - } - } -} - -/** This method sets the memory capacity, then flush and rebuild the cache */ -public synchronized void setMemoryCapacity(long memoryCacheCapacity) { - if (memoryCacheCapacity < 0) { - throw new IllegalArgumentException("Memory capacity too small"); - } else { - this.memoryCacheCapacity = memoryCacheCapacity; - flush(); - } - -} - -/** This method sets the memory threshold, then flush and rebuild the cache */ -public synchronized void setMemoryThreshold(float memoryCacheThreshold) { - if (memoryCacheThreshold < 0 || memoryCacheThreshold > 1) { - throw new IllegalArgumentException( - "Memory threshold must be between 0 and 1"); - } else { - this.memoryCacheThreshold = memoryCacheThreshold; - flush(); - } - -} - -/** Diagnostic is disabled, then the cache is flushed and rebuilt */ -public synchronized void disableDiagnostics() { - this.diagnosticEnabled = false; - flush(); -} - -/** Diagnostic is enabled, then the cache is flushed and rebuilt */ -public synchronized void enableDiagnostics() { - this.diagnosticEnabled = true; - flush(); -} - -/** The counters are set to 0 when the cache is flushed */ -public synchronized void resetCounts() { - flush(); -} - -/** This method returns the number of cache hits */ -public long getCacheHitCount() { - return hitNumber; -} - -/** This method returns the cache weighed size */ -public long getCacheMemoryUsed() { - return -1; -} - -/** This method returns the number of cache miss */ -public long getCacheMissCount() { - return missNumber; -} - -/** This method returns the number of tile present in the cache */ -public long getCacheTileCount() { - return cacheObject.size(); -} - -/** Not supported */ -public void setTileCapacity(int arg0) { - throw new UnsupportedOperationException("Deprecated Operation"); - -} - -/** Not supported */ -public int getTileCapacity() { - throw new UnsupportedOperationException("Deprecated Operation"); -} - -/** Not supported */ -public Comparator getTileComparator() { - throw new UnsupportedOperationException("Comparator not supported"); -} - -/** Not supported */ -public void setTileComparator(Comparator arg0) { - throw new UnsupportedOperationException("Comparator not supported"); -} - -/** Not supported */ -public void memoryControl() { - throw new UnsupportedOperationException("Memory Control not supported"); -} - -} diff --git a/concurrent-tile-cache/src/test/java/it/geosolutions/concurrencytest/CacheCoberturaTest.java b/concurrent-tile-cache/src/test/java/it/geosolutions/concurrencytest/CacheCoberturaTest.java index e4ef232a..b2e232f2 100644 --- a/concurrent-tile-cache/src/test/java/it/geosolutions/concurrencytest/CacheCoberturaTest.java +++ b/concurrent-tile-cache/src/test/java/it/geosolutions/concurrencytest/CacheCoberturaTest.java @@ -15,7 +15,7 @@ public class CacheCoberturaTest { @Test public void testConcurrency() throws Exception { // setting the parameters - int cacheUsed=4; + int cacheUsed=1; int concurrencyLevel = 16; long memoryCacheCapacity = 128 * 1024 * 1024; RenderedImage imageSynth = ConcurrentCacheTest.getSynthetic(1); diff --git a/concurrent-tile-cache/src/test/java/it/geosolutions/concurrencytest/ConcurrentCacheTest.java b/concurrent-tile-cache/src/test/java/it/geosolutions/concurrencytest/ConcurrentCacheTest.java index 161e1445..54dbc662 100644 --- a/concurrent-tile-cache/src/test/java/it/geosolutions/concurrencytest/ConcurrentCacheTest.java +++ b/concurrent-tile-cache/src/test/java/it/geosolutions/concurrencytest/ConcurrentCacheTest.java @@ -1,9 +1,7 @@ package it.geosolutions.concurrencytest; import it.geosolutions.concurrent.ConcurrentTileCache; -import it.geosolutions.concurrentlinked.ConcurrentCache; -import it.geosolutions.concurrentlinked.ConcurrentLinkedCache; -import it.geosolutions.concurrentlinked.ConcurrentNonBlockingCache; + import java.awt.image.RenderedImage; import java.awt.image.renderable.ParameterBlock; import java.io.File; @@ -16,6 +14,7 @@ import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; + import javax.imageio.stream.FileImageInputStream; import javax.media.jai.InterpolationNearest; import javax.media.jai.JAI; @@ -133,29 +132,6 @@ public double[] testwriteImageAndWatchFlag(int cacheUsed, int concurrencyLevel, } JAI.getDefaultInstance().setTileCache(cTileCache); break; - case 2: - ConcurrentLinkedCache cLinkedCache = new ConcurrentLinkedCache(); - cLinkedCache.setConcurrencyLevel(concurrencyLevel); - if (diagnostics) { - cLinkedCache.enableDiagnostics(); - } - JAI.getDefaultInstance().setTileCache(cLinkedCache); - break; - case 3: - ConcurrentCache cCache = new ConcurrentCache(); - cCache.setConcurrencyLevel(concurrencyLevel); - if (diagnostics) { - cCache.enableDiagnostics(); - } - JAI.getDefaultInstance().setTileCache(cCache); - break; - case 4: - ConcurrentNonBlockingCache cNonBlockingCache = new ConcurrentNonBlockingCache(); - if (diagnostics) { - cNonBlockingCache.enableDiagnostics(); - } - JAI.getDefaultInstance().setTileCache(cNonBlockingCache); - break; } JAI.getDefaultInstance().getTileCache().setMemoryCapacity(memoryCacheCapacity); JAI.getDefaultInstance().getTileScheduler().setParallelism(10); @@ -436,18 +412,6 @@ public void run() { ConcurrentTileCache cTileCache = (ConcurrentTileCache) cache; memory = cTileCache.getCacheMemoryUsed(); break; - case 2: - ConcurrentLinkedCache cLinkedCache = (ConcurrentLinkedCache) cache; - memory = cLinkedCache.getCacheMemoryUsed(); - break; - case 3: - ConcurrentCache cCache = (ConcurrentCache) cache; - memory = cCache.getCacheMemoryUsed(); - break; - case 4: - ConcurrentNonBlockingCache cNonBlockingCache = (ConcurrentNonBlockingCache) cache; - memory = cNonBlockingCache.getCacheMemoryUsed(); - break; } LOGGER.log(Level.INFO, "Current Memory Used: " + memory / (1024) + " Kb"); diff --git a/concurrent-tile-cache/src/test/java/it/geosolutions/concurrencytest/ConcurrentMultiMapTest.java b/concurrent-tile-cache/src/test/java/it/geosolutions/concurrencytest/ConcurrentMultiMapTest.java new file mode 100644 index 00000000..cd39b3af --- /dev/null +++ b/concurrent-tile-cache/src/test/java/it/geosolutions/concurrencytest/ConcurrentMultiMapTest.java @@ -0,0 +1,155 @@ +package it.geosolutions.concurrencytest; + +import it.geosolutions.concurrent.ConcurrentTileCacheMultiMap; + +import java.awt.image.Raster; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.imageio.stream.FileImageInputStream; +import javax.imageio.stream.ImageInputStream; +import javax.media.jai.RenderedOp; + +import junit.framework.Assert; + +import org.geotools.TestData; +import org.junit.Test; + +import com.sun.media.jai.operator.ImageReadDescriptor; + +/** + * This test class is used for checking if the {@link ConcurrentTileCacheMultiMap} behaves correctly. + * + * @author Nicola Lagomarsini GeoSolutions S.A.S. + * + */ +public class ConcurrentMultiMapTest { + + /** Total number of requests to execute */ + private final static int TOTAL = 100; + + @Test + public void testAddAndGetTile() throws InterruptedException, FileNotFoundException, IOException { + // Input stream to use + ImageInputStream stream_in = null; + try { + stream_in = new FileImageInputStream(TestData.file(this, "world.tiff")); + // Input RenderedImage to use + final RenderedOp input = ImageReadDescriptor.create(stream_in, 0, false, false, false, + null, null, null, null, null); + + // Boolean used for checking if the conditions are passed + final AtomicBoolean passed = new AtomicBoolean(true); + // Cache creation + final ConcurrentTileCacheMultiMap cache = new ConcurrentTileCacheMultiMap(1000 * 1000, + false, 1f, 4); + // Selection of one tile from the image + Raster data = input.getTile(input.getMinTileX(), input.getMinTileY()); + // Setting the tile inside the cache + cache.add(input, input.getMinTileX(), input.getMinTileY(), data); + // Thread pool to use for doing concurrent access on the cache + ThreadPoolExecutor executor = new ThreadPoolExecutor(TOTAL, TOTAL, 60, TimeUnit.SECONDS, + new ArrayBlockingQueue(1000000)); + // Latch used for waiting all the threads to end their work + final CountDownLatch latch = new CountDownLatch(TOTAL); + // Cycle for launching various requests + int counter = TOTAL; + while (counter > 0) { + + executor.execute(new Runnable() { + + public void run() { + // Get the tile to use + Raster data = cache.getTile(input, input.getMinTileX(), input.getMinTileY()); + if (data == null) { + passed.getAndSet(false); + } + latch.countDown(); + + } + }); + // Counter update + counter--; + } + // Waiting all threads to finish + latch.await(); + // Ensure that all the threads have found the tile + Assert.assertTrue(passed.get()); + } finally { + try { + if (stream_in != null) { + stream_in.flush(); + stream_in.close(); + } + } catch (Throwable t) { + // + } + } + } + + @Test + public void testRemoveTile() throws InterruptedException, FileNotFoundException, IOException { + // Input stream to use + ImageInputStream stream_in = null; + try { + stream_in = new FileImageInputStream(TestData.file(this, "world.tiff")); + // Input RenderedImage to use + final RenderedOp input = ImageReadDescriptor.create(stream_in, 0, false, false, false, + null, null, null, null, null); + + // Boolean used for checking if the conditions are passed + final AtomicBoolean passed = new AtomicBoolean(true); + // Cache creation + final ConcurrentTileCacheMultiMap cache = new ConcurrentTileCacheMultiMap(1000 * 1000, + false, 1f, 4); + // Selection of one tile from the image + Raster data = input.getTile(input.getMinTileX(), input.getMinTileY()); + // Setting the tile inside the cache + cache.add(input, input.getMinTileX(), input.getMinTileY(), data); + // Removing tile + cache.remove(input, input.getMinTileX(), input.getMinTileY()); + // Thread pool to use for doing concurrent access on the cache + ThreadPoolExecutor executor = new ThreadPoolExecutor(TOTAL, TOTAL, 60, TimeUnit.SECONDS, + new ArrayBlockingQueue(1000000)); + // Latch used for waiting all the threads to end their work + final CountDownLatch latch = new CountDownLatch(TOTAL); + // Cycle for launching various requests + int counter = TOTAL; + while (counter > 0) { + + executor.execute(new Runnable() { + + public void run() { + // Get the tile to use + Raster data = cache.getTile(input, input.getMinTileX(), input.getMinTileY()); + if (data != null) { + passed.getAndSet(false); + } + latch.countDown(); + + } + }); + // Counter update + counter--; + } + // Waiting all threads to finish + latch.await(); + // Ensure that all the threads have found the tile + Assert.assertTrue(passed.get()); + } finally { + try { + if (stream_in != null) { + stream_in.flush(); + stream_in.close(); + } + } catch (Throwable t) { + // + } + } + } +} diff --git a/concurrent-tile-cache/src/test/resources/it/geosolutions/concurrencytest/test-data/world.tiff b/concurrent-tile-cache/src/test/resources/it/geosolutions/concurrencytest/test-data/world.tiff new file mode 100644 index 00000000..7ea9c6f7 Binary files /dev/null and b/concurrent-tile-cache/src/test/resources/it/geosolutions/concurrencytest/test-data/world.tiff differ diff --git a/jt-utilities/src/test/java/it/geosolutions/jaiext/range/RangeTest.java b/jt-utilities/src/test/java/it/geosolutions/jaiext/range/RangeTest.java index bb18a72c..e68e3c71 100644 --- a/jt-utilities/src/test/java/it/geosolutions/jaiext/range/RangeTest.java +++ b/jt-utilities/src/test/java/it/geosolutions/jaiext/range/RangeTest.java @@ -14,6 +14,8 @@ /** * This test-class is used for evaluating the functionalities of the {@link Range} class and its subclasses. Also this class is compared to other * Range classes for seeing if its contain() method could have a better performance than that of the other Range classes. + * + * Guava Ranges are commented in order to wait to upgrade the Guava version to 14.0.1 */ public class RangeTest { @@ -187,25 +189,25 @@ public class RangeTest { private static NumberRange rangeGeoToolsDpoint; - private static com.google.common.collect.Range rangeGuavaB; - - private static com.google.common.collect.Range rangeGuavaS; - - private static com.google.common.collect.Range rangeGuavaI; - - private static com.google.common.collect.Range rangeGuavaF; - - private static com.google.common.collect.Range rangeGuavaD; - - private static com.google.common.collect.Range rangeGuavaBpoint; - - private static com.google.common.collect.Range rangeGuavaSpoint; - - private static com.google.common.collect.Range rangeGuavaIpoint; - - private static com.google.common.collect.Range rangeGuavaFpoint; - - private static com.google.common.collect.Range rangeGuavaDpoint; +// private static com.google.common.collect.Range rangeGuavaB; +// +// private static com.google.common.collect.Range rangeGuavaS; +// +// private static com.google.common.collect.Range rangeGuavaI; +// +// private static com.google.common.collect.Range rangeGuavaF; +// +// private static com.google.common.collect.Range rangeGuavaD; +// +// private static com.google.common.collect.Range rangeGuavaBpoint; +// +// private static com.google.common.collect.Range rangeGuavaSpoint; +// +// private static com.google.common.collect.Range rangeGuavaIpoint; +// +// private static com.google.common.collect.Range rangeGuavaFpoint; +// +// private static com.google.common.collect.Range rangeGuavaDpoint; @BeforeClass public static void initialSetup() { @@ -305,18 +307,18 @@ public static void initialSetup() { rangeGeoToolsFpoint = new org.geotools.util.NumberRange(Float.class, 5f, 5f); rangeGeoToolsDpoint = new org.geotools.util.NumberRange(Double.class, 5d, 5d); - // Guava Ranges - rangeGuavaB = com.google.common.collect.Range.closed((byte) 1, (byte) 60); - rangeGuavaS = com.google.common.collect.Range.closed((short) 1, (short) 60); - rangeGuavaI = com.google.common.collect.Range.closed(1, 60); - rangeGuavaF = com.google.common.collect.Range.closed(0.5f, 60.5f); - rangeGuavaD = com.google.common.collect.Range.closed(1.5d, 60.5d); - // 1 point Ranges - rangeGuavaBpoint = com.google.common.collect.Range.singleton((byte) 5); - rangeGuavaSpoint = com.google.common.collect.Range.singleton((short) 5); - rangeGuavaIpoint = com.google.common.collect.Range.singleton(5); - rangeGuavaFpoint = com.google.common.collect.Range.singleton(5f); - rangeGuavaDpoint = com.google.common.collect.Range.singleton(5d); +// // Guava Ranges +// rangeGuavaB = com.google.common.collect.Range.closed((byte) 1, (byte) 60); +// rangeGuavaS = com.google.common.collect.Range.closed((short) 1, (short) 60); +// rangeGuavaI = com.google.common.collect.Range.closed(1, 60); +// rangeGuavaF = com.google.common.collect.Range.closed(0.5f, 60.5f); +// rangeGuavaD = com.google.common.collect.Range.closed(1.5d, 60.5d); +// // 1 point Ranges +// rangeGuavaBpoint = com.google.common.collect.Range.singleton((byte) 5); +// rangeGuavaSpoint = com.google.common.collect.Range.singleton((short) 5); +// rangeGuavaIpoint = com.google.common.collect.Range.singleton(5); +// rangeGuavaFpoint = com.google.common.collect.Range.singleton(5f); +// rangeGuavaDpoint = com.google.common.collect.Range.singleton(5d); } @Test @@ -612,51 +614,51 @@ public void testGeoToolsRangeTimeByte1or2Points() { } } - @Test - public void testGuavaRangeTimeByte1or2Points() { - - if (!SINGLE_POINT) { - switch(TEST_SELECTOR){ - case DataBuffer.TYPE_BYTE: - testGuavaRangeTime(rangeGuavaB, SINGLE_POINT,arrayBtest); - break; - case DataBuffer.TYPE_SHORT: - testGuavaRangeTime(rangeGuavaS, SINGLE_POINT,arrayStest); - break; - case DataBuffer.TYPE_INT: - testGuavaRangeTime(rangeGuavaI, SINGLE_POINT,arrayItest); - break; - case DataBuffer.TYPE_FLOAT: - testGuavaRangeTime(rangeGuavaF, SINGLE_POINT,arrayFtest); - break; - case DataBuffer.TYPE_DOUBLE: - testGuavaRangeTime(rangeGuavaD, SINGLE_POINT,arrayDtest); - break; - default: - throw new IllegalArgumentException("Wrong data type"); - } - } else { - switch(TEST_SELECTOR){ - case DataBuffer.TYPE_BYTE: - testGuavaRangeTime(rangeGuavaBpoint, SINGLE_POINT,arrayBtest); - break; - case DataBuffer.TYPE_SHORT: - testGuavaRangeTime(rangeGuavaSpoint, SINGLE_POINT,arrayStest); - break; - case DataBuffer.TYPE_INT: - testGuavaRangeTime(rangeGuavaIpoint, SINGLE_POINT,arrayItest); - break; - case DataBuffer.TYPE_FLOAT: - testGuavaRangeTime(rangeGuavaFpoint, SINGLE_POINT,arrayFtest); - break; - case DataBuffer.TYPE_DOUBLE: - testGuavaRangeTime(rangeGuavaDpoint, SINGLE_POINT,arrayDtest); - break; - default: - throw new IllegalArgumentException("Wrong data type"); - } - } - } +// @Test +// public void testGuavaRangeTimeByte1or2Points() { +// +// if (!SINGLE_POINT) { +// switch(TEST_SELECTOR){ +// case DataBuffer.TYPE_BYTE: +// testGuavaRangeTime(rangeGuavaB, SINGLE_POINT,arrayBtest); +// break; +// case DataBuffer.TYPE_SHORT: +// testGuavaRangeTime(rangeGuavaS, SINGLE_POINT,arrayStest); +// break; +// case DataBuffer.TYPE_INT: +// testGuavaRangeTime(rangeGuavaI, SINGLE_POINT,arrayItest); +// break; +// case DataBuffer.TYPE_FLOAT: +// testGuavaRangeTime(rangeGuavaF, SINGLE_POINT,arrayFtest); +// break; +// case DataBuffer.TYPE_DOUBLE: +// testGuavaRangeTime(rangeGuavaD, SINGLE_POINT,arrayDtest); +// break; +// default: +// throw new IllegalArgumentException("Wrong data type"); +// } +// } else { +// switch(TEST_SELECTOR){ +// case DataBuffer.TYPE_BYTE: +// testGuavaRangeTime(rangeGuavaBpoint, SINGLE_POINT,arrayBtest); +// break; +// case DataBuffer.TYPE_SHORT: +// testGuavaRangeTime(rangeGuavaSpoint, SINGLE_POINT,arrayStest); +// break; +// case DataBuffer.TYPE_INT: +// testGuavaRangeTime(rangeGuavaIpoint, SINGLE_POINT,arrayItest); +// break; +// case DataBuffer.TYPE_FLOAT: +// testGuavaRangeTime(rangeGuavaFpoint, SINGLE_POINT,arrayFtest); +// break; +// case DataBuffer.TYPE_DOUBLE: +// testGuavaRangeTime(rangeGuavaDpoint, SINGLE_POINT,arrayDtest); +// break; +// default: +// throw new IllegalArgumentException("Wrong data type"); +// } +// } +// } @@ -964,38 +966,38 @@ public >void testGeoToolsRangeTime(org.geotools + " nsec."); } - public >void testGuavaRangeTime(com.google.common.collect.Range testRange, - boolean isPoint, T[] array) { - int totalCycles = NOT_BENCHMARK_ITERATION + BENCHMARK_ITERATION; - // Initialization of the statistics - long mean = 0; - for (int i = 0; i < totalCycles; i++) { - // Total calculation time - long start = System.nanoTime(); - - for (int j = 0; j < array.length; j++) { - testRange.contains(array[j]); - } - long end = System.nanoTime() - start; - - // If the the first NOT_BENCHMARK_ITERATION cycles has been done, then the mean, maximum and minimum values are stored - if (i > NOT_BENCHMARK_ITERATION - 1) { - if (i == NOT_BENCHMARK_ITERATION) { - mean = end; - } else { - mean = mean + end; - } - } - } - String description = ""; - if (isPoint) { - description += " a single point"; - } - // Mean values - double meanValue = mean / BENCHMARK_ITERATION; - // Output print - System.out.println("\nMean value for" + description + " Guava Range : " + meanValue - + " nsec."); - } +// public >void testGuavaRangeTime(com.google.common.collect.Range testRange, +// boolean isPoint, T[] array) { +// int totalCycles = NOT_BENCHMARK_ITERATION + BENCHMARK_ITERATION; +// // Initialization of the statistics +// long mean = 0; +// for (int i = 0; i < totalCycles; i++) { +// // Total calculation time +// long start = System.nanoTime(); +// +// for (int j = 0; j < array.length; j++) { +// testRange.contains(array[j]); +// } +// long end = System.nanoTime() - start; +// +// // If the the first NOT_BENCHMARK_ITERATION cycles has been done, then the mean, maximum and minimum values are stored +// if (i > NOT_BENCHMARK_ITERATION - 1) { +// if (i == NOT_BENCHMARK_ITERATION) { +// mean = end; +// } else { +// mean = mean + end; +// } +// } +// } +// String description = ""; +// if (isPoint) { +// description += " a single point"; +// } +// // Mean values +// double meanValue = mean / BENCHMARK_ITERATION; +// // Output print +// System.out.println("\nMean value for" + description + " Guava Range : " + meanValue +// + " nsec."); +// } } diff --git a/pom.xml b/pom.xml index 7d36bdc2..c75da939 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ 10-SNAPSHOT true 256M - 14.0.1 + 11.0.1