cache added

This commit is contained in:
simon 2020-09-09 18:00:33 +03:00
parent 576e70a606
commit 2cd4e23463
3 changed files with 101 additions and 20 deletions

View file

@ -0,0 +1,77 @@
package net.osmand.plus.server;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import net.osmand.PlatformUtil;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.server.endpoints.TileEndpoint;
import org.apache.commons.logging.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.util.concurrent.ConcurrentLinkedQueue;
public class MetaTileFileSystemCache {
private static final Log LOG = PlatformUtil.getLog(TileEndpoint.class);
private static final Object TILES_FOLDER = "tiles";
private static final int MAX_IN_MEMORY_CACHE_SIZE = 4;
private static final int MAX_CACHE_SIZE = 4;
private final ConcurrentLinkedQueue<TileEndpoint.MetaTileCache> inMemoryCache = new ConcurrentLinkedQueue<>();
private final File externalCacheDir;
public boolean inMemoryCacheEnabled = false;
public MetaTileFileSystemCache(OsmandApplication application) {
externalCacheDir = new File(
application.getExternalCacheDir().getAbsoluteFile() + File.separator + TILES_FOLDER);
if (!externalCacheDir.exists()) {
externalCacheDir.mkdir();
}
}
public void put(TileEndpoint.MetaTileCache tile) {
while (inMemoryCache.size() > MAX_IN_MEMORY_CACHE_SIZE) {
inMemoryCache.poll();
}
while (externalCacheDir.listFiles().length > MAX_CACHE_SIZE) {
//remove outdated files
for (int i = 0; i < externalCacheDir.listFiles().length - MAX_CACHE_SIZE; i++) {
externalCacheDir.listFiles()[i].delete();
}
}
String fileName = tile.getTileId();
File file = new File(externalCacheDir, fileName);
if (file.exists()) {
file.delete();
}
try {
FileOutputStream out = new FileOutputStream(file);
tile.getBitmap().compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
if (inMemoryCacheEnabled) {
inMemoryCache.add(tile);
}
}
public TileEndpoint.MetaTileCache get(int zoom, int METATILE_SIZE, int x, int y) {
for (int tx = x - METATILE_SIZE + 1; tx < METATILE_SIZE + x - 1; tx++) {
for (int ty = y - METATILE_SIZE + 1; ty < METATILE_SIZE + y - 1; ty++) {
File file = new File(externalCacheDir, zoom + "_" + METATILE_SIZE + "_" + tx + "_" + ty);
if (file.exists()) {
TileEndpoint.MetaTileCache tile = new TileEndpoint.MetaTileCache(
BitmapFactory.decodeFile(file.getAbsolutePath()),
tx, ty, tx + METATILE_SIZE, ty + METATILE_SIZE, zoom
);
if (inMemoryCacheEnabled) {
inMemoryCache.add(tile);
}
return tile;
}
}
}
return null;
}
}

View file

@ -62,6 +62,7 @@ public class OsmAndHttpServer extends NanoHTTPD {
return e.getValue().process(session, uri);
} catch (Exception exception) {
LOG.error("SERVER ERROR: " + exception.getMessage());
return ErrorResponses.response500;
}
}
}

View file

@ -6,13 +6,13 @@ import net.osmand.PlatformUtil;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.resources.AsyncLoadingThread;
import net.osmand.plus.server.MetaTileFileSystemCache;
import net.osmand.plus.server.OsmAndHttpServer;
import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.concurrent.ConcurrentLinkedQueue;
import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse;
@ -22,14 +22,12 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint {
private static final int TIMEOUT_STEP = 500;
private static final int TIMEOUT = 5000;
private static final int METATILE_SIZE = 2;
private static final int MAX_CACHE_SIZE = 4;
private static final Log LOG = PlatformUtil.getLog(TileEndpoint.class);
private final MapActivity mapActivity;
// TODO store on file system
private final ConcurrentLinkedQueue<MetaTileCache> cache = new ConcurrentLinkedQueue<>();
private final MetaTileFileSystemCache cache;
private static class MetaTileCache {
public static class MetaTileCache {
Bitmap bmp;
int sx;
int sy;
@ -37,11 +35,28 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint {
int ey;
int zoom;
public MetaTileCache() {
}
public MetaTileCache(Bitmap bmp, int sx, int sy, int ex, int ey, int zoom) {
this.bmp = bmp;
this.sx = sx;
this.sy = sy;
this.ex = ex;
this.ey = ey;
this.zoom = zoom;
}
// to be used in file name
public String getTileId() {
return zoom + "_" + METATILE_SIZE + "_" + sx + "_" + sy;
}
public Bitmap getBitmap() {
return bmp;
}
public Bitmap getSubtile(int x, int y) {
return Bitmap.createBitmap(bmp,
(x - sx) * TILE_SIZE_PX * TILE_DENSITY,
@ -52,13 +67,7 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint {
public TileEndpoint(MapActivity mapActivity) {
this.mapActivity = mapActivity;
}
private void addToMemoryCache(MetaTileCache res) {
while (cache.size() > MAX_CACHE_SIZE) {
cache.poll();
}
cache.add(res);
this.cache = new MetaTileFileSystemCache(mapActivity.getMyApplication());
}
@Override
@ -78,13 +87,7 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint {
int zoom = Integer.parseInt(prms[1]);
int x = Integer.parseInt(prms[2]);
int y = Integer.parseInt(prms[3]);
MetaTileCache res = null;
for (MetaTileCache r : cache) {
if (r.zoom == zoom && r.ex >= x && r.ey >= y && r.sx <= x && r.sy <= y) {
res = r;
}
}
MetaTileCache res = cache.get(zoom, METATILE_SIZE, x, y);
if (res == null) {
res = requestMetatile(x, y, zoom);
if (res == null) {
@ -137,7 +140,7 @@ public class TileEndpoint implements OsmAndHttpServer.ApiEndpoint {
res.zoom = zoom;
Bitmap tempBmp = mapActivity.getMapView().getBufferBitmap();
res.bmp = tempBmp.copy(tempBmp.getConfig(), true);
addToMemoryCache(res);
cache.put(res);
}
return res;
} catch (InterruptedException e) {