Add MapTileLayerSize for cache size
This commit is contained in:
parent
a0e52f355f
commit
1e809d7915
2 changed files with 78 additions and 37 deletions
|
@ -7,7 +7,7 @@ import net.osmand.data.RotatedTileBox;
|
||||||
import net.osmand.map.ITileSource;
|
import net.osmand.map.ITileSource;
|
||||||
import net.osmand.map.MapTileDownloader.DownloadRequest;
|
import net.osmand.map.MapTileDownloader.DownloadRequest;
|
||||||
import net.osmand.plus.SQLiteTileSource;
|
import net.osmand.plus.SQLiteTileSource;
|
||||||
import net.osmand.plus.views.MapTileLayer;
|
import net.osmand.plus.resources.ResourceManager.MapTileLayerSize;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
@ -16,19 +16,18 @@ import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread to load map objects (POI, transport stops )async
|
* Thread to load map objects (POI, transport stops )async
|
||||||
*/
|
*/
|
||||||
public class AsyncLoadingThread extends Thread {
|
public class AsyncLoadingThread extends Thread {
|
||||||
|
|
||||||
public static final int LIMIT_TRANSPORT = 200;
|
private static final int CACHE_LAYER_SIZE_EXPIRE_TIME_MS = 30 * 1000;
|
||||||
|
|
||||||
private static final Log log = PlatformUtil.getLog(AsyncLoadingThread.class);
|
private static final Log log = PlatformUtil.getLog(AsyncLoadingThread.class);
|
||||||
|
|
||||||
Stack<Object> requests = new Stack<Object>();
|
private final Stack<Object> requests = new Stack<Object>();
|
||||||
private final ResourceManager resourceManger;
|
private final ResourceManager resourceManger;
|
||||||
|
|
||||||
public AsyncLoadingThread(ResourceManager resourceManger) {
|
public AsyncLoadingThread(ResourceManager resourceManger) {
|
||||||
|
@ -65,7 +64,7 @@ public class AsyncLoadingThread extends Thread {
|
||||||
updateBitmapTilesCache();
|
updateBitmapTilesCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tileLoaded || mapLoaded) {
|
if (tileLoaded || mapLoaded) {
|
||||||
// use downloader callback
|
// use downloader callback
|
||||||
resourceManger.getMapTileDownloader().fireLoadCallback(null);
|
resourceManger.getMapTileDownloader().fireLoadCallback(null);
|
||||||
}
|
}
|
||||||
|
@ -78,21 +77,6 @@ public class AsyncLoadingThread extends Thread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateBitmapTilesCache() {
|
|
||||||
int maxCacheSize = 0;
|
|
||||||
for (Entry<MapTileLayer, Integer> entry : resourceManger.getMapTileLayerSizes().entrySet()) {
|
|
||||||
MapTileLayer layer = entry.getKey();
|
|
||||||
if (layer.isVisible()) {
|
|
||||||
maxCacheSize += entry.getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BitmapTilesCache bitmapTilesCache = resourceManger.getBitmapTilesCache();
|
|
||||||
if (maxCacheSize > 0 && maxCacheSize * 1.2 < bitmapTilesCache.getMaxCacheSize()) {
|
|
||||||
log.info("Bitmap tiles to load in memory : " + maxCacheSize);
|
|
||||||
bitmapTilesCache.setMaxCacheSize(maxCacheSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void requestToLoadTile(TileLoadDownloadRequest req) {
|
public void requestToLoadTile(TileLoadDownloadRequest req) {
|
||||||
requests.push(req);
|
requests.push(req);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +85,6 @@ public class AsyncLoadingThread extends Thread {
|
||||||
requests.push(req);
|
requests.push(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isFilePendingToDownload(File fileToSave) {
|
public boolean isFilePendingToDownload(File fileToSave) {
|
||||||
return resourceManger.getMapTileDownloader().isFilePendingToDownload(fileToSave);
|
return resourceManger.getMapTileDownloader().isFilePendingToDownload(fileToSave);
|
||||||
}
|
}
|
||||||
|
@ -114,6 +97,29 @@ public class AsyncLoadingThread extends Thread {
|
||||||
resourceManger.getMapTileDownloader().requestToDownload(req);
|
resourceManger.getMapTileDownloader().requestToDownload(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateBitmapTilesCache() {
|
||||||
|
int maxCacheSize = 0;
|
||||||
|
long currentTime = System.currentTimeMillis();
|
||||||
|
for (MapTileLayerSize layerSize : resourceManger.getMapTileLayerSizes()) {
|
||||||
|
if (layerSize.markToGCTimestamp != null && currentTime - layerSize.markToGCTimestamp > CACHE_LAYER_SIZE_EXPIRE_TIME_MS) {
|
||||||
|
resourceManger.removeMapTileLayerSize(layerSize.layer);
|
||||||
|
} else if (currentTime - layerSize.activeTimestamp > CACHE_LAYER_SIZE_EXPIRE_TIME_MS) {
|
||||||
|
layerSize.markToGCTimestamp = currentTime + CACHE_LAYER_SIZE_EXPIRE_TIME_MS;
|
||||||
|
} else if (layerSize.markToGCTimestamp == null) {
|
||||||
|
maxCacheSize += layerSize.tiles;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BitmapTilesCache bitmapTilesCache = resourceManger.getBitmapTilesCache();
|
||||||
|
int oldCacheSize = bitmapTilesCache.getMaxCacheSize();
|
||||||
|
if (maxCacheSize != 0 && maxCacheSize * 1.2 < oldCacheSize || maxCacheSize > oldCacheSize) {
|
||||||
|
if (maxCacheSize / 2.5 > oldCacheSize) {
|
||||||
|
bitmapTilesCache.clearTiles();
|
||||||
|
}
|
||||||
|
log.info("Bitmap tiles to load in memory : " + maxCacheSize);
|
||||||
|
bitmapTilesCache.setMaxCacheSize(maxCacheSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class TileLoadDownloadRequest extends DownloadRequest {
|
public static class TileLoadDownloadRequest extends DownloadRequest {
|
||||||
|
|
||||||
public final String tileId;
|
public final String tileId;
|
||||||
|
@ -139,7 +145,7 @@ public class AsyncLoadingThread extends Thread {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveTile(InputStream inputStream) throws IOException {
|
public void saveTile(InputStream inputStream) throws IOException {
|
||||||
if(tileSource instanceof SQLiteTileSource){
|
if (tileSource instanceof SQLiteTileSource) {
|
||||||
ByteArrayOutputStream stream = null;
|
ByteArrayOutputStream stream = null;
|
||||||
try {
|
try {
|
||||||
stream = new ByteArrayOutputStream(inputStream.available());
|
stream = new ByteArrayOutputStream(inputStream.available());
|
||||||
|
@ -149,14 +155,13 @@ public class AsyncLoadingThread extends Thread {
|
||||||
try {
|
try {
|
||||||
((SQLiteTileSource) tileSource).insertImage(xTile, yTile, zoom, stream.toByteArray());
|
((SQLiteTileSource) tileSource).insertImage(xTile, yTile, zoom, stream.toByteArray());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.warn("Tile x="+xTile +" y="+ yTile+" z="+ zoom+" couldn't be read", e); //$NON-NLS-1$//$NON-NLS-2$
|
log.warn("Tile x=" + xTile + " y=" + yTile + " z=" + zoom + " couldn't be read", e); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
Algorithms.closeStream(inputStream);
|
Algorithms.closeStream(inputStream);
|
||||||
Algorithms.closeStream(stream);
|
Algorithms.closeStream(stream);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
super.saveTile(inputStream);
|
super.saveTile(inputStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,6 +229,4 @@ public class AsyncLoadingThread extends Thread {
|
||||||
this.mapLoadedListener = mapLoadedListener;
|
this.mapLoadedListener = mapLoadedListener;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -100,7 +100,7 @@ public class ResourceManager {
|
||||||
private List<TilesCache> tilesCacheList = new ArrayList<>();
|
private List<TilesCache> tilesCacheList = new ArrayList<>();
|
||||||
private BitmapTilesCache bitmapTilesCache;
|
private BitmapTilesCache bitmapTilesCache;
|
||||||
private GeometryTilesCache geometryTilesCache;
|
private GeometryTilesCache geometryTilesCache;
|
||||||
private Map<MapTileLayer, Integer> mapTileLayerSizes = new ConcurrentHashMap<>();
|
private List<MapTileLayerSize> mapTileLayerSizes = new ArrayList<>();
|
||||||
|
|
||||||
private final OsmandApplication context;
|
private final OsmandApplication context;
|
||||||
private List<ResourceListener> resourceListeners = new ArrayList<>();
|
private List<ResourceListener> resourceListeners = new ArrayList<>();
|
||||||
|
@ -121,7 +121,20 @@ public class ResourceManager {
|
||||||
ROUTING,
|
ROUTING,
|
||||||
TRANSPORT_ROUTING
|
TRANSPORT_ROUTING
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class MapTileLayerSize {
|
||||||
|
final MapTileLayer layer;
|
||||||
|
Long markToGCTimestamp = null;
|
||||||
|
long activeTimestamp;
|
||||||
|
int tiles;
|
||||||
|
|
||||||
|
public MapTileLayerSize(MapTileLayer layer, int tiles, long activeTimestamp) {
|
||||||
|
this.layer = layer;
|
||||||
|
this.tiles = tiles;
|
||||||
|
this.activeTimestamp = activeTimestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class BinaryMapReaderResource {
|
public static class BinaryMapReaderResource {
|
||||||
private BinaryMapIndexReader initialReader;
|
private BinaryMapIndexReader initialReader;
|
||||||
private File filename;
|
private File filename;
|
||||||
|
@ -288,16 +301,41 @@ public class ResourceManager {
|
||||||
resourceListeners.remove(listener);
|
resourceListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<MapTileLayer, Integer> getMapTileLayerSizes() {
|
public List<MapTileLayerSize> getMapTileLayerSizes() {
|
||||||
return mapTileLayerSizes;
|
return mapTileLayerSizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMapTileLayerSizes(MapTileLayer layer, int tiles) {
|
public void setMapTileLayerSizes(MapTileLayer layer, int tiles) {
|
||||||
mapTileLayerSizes.put(layer, tiles);
|
MapTileLayerSize layerSize = getMapTileLayerSize(layer);
|
||||||
|
if (layerSize != null) {
|
||||||
|
if (layerSize.markToGCTimestamp != null) {
|
||||||
|
layerSize.markToGCTimestamp = null;
|
||||||
|
layerSize.activeTimestamp = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
layerSize.tiles = tiles;
|
||||||
|
} else {
|
||||||
|
List<MapTileLayerSize> layerSizes = new ArrayList<>(mapTileLayerSizes);
|
||||||
|
layerSizes.add(new MapTileLayerSize(layer, tiles, System.currentTimeMillis()));
|
||||||
|
mapTileLayerSizes = layerSizes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeMapTileLayerSize(MapTileLayer layer) {
|
public void removeMapTileLayerSize(MapTileLayer layer) {
|
||||||
mapTileLayerSizes.remove(layer);
|
MapTileLayerSize layerSize = getMapTileLayerSize(layer);
|
||||||
|
if (layerSize != null) {
|
||||||
|
List<MapTileLayerSize> layerSizes = new ArrayList<>(mapTileLayerSizes);
|
||||||
|
layerSizes.remove(layerSize);
|
||||||
|
mapTileLayerSizes = layerSizes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MapTileLayerSize getMapTileLayerSize(MapTileLayer layer) {
|
||||||
|
for (MapTileLayerSize layerSize : mapTileLayerSizes) {
|
||||||
|
if (layerSize.layer == layer) {
|
||||||
|
return layerSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetStoreDirectory() {
|
public void resetStoreDirectory() {
|
||||||
|
|
Loading…
Reference in a new issue