Reduce memory map consumption
This commit is contained in:
parent
f13883216c
commit
e8df7a420e
5 changed files with 75 additions and 38 deletions
|
@ -49,12 +49,20 @@ public class BinaryMapIndexReader {
|
|||
private final BinaryMapAddressReaderAdapter addressAdapter;
|
||||
|
||||
public BinaryMapIndexReader(final RandomAccessFile raf) throws IOException {
|
||||
this(raf, false);
|
||||
}
|
||||
|
||||
public BinaryMapIndexReader(final RandomAccessFile raf, boolean readOnlyMapData) throws IOException {
|
||||
this.raf = raf;
|
||||
codedIS = CodedInputStreamRAF.newInstance(raf, 1024);
|
||||
codedIS.setSizeLimit(Integer.MAX_VALUE); // 2048 MB
|
||||
|
||||
transportAdapter = new BinaryMapTransportReaderAdapter(this);
|
||||
addressAdapter = new BinaryMapAddressReaderAdapter(this);
|
||||
if(!readOnlyMapData){
|
||||
transportAdapter = new BinaryMapTransportReaderAdapter(this);
|
||||
addressAdapter = new BinaryMapAddressReaderAdapter(this);
|
||||
} else {
|
||||
transportAdapter = null;
|
||||
addressAdapter = null;
|
||||
}
|
||||
init();
|
||||
}
|
||||
|
||||
|
@ -84,28 +92,33 @@ public class BinaryMapIndexReader {
|
|||
indexes.add(mapIndex);
|
||||
break;
|
||||
case OsmandOdb.OsmAndStructure.ADDRESSINDEX_FIELD_NUMBER:
|
||||
|
||||
AddressRegion region = new AddressRegion();
|
||||
region.length = readInt();
|
||||
region.filePointer = codedIS.getTotalBytesRead();
|
||||
oldLimit = codedIS.pushLimit(region.length);
|
||||
addressAdapter.readAddressIndex(region);
|
||||
codedIS.popLimit(oldLimit);
|
||||
codedIS.seek(region.filePointer + region.length);
|
||||
if(region.name != null){
|
||||
addressIndexes.add(region);
|
||||
indexes.add(region);
|
||||
if(addressAdapter != null){
|
||||
oldLimit = codedIS.pushLimit(region.length);
|
||||
addressAdapter.readAddressIndex(region);
|
||||
if(region.name != null){
|
||||
addressIndexes.add(region);
|
||||
indexes.add(region);
|
||||
}
|
||||
codedIS.popLimit(oldLimit);
|
||||
}
|
||||
codedIS.seek(region.filePointer + region.length);
|
||||
break;
|
||||
case OsmandOdb.OsmAndStructure.TRANSPORTINDEX_FIELD_NUMBER:
|
||||
TransportIndex ind = new TransportIndex();
|
||||
ind.length = readInt();
|
||||
ind.filePointer = codedIS.getTotalBytesRead();
|
||||
oldLimit = codedIS.pushLimit(ind.length);
|
||||
transportAdapter.readTransportIndex(ind);
|
||||
codedIS.popLimit(oldLimit);
|
||||
if (transportAdapter != null) {
|
||||
oldLimit = codedIS.pushLimit(ind.length);
|
||||
transportAdapter.readTransportIndex(ind);
|
||||
codedIS.popLimit(oldLimit);
|
||||
transportIndexes.add(ind);
|
||||
indexes.add(ind);
|
||||
}
|
||||
codedIS.seek(ind.filePointer + ind.length);
|
||||
transportIndexes.add(ind);
|
||||
indexes.add(ind);
|
||||
break;
|
||||
case OsmandOdb.OsmAndStructure.VERSIONCONFIRM_FIELD_NUMBER :
|
||||
int cversion = codedIS.readUInt32();
|
||||
|
@ -435,7 +448,7 @@ public class BinaryMapIndexReader {
|
|||
int length = readInt();
|
||||
int filePointer = codedIS.getTotalBytesRead();
|
||||
oldLimit = codedIS.pushLimit(length);
|
||||
MapRoot mapRoot = readMapLevel();
|
||||
MapRoot mapRoot = readMapLevel(new MapRoot());
|
||||
mapRoot.length = length;
|
||||
mapRoot.filePointer = filePointer;
|
||||
index.getRoots().add(mapRoot);
|
||||
|
@ -492,8 +505,7 @@ public class BinaryMapIndexReader {
|
|||
}
|
||||
|
||||
|
||||
private MapRoot readMapLevel() throws IOException {
|
||||
MapRoot root = new MapRoot();
|
||||
private MapRoot readMapLevel(MapRoot root) throws IOException {
|
||||
while(true){
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
|
@ -519,15 +531,19 @@ public class BinaryMapIndexReader {
|
|||
root.minZoom = codedIS.readInt32();
|
||||
break;
|
||||
case OsmandOdb.MapRootLevel.ROOT_FIELD_NUMBER :
|
||||
MapTree r = new MapTree();
|
||||
// left, ... already initialized
|
||||
r.length = readInt();
|
||||
r.filePointer = codedIS.getTotalBytesRead();
|
||||
int oldLimit = codedIS.pushLimit(r.length);
|
||||
readMapTreeBounds(r, root.left, root.right, root.top, root.bottom);
|
||||
root.trees.add(r);
|
||||
codedIS.popLimit(oldLimit);
|
||||
codedIS.seek(r.filePointer + r.length);
|
||||
int length = readInt();
|
||||
int filePointer = codedIS.getTotalBytesRead();
|
||||
if (root.trees != null) {
|
||||
MapTree r = new MapTree();
|
||||
// left, ... already initialized
|
||||
r.length = length;
|
||||
r.filePointer = filePointer;
|
||||
int oldLimit = codedIS.pushLimit(r.length);
|
||||
readMapTreeBounds(r, root.left, root.right, root.top, root.bottom);
|
||||
root.trees.add(r);
|
||||
codedIS.popLimit(oldLimit);
|
||||
}
|
||||
codedIS.seek(filePointer + length);
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
|
@ -585,6 +601,15 @@ public class BinaryMapIndexReader {
|
|||
if (index.right < req.left || index.left > req.right || index.top > req.bottom || index.bottom < req.top) {
|
||||
continue;
|
||||
}
|
||||
// lazy initializing trees
|
||||
if(index.trees == null){
|
||||
index.trees = new ArrayList<MapTree>();
|
||||
codedIS.seek(index.filePointer);
|
||||
int oldLimit = codedIS.pushLimit(index.length);
|
||||
readMapLevel(index);
|
||||
codedIS.popLimit(oldLimit);
|
||||
}
|
||||
|
||||
for (MapTree tree : index.trees) {
|
||||
if (tree.right < req.left || tree.left > req.right || tree.top > req.bottom || tree.bottom < req.top) {
|
||||
continue;
|
||||
|
@ -1048,7 +1073,7 @@ public class BinaryMapIndexReader {
|
|||
return bottom;
|
||||
}
|
||||
|
||||
List<MapTree> trees = new ArrayList<MapTree>();
|
||||
private List<MapTree> trees = null;
|
||||
}
|
||||
|
||||
private static class MapTree {
|
||||
|
|
|
@ -103,7 +103,8 @@ public class BinaryMapTransportReaderAdapter {
|
|||
IndexStringTable st = new IndexStringTable();
|
||||
st.length = codedIS.readRawVarint32();
|
||||
st.fileOffset = codedIS.getTotalBytesRead();
|
||||
readStringTable(st, 0, 20, true);
|
||||
// Do not cache for now save memory
|
||||
// readStringTable(st, 0, 20, true);
|
||||
ind.stringTable = st;
|
||||
codedIS.seek(st.length + st.fileOffset);
|
||||
break;
|
||||
|
|
|
@ -40,11 +40,21 @@ public class BinaryRoutePlanner {
|
|||
|
||||
private static double squareRootDist(int x1, int y1, int x2, int y2) {
|
||||
// translate into meters
|
||||
double dy = (y1 - y2) * 0.01863d;
|
||||
double dx = (x1 - x2) * 0.011d;
|
||||
double dy = convert31YToMeters(y1, y2);
|
||||
double dx = convert31XToMeters(x1, x2);
|
||||
return Math.sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
private static double convert31YToMeters(int y1, int y2) {
|
||||
// translate into meters
|
||||
return (y1 - y2) * 0.01863d;
|
||||
}
|
||||
|
||||
private static double convert31XToMeters(int x1, int x2) {
|
||||
// translate into meters
|
||||
return (x1 - x2) * 0.011d;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void loadRoutes(final RoutingContext ctx, int tileX, int tileY) throws IOException {
|
||||
|
@ -166,7 +176,7 @@ public class BinaryRoutePlanner {
|
|||
Comparator<RouteSegment> nonHeuristicSegmentsComparator = new Comparator<RouteSegment>(){
|
||||
@Override
|
||||
public int compare(RouteSegment o1, RouteSegment o2) {
|
||||
return roadPriorityComparator(o1.distanceFromStart, o1.distanceToEnd, o2.distanceFromStart, o2.distanceToEnd, 1);
|
||||
return roadPriorityComparator(o1.distanceFromStart, o1.distanceToEnd, o2.distanceFromStart, o2.distanceToEnd, 0.5);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -228,9 +238,9 @@ public class BinaryRoutePlanner {
|
|||
break;
|
||||
}
|
||||
if(ctx.planRouteIn2Directions()){
|
||||
// inverse = nonHeuristicSegmentsComparator.compare(graphDirectSegments.peek(), graphReverseSegments.peek()) > 0;
|
||||
inverse = nonHeuristicSegmentsComparator.compare(graphDirectSegments.peek(), graphReverseSegments.peek()) > 0;
|
||||
// make it more simmetrical with dynamic prioritizing it makes big sense
|
||||
inverse = !inverse;
|
||||
// inverse = !inverse;
|
||||
} else {
|
||||
// different strategy : use onedirectional graph
|
||||
inverse = !ctx.getPlanRoadDirection().booleanValue();
|
||||
|
|
|
@ -49,7 +49,7 @@ import org.xml.sax.SAXException;
|
|||
public class MapRouterLayer implements MapPanelLayer {
|
||||
|
||||
private /*final */ static boolean ANIMATE_CALCULATING_ROUTE = false;
|
||||
private /*final */ static int SIZE_OF_ROUTES_TO_ANIMATE = 50;
|
||||
private /*final */ static int SIZE_OF_ROUTES_TO_ANIMATE = 250;
|
||||
|
||||
|
||||
private MapPanel map;
|
||||
|
@ -340,7 +340,7 @@ public class MapRouterLayer implements MapPanelLayer {
|
|||
BinaryMapIndexReader[] rs = new BinaryMapIndexReader[files.length];
|
||||
for(int i=0; i<files.length; i++){
|
||||
RandomAccessFile raf = new RandomAccessFile(files[i], "r"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
rs[i] = new BinaryMapIndexReader(raf);
|
||||
rs[i] = new BinaryMapIndexReader(raf, true);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -72,8 +72,9 @@ public class ResourceManager {
|
|||
protected static ResourceManager manager = null;
|
||||
|
||||
// it is not good investigated but no more than 64 (satellite images)
|
||||
// Only 8 MB (from 16 Mb whole mem) available for images : image 64K * 128 = 8 MB (8 bit), 64 - 16 bit, 32 - 32 bit
|
||||
protected int maxImgCacheSize = 32;
|
||||
// Only 8 MB (from 16 Mb whole mem) available for images : image 64K * 128 = 8 MB (8 bit), 64 - 16 bit, 32 - 32 bit
|
||||
// at least 3*9?
|
||||
protected int maxImgCacheSize = 28;
|
||||
|
||||
protected Map<String, Bitmap> cacheOfImages = new LinkedHashMap<String, Bitmap>();
|
||||
protected Map<String, Boolean> imagesOnFS = new LinkedHashMap<String, Boolean>() ;
|
||||
|
|
Loading…
Reference in a new issue