-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
642 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
pl.edu.agh.cast.map/src/main/java/pl/edu/agh/cast/map/cache/IMapCache.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package pl.edu.agh.cast.map.cache; | ||
|
||
import org.eclipse.swt.graphics.ImageData; | ||
|
||
import pl.edu.agh.cast.common.IDisposable; | ||
|
||
/** | ||
* Map cache is one of the elements in map tile sources chain. Map cache has been distinguished from | ||
* {@link pl.edu.agh.cast.map.editor.provider.IMapProvider} due to the fact that cache is operating on already loaded tiles (In fact | ||
* definition of 'already loaded tiles' can vary in different {@link IMapCache} implementation) to enhance performance of obtaining tiles | ||
* greatly. | ||
* | ||
*/ | ||
public interface IMapCache extends IDisposable { | ||
|
||
/** | ||
* Return tile described by 3 parameters - map's zoom level, tile's column number and tile's row number.<br/> | ||
* Tiles can be requested synchronously in UI Thread or asynchronously from other thread, so <b>synchronization if needed should be | ||
* considered</b>. | ||
* | ||
* @param zoom | ||
* Map's zoom level. | ||
* @param column | ||
* Tile's column number. | ||
* @param row | ||
* Tile's row number. | ||
* | ||
* @return Image of requested tile or <code>null</code> otherwise. | ||
*/ | ||
ImageData getTile(int zoom, int column, int row); | ||
|
||
/** | ||
* Saves tile (described by 3 parameters - map's zoom level, tile's column number and tile's row number) in cache. Tiles can be provided | ||
* synchronously in UI Thread or asynchronously from other thread, so <b>synchronization if needed should be considered</b>. | ||
* | ||
* @param zoom | ||
* Map's zoom level. | ||
* @param column | ||
* Tile's column number. | ||
* @param row | ||
* Tile's row number. | ||
* @param tile | ||
* Image of tile. | ||
*/ | ||
void saveTile(int zoom, int column, int row, ImageData tile); | ||
|
||
} |
161 changes: 161 additions & 0 deletions
161
pl.edu.agh.cast.map/src/main/java/pl/edu/agh/cast/map/cache/MemoryMapCache.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
package pl.edu.agh.cast.map.cache; | ||
|
||
import java.util.Collections; | ||
import java.util.Iterator; | ||
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
|
||
import org.apache.log4j.Logger; | ||
import org.eclipse.swt.graphics.ImageData; | ||
|
||
import pl.edu.agh.cast.map.config.IMapConfigurationProvider; | ||
|
||
/** | ||
* Caches map's tiles in memory. | ||
* | ||
*/ | ||
public class MemoryMapCache implements IMapCache { | ||
|
||
/** | ||
* Logger. | ||
*/ | ||
private static Logger log = Logger.getLogger(MemoryMapCache.class); | ||
|
||
/** | ||
* Limit of operational memory (In megabytes). | ||
*/ | ||
private int memoryLimit; | ||
|
||
/** | ||
* Size of allocated memory (in bytes). | ||
*/ | ||
private long allocatedMemory; | ||
|
||
/** | ||
* Map of cached tiles. | ||
*/ | ||
private Map<String, ImageData> cachedTiles = Collections | ||
.synchronizedMap(new LinkedHashMap<String, ImageData>()); | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param memoryLimit | ||
* Limit of memory that can be used for tiles storing (in | ||
* megabytes). | ||
*/ | ||
public MemoryMapCache(int memoryLimit) { | ||
this.memoryLimit = memoryLimit; | ||
allocatedMemory = 0; | ||
} | ||
|
||
// BEGIN API Methods | ||
|
||
/** | ||
* Creates instance of {@link MemoryMapCache}. Appropriate memory cache's | ||
* configuration is obtained from given {@link IMapConfigurationProvider}. | ||
* If memory cache is disabled in application's setting than | ||
* <code>null</code> will be returned. | ||
* | ||
* @return Instance of {@link MemoryMapCache} or <code>null</code> is memory | ||
* cache is disabled | ||
*/ | ||
public static MemoryMapCache createMemoryMapCache( | ||
IMapConfigurationProvider config) { | ||
MemoryMapCache result = null; | ||
|
||
if (config.memoryCacheEnabled()) { | ||
result = new MemoryMapCache(config.memoryCacheLimit()); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
* | ||
* @see pl.edu.agh.cast.map.editor.cache.IMapCache#getTile(int, int, int) | ||
*/ | ||
@Override | ||
public ImageData getTile(int zoom, int column, int row) { | ||
return cachedTiles.get(getKey(zoom, column, row)); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
* | ||
* @see pl.edu.agh.cast.map.editor.cache.IMapCache#saveTile(int, int, int, | ||
* org.eclipse.swt.graphics.ImageData) | ||
*/ | ||
@Override | ||
public void saveTile(int zoom, int column, int row, ImageData tile) { | ||
String key = getKey(zoom, column, row); | ||
ImageData old = cachedTiles.put(key, tile); | ||
if (old != null) { | ||
if (log.isDebugEnabled()) { | ||
log.debug(String.format( | ||
"Tile under key %s has been overriden.", key)); //$NON-NLS-1$ | ||
} | ||
} | ||
|
||
long newSize = sizeOfImage(tile); | ||
long oldSize = sizeOfImage(old); | ||
allocatedMemory += newSize - oldSize; | ||
|
||
while ((allocatedMemory / 1048576.0) > memoryLimit) { | ||
synchronized (cachedTiles) { | ||
Iterator<String> iterator = cachedTiles.keySet().iterator(); | ||
if (iterator.hasNext()) { | ||
allocatedMemory -= sizeOfImage(cachedTiles.get(iterator | ||
.next())); | ||
iterator.remove(); | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
* | ||
* @see pl.edu.agh.cast.common.IDisposable#dispose() | ||
*/ | ||
@Override | ||
public void dispose() { | ||
cachedTiles.clear(); | ||
allocatedMemory = 0; | ||
} | ||
|
||
// END API Methods | ||
|
||
/** | ||
* Returns key for specified attributes. | ||
* | ||
* @param zoom | ||
* Tile zoom level. | ||
* @param column | ||
* Tile column. | ||
* @param row | ||
* Tile row. | ||
* @return Key for specified attributes. | ||
*/ | ||
private String getKey(int zoom, int column, int row) { | ||
String separator = "/"; //$NON-NLS-1$ | ||
return zoom + separator + column + separator + row; | ||
} | ||
|
||
/** | ||
* Returns size of image in memory. | ||
* | ||
* @param image | ||
* Image to investigate. | ||
* @return Size of image in memory. | ||
*/ | ||
private long sizeOfImage(ImageData image) { | ||
if (image == null) { | ||
return 0; | ||
} | ||
|
||
return image.width * image.height * (image.depth / 8); | ||
} | ||
|
||
} |
21 changes: 21 additions & 0 deletions
21
pl.edu.agh.cast.map/src/main/java/pl/edu/agh/cast/map/config/IMapConfigurationProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package pl.edu.agh.cast.map.config; | ||
|
||
import java.util.List; | ||
|
||
import pl.edu.agh.cast.map.provider.IMapProvider; | ||
|
||
public interface IMapConfigurationProvider { | ||
|
||
boolean discCacheEnabled(); | ||
|
||
boolean discCacheLimitEnabled(); | ||
|
||
int discCacheLimit(); | ||
|
||
boolean memoryCacheEnabled(); | ||
|
||
int memoryCacheLimit(); | ||
|
||
List<IMapProvider> mapProviders(); | ||
|
||
} |
37 changes: 37 additions & 0 deletions
37
pl.edu.agh.cast.map/src/main/java/pl/edu/agh/cast/map/config/IMapConfigurator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package pl.edu.agh.cast.map.config; | ||
|
||
import pl.edu.agh.cast.map.provider.IMapProvider; | ||
|
||
public interface IMapConfigurator extends IMapConfigurationProvider { | ||
|
||
// Disc cache | ||
|
||
void enableDiscCache(boolean enabled); | ||
|
||
void enableDiscCacheLimit(boolean enabled); | ||
|
||
/** | ||
* | ||
* @param limit | ||
* in MB | ||
*/ | ||
void setDiscCacheLimit(int limit); | ||
|
||
// Memory cache | ||
|
||
void enableMemoryCache(boolean enabled); | ||
|
||
/** | ||
* | ||
* @param limit | ||
* in MB | ||
*/ | ||
void setMemoryCacheLimit(int limit); | ||
|
||
// Map providers | ||
|
||
void addMapProvider(IMapProvider mapProvider); | ||
|
||
void removeMapProvider(IMapProvider mapProvider); | ||
|
||
} |
Oops, something went wrong.