Reduce memory map consumption

This commit is contained in:
Victor Shcherb 2011-07-07 20:49:09 +02:00
parent f13883216c
commit e8df7a420e
5 changed files with 75 additions and 38 deletions

View file

@ -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 {

View file

@ -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;

View file

@ -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();

View file

@ -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);
}

View file

@ -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>() ;