/*******************************************************************************
* Copyright (c) 2014 Open Door Logistics (www.opendoorlogistics.com)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser Public License 3.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl.html
*
******************************************************************************/
package com.opendoorlogistics.core.cache;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import com.opendoorlogistics.api.cache.ObjectCachePool;
import com.opendoorlogistics.api.ui.Disposable;
import com.opendoorlogistics.core.utils.Pair;
/**
* A class to store all other caches! Note that cache retrieval by string
* is not standardised - e.g. lower case strings will be treated differently
* to upper case strings etc. This is because cache retrieval needs to be fast
* @author Phil
*
*/
public class ApplicationCache implements Disposable, ObjectCachePool{
private static final ApplicationCache singleton = new ApplicationCache();
private final HashMap<String, RecentlyUsedCache> caches = new HashMap<>();
public static final String DISTANCE_MATRIX_CACHE = "distance-matrix-cache";
public static final String ROUTE_GEOMETRY_CACHE = "route-geometry-cache";
public static final String GEOMETRY_MERGER_CACHE = "geometry-merge-cache";
public static final String GEOMETRY_BORDER_CACHE = "geometry-border-cache";
public static final String A_TO_B_DISTANCE_METRES_CACHE = "a-to-b-distance-metres-cache";
public static final String A_TO_B_TIME_SECONDS_CACHE = "a-to-b-time-seconds-cache";
public static final String IMPORTED_SHAPEFILE_CACHE = "imported-shapefile-cache";
public static final String GEOM_CENTROID_CACHE = "geom-centroid-cache";
public static final String PROJECTED_RENDERER_GEOMETRY = "projected-renderer-geometry";
public static final String ROG_QUADTREE_BLOCKS = "render-optimised-geometry-quadtree-blocks";
public static final String ROG_FULL_GEOMETRY = "render-optimised-geometry-full-geometry";
public static final String MAPSFORGE_BACKGROUND_TILES = "mapsforge-background-tiles";
public static final String TEXT_LAYOUT_CACHE = "text-layout-cache";
public static final String SYNCHRONOUS_RETRIEVED_TILE_CACHE = "synchronous-retrieved-tile-cache";
public static final String LOOKUP_NEAREST_TRANSFORMED_GEOMS = "lookup-nearest-transformed-geoms";
public static final String IMAGE_FORMULAE_CACHE = "image-formulae-cache";
public static final String IMAGE_WITH_VIEW_FORMULAE_CACHE = "image-with-view-formulae-cache";
public static final String PROJECTABLE_GEOMETRY_CONTAINS_CACHE = "projectable-geometry-contains-cache";
public static final String PROJECTED_GEOMETRY_CONTAINS_CACHE = "projected-geometry-contains-cache";
public static final String GRID_TRANSFORMS_CACHE = "grid-transforms-cache";
public static final String FAST_CONTAINED_POINTS_QUADTREE= "fast-contained-points-quadtree";
public static final String FUNCTION_IMPORTED_DATASTORES= "function-imported-datastores";
public void clearCache(){
for(RecentlyUsedCache cache : caches.values()){
cache.clear();
}
}
public static ApplicationCache singleton(){
return singleton;
}
private ApplicationCache(){
long MB = 1024*1024;
create(DISTANCE_MATRIX_CACHE, 128 * MB);
create(ROUTE_GEOMETRY_CACHE, 64 *MB);
create(GEOMETRY_MERGER_CACHE, 32* MB);
create(GEOMETRY_BORDER_CACHE, 32* MB);
create(A_TO_B_DISTANCE_METRES_CACHE, 12*MB);
create(A_TO_B_TIME_SECONDS_CACHE, 12*MB);
create(IMPORTED_SHAPEFILE_CACHE, 128*MB);
create(GEOM_CENTROID_CACHE, 16 * MB);
create(PROJECTED_RENDERER_GEOMETRY, 256 * MB);
create(ROG_QUADTREE_BLOCKS, 128 * MB);
create(ROG_FULL_GEOMETRY, 64 * MB);
create(MAPSFORGE_BACKGROUND_TILES, 64 * MB);
create(TEXT_LAYOUT_CACHE, 32 * MB);
create(SYNCHRONOUS_RETRIEVED_TILE_CACHE, 32 * MB);
create(LOOKUP_NEAREST_TRANSFORMED_GEOMS, 256 * MB);
create(IMAGE_FORMULAE_CACHE, 64 * MB);
create(IMAGE_WITH_VIEW_FORMULAE_CACHE, 64 * MB);
create(PROJECTABLE_GEOMETRY_CONTAINS_CACHE, 64 * MB);
create(PROJECTED_GEOMETRY_CONTAINS_CACHE, 64 * MB);
create(GRID_TRANSFORMS_CACHE, 6 * MB);
create(FAST_CONTAINED_POINTS_QUADTREE, 64 * MB);
create(FUNCTION_IMPORTED_DATASTORES, 512 * MB);
}
@Override
public RecentlyUsedCache get(String cacheId){
return caches.get(cacheId);
}
@Override
public RecentlyUsedCache create(String cacheId, long maxSizeInBytes){
if(get(cacheId)!=null){
throw new RuntimeException("Cache already exists with id: " + cacheId);
}
RecentlyUsedCache ret = new RecentlyUsedCache(cacheId,maxSizeInBytes);
caches.put(cacheId,ret );
return ret;
}
public String getUsageReport(){
StringBuilder builder = new StringBuilder();
long total=0;
ArrayList<Pair<Long, String>> list = new ArrayList<Pair<Long,String>>();
for(Map.Entry<String,RecentlyUsedCache> entry : caches.entrySet()){
long bytes = entry.getValue().getEstimatedTotalBytes();
list.add(new Pair<Long, String>(bytes, entry.getKey()));
total += bytes;
}
Collections.sort(list, new Comparator<Pair<Long, String>>() {
@Override
public int compare(Pair<Long, String> o1, Pair<Long, String> o2) {
int diff = o2.getFirst().compareTo(o1.getFirst());
if(diff==0){
diff = o1.getSecond().compareTo(o2.getSecond());
}
return diff;
}
});
class ToMbString{
String toMB(long bytes){
double val =(double) bytes / (1024*1024);
DecimalFormat df = new DecimalFormat("0.00");
return df.format(val);
}
}
ToMbString toMB = new ToMbString();
builder.append("Estimated total usage is " + toMB.toMB(total) + " MB" + System.lineSeparator());
for(Pair<Long, String> pair : list){
builder.append(pair.getSecond() + " estimated " + toMB.toMB(pair.getFirst()) + " MB" + System.lineSeparator());
}
return builder.toString();
}
@Override
public void dispose() {
}
}