Speed up loading

This commit is contained in:
Victor Shcherb 2012-08-15 00:25:41 +02:00
parent 05b6cd9ca5
commit b7553405f9
4 changed files with 112 additions and 45 deletions

View file

@ -145,9 +145,7 @@ public class BinaryMapIndexReader {
mapIndex.length = readInt();
mapIndex.filePointer = codedIS.getTotalBytesRead();
int oldLimit = codedIS.pushLimit(mapIndex.length);
// FIXME
// codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
readMapIndex(mapIndex);
readMapIndex(mapIndex, false);
basemap = basemap || mapIndex.isBaseMap();
codedIS.popLimit(oldLimit);
codedIS.seek(mapIndex.filePointer + mapIndex.length);
@ -209,7 +207,7 @@ public class BinaryMapIndexReader {
oldLimit = codedIS.pushLimit(poiInd.length);
// FIXME
// codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
poiAdapter.readPoiIndex(poiInd);
poiAdapter.readPoiIndex(poiInd, false);
codedIS.popLimit(oldLimit);
poiIndexes.add(poiInd);
indexes.add(poiInd);
@ -574,8 +572,9 @@ public class BinaryMapIndexReader {
* Map public methods
*/
private void readMapIndex(MapIndex index) throws IOException {
private void readMapIndex(MapIndex index, boolean onlyInitEncodingRules) throws IOException {
int defaultId = 1;
int oldLimit ;
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
@ -583,29 +582,34 @@ public class BinaryMapIndexReader {
switch (tag) {
case 0:
// encoding rules are required!
if(index.encodingRules.isEmpty()){
throw new IllegalStateException("Encoding rules are not defined for the map index");
if (onlyInitEncodingRules) {
index.finishInitializingTags();
}
index.finishInitializingTags();
return;
case OsmandOdb.OsmAndMapIndex.NAME_FIELD_NUMBER :
index.setName(codedIS.readString());
break;
case OsmandOdb.OsmAndMapIndex.RULES_FIELD_NUMBER :
int len = codedIS.readInt32();
int oldLimit = codedIS.pushLimit(len);
readMapEncodingRule(index, defaultId++);
codedIS.popLimit(oldLimit);
if (onlyInitEncodingRules) {
int len = codedIS.readInt32();
oldLimit = codedIS.pushLimit(len);
readMapEncodingRule(index, defaultId++);
codedIS.popLimit(oldLimit);
} else {
skipUnknownField(t);
}
break;
case OsmandOdb.OsmAndMapIndex.LEVELS_FIELD_NUMBER :
int length = readInt();
int filePointer = codedIS.getTotalBytesRead();
oldLimit = codedIS.pushLimit(length);
MapRoot mapRoot = readMapLevel(new MapRoot());
mapRoot.length = length;
mapRoot.filePointer = filePointer;
index.getRoots().add(mapRoot);
codedIS.popLimit(oldLimit);
if (!onlyInitEncodingRules) {
oldLimit = codedIS.pushLimit(length);
MapRoot mapRoot = readMapLevel(new MapRoot());
mapRoot.length = length;
mapRoot.filePointer = filePointer;
index.getRoots().add(mapRoot);
codedIS.popLimit(oldLimit);
}
codedIS.seek(filePointer + length);
break;
default:
@ -749,6 +753,13 @@ public class BinaryMapIndexReader {
if (index.right < req.left || index.left > req.right || index.top > req.bottom || index.bottom < req.top) {
continue;
}
// lazy initializing rules
if(mapIndex.encodingRules.isEmpty()) {
codedIS.seek(mapIndex.filePointer);
int oldLimit = codedIS.pushLimit(mapIndex.length);
readMapIndex(mapIndex, true);
codedIS.popLimit(oldLimit);
}
// lazy initializing trees
if(index.trees == null){
index.trees = new ArrayList<MapTree>();

View file

@ -79,7 +79,7 @@ public class BinaryMapPoiReaderAdapter {
return map.readInt();
}
protected void readPoiBoundariesIndex(PoiRegion region) throws IOException {
private void readPoiBoundariesIndex(PoiRegion region) throws IOException {
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
@ -106,7 +106,9 @@ public class BinaryMapPoiReaderAdapter {
}
protected void readPoiIndex(PoiRegion region) throws IOException {
protected void readPoiIndex(PoiRegion region, boolean readCategories) throws IOException {
int length;
int oldLimit;
while(true){
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
@ -116,19 +118,21 @@ public class BinaryMapPoiReaderAdapter {
case OsmandOdb.OsmAndPoiIndex.NAME_FIELD_NUMBER :
region.name = codedIS.readString();
break;
case OsmandOdb.OsmAndPoiIndex.BOUNDARIES_FIELD_NUMBER: {
int length = codedIS.readRawVarint32();
int oldLimit = codedIS.pushLimit(length);
case OsmandOdb.OsmAndPoiIndex.BOUNDARIES_FIELD_NUMBER:
length = codedIS.readRawVarint32();
oldLimit = codedIS.pushLimit(length);
readPoiBoundariesIndex(region);
codedIS.popLimit(oldLimit);
}
break;
case OsmandOdb.OsmAndPoiIndex.CATEGORIESTABLE_FIELD_NUMBER : {
int length = codedIS.readRawVarint32();
int oldLimit = codedIS.pushLimit(length);
case OsmandOdb.OsmAndPoiIndex.CATEGORIESTABLE_FIELD_NUMBER :
if(!readCategories){
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
return;
}
length = codedIS.readRawVarint32();
oldLimit = codedIS.pushLimit(length);
readCategory(region);
codedIS.popLimit(oldLimit);
} break;
case OsmandOdb.OsmAndPoiIndex.BOXES_FIELD_NUMBER :
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
return;
@ -162,6 +166,10 @@ public class BinaryMapPoiReaderAdapter {
}
}
protected void initCategories(PoiRegion region){
}
protected void searchPoiByName( PoiRegion region, SearchRequest<Amenity> req) throws IOException {
TIntLongHashMap offsets = new TIntLongHashMap();
Collator instance = Collator.getInstance();
@ -170,6 +178,7 @@ public class BinaryMapPoiReaderAdapter {
StringMatcherMode.CHECK_STARTS_FROM_SPACE);
long time = System.currentTimeMillis();
int indexOffset = codedIS.getTotalBytesRead();
boolean readCategories = region.categories.isEmpty();
while(true){
if(req.isCancelled()){
return;
@ -186,6 +195,15 @@ public class BinaryMapPoiReaderAdapter {
offsets = readPoiNameIndex(instance, req.nameQuery, req);
codedIS.popLimit(oldLimit);
break;
case OsmandOdb.OsmAndPoiIndex.CATEGORIESTABLE_FIELD_NUMBER :
if(!readCategories){
skipUnknownField(t);
} else {
length = codedIS.readRawVarint32();
oldLimit = codedIS.pushLimit(length);
readCategory(region);
codedIS.popLimit(oldLimit);
}
case OsmandOdb.OsmAndPoiIndex.POIDATA_FIELD_NUMBER :
// also offsets can be randomly skipped by limit
Integer[] offKeys = new Integer[offsets.size()];
@ -349,6 +367,9 @@ public class BinaryMapPoiReaderAdapter {
skipTiles = new TLongHashSet();
zoomToSkip = req.zoom + ZOOM_TO_SKIP_FILTER;
}
int length ;
int oldLimit ;
boolean readCategories = region.categories.isEmpty();
TIntLongHashMap offsetsMap = new TIntLongHashMap();
while(true){
if(req.isCancelled()){
@ -359,9 +380,18 @@ public class BinaryMapPoiReaderAdapter {
switch (tag) {
case 0:
return;
case OsmandOdb.OsmAndPoiIndex.CATEGORIESTABLE_FIELD_NUMBER :
if(!readCategories){
skipUnknownField(t);
} else {
length = codedIS.readRawVarint32();
oldLimit = codedIS.pushLimit(length);
readCategory(region);
codedIS.popLimit(oldLimit);
}
case OsmandOdb.OsmAndPoiIndex.BOXES_FIELD_NUMBER :
int length = readInt();
int oldLimit = codedIS.pushLimit(length);
length = readInt();
oldLimit = codedIS.pushLimit(length);
readBoxField(left31, right31, top31, bottom31, 0, 0, 0, offsetsMap, skipTiles, req, region);
codedIS.popLimit(oldLimit);
break;

View file

@ -97,7 +97,7 @@ bool readMapTreeBounds(CodedInputStream* input, MapTreeBounds* tree, MapRoot* ro
return true;
}
bool readMapLevel(CodedInputStream* input, MapRoot* root) {
bool readMapLevel(CodedInputStream* input, MapRoot* root, bool initSubtrees) {
int tag;
int si;
while ((tag = input->ReadTag()) != 0) {
@ -131,6 +131,10 @@ bool readMapLevel(CodedInputStream* input, MapRoot* root) {
break;
}
case OsmAndMapIndex_MapRootLevel::kBoxesFieldNumber: {
if(!initSubtrees){
input->Skip(input->BytesUntilLimit());
return true;
}
MapTreeBounds bounds;
readInt(input, &bounds.length);
bounds.filePointer = input->getTotalBytesRead();
@ -345,7 +349,7 @@ bool readRoutingIndex(CodedInputStream* input, RoutingIndex* routingIndex) {
return true;
}
bool readMapIndex(CodedInputStream* input, MapIndex* mapIndex) {
bool readMapIndex(CodedInputStream* input, MapIndex* mapIndex, bool onlyInitEncodingRules) {
uint32_t tag;
uint32_t defaultId = 1;
while ((tag = input->ReadTag()) != 0) {
@ -355,22 +359,29 @@ bool readMapIndex(CodedInputStream* input, MapIndex* mapIndex) {
break;
}
case OsmAndMapIndex::kRulesFieldNumber: {
int len;
WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_INT32>(input, &len);
int oldLimit = input->PushLimit(len);
readMapEncodingRule(input, mapIndex, defaultId++);
input->PopLimit(oldLimit);
if(onlyInitEncodingRules) {
int len;
WireFormatLite::ReadPrimitive<int32_t, WireFormatLite::TYPE_INT32>(input, &len);
int oldLimit = input->PushLimit(len);
readMapEncodingRule(input, mapIndex, defaultId++);
input->PopLimit(oldLimit);
} else {
skipUnknownFields(input, tag);
}
break;
}
case OsmAndMapIndex::kLevelsFieldNumber: {
MapRoot mapLevel;
readInt(input, &mapLevel.length);
mapLevel.filePointer = input->getTotalBytesRead();
int oldLimit = input->PushLimit(mapLevel.length);
readMapLevel(input, &mapLevel);
input->PopLimit(oldLimit);
if (!onlyInitEncodingRules) {
int oldLimit = input->PushLimit(mapLevel.length);
readMapLevel(input, &mapLevel, false);
input->PopLimit(oldLimit);
mapIndex->levels.push_back(mapLevel);
}
input->Seek(mapLevel.filePointer + mapLevel.length);
mapIndex->levels.push_back(mapLevel);
break;
}
default: {
@ -384,7 +395,9 @@ bool readMapIndex(CodedInputStream* input, MapIndex* mapIndex) {
}
}
}
mapIndex->finishInitializingTags();
if(onlyInitEncodingRules) {
mapIndex->finishInitializingTags();
}
return true;
}
@ -410,7 +423,7 @@ bool initMapStructure(CodedInputStream* input, BinaryMapFile* file) {
readInt(input, &mapIndex.length);
mapIndex.filePointer = input->getTotalBytesRead();
int oldLimit = input->PushLimit(mapIndex.length);
readMapIndex(input, &mapIndex);
readMapIndex(input, &mapIndex, false);
input->PopLimit(oldLimit);
input->Seek(mapIndex.filePointer + mapIndex.length);
file->mapIndexes.push_back(mapIndex);
@ -830,6 +843,20 @@ bool readMapDataBlocks(CodedInputStream* input, SearchQuery* req, MapTreeBounds*
bool sortTreeBounds (const MapTreeBounds& i,const MapTreeBounds& j) { return (i.mapDataBlock<j.mapDataBlock); }
void searchMapData(CodedInputStream* input, MapRoot* root, MapIndex* ind, SearchQuery* req) {
// lazy initializing rules
if (ind->decodingRules.size() == 0) {
input->Seek(ind->filePointer);
int oldLimit = input->PushLimit(ind->length);
readMapIndex(input, ind, true);
input->PopLimit(oldLimit);
}
// lazy initializing subtrees
if (root->bounds.size() == 0) {
input->Seek(root->filePointer);
int oldLimit = input->PushLimit(root->length);
readMapLevel(input, root, true);
input->PopLimit(oldLimit);
}
// search
for (std::vector<MapTreeBounds>::iterator i = root->bounds.begin();
i != root->bounds.end(); i++) {
@ -839,6 +866,7 @@ void searchMapData(CodedInputStream* input, MapRoot* root, MapIndex* ind, Search
if (i->right < req->left || i->left > req->right || i->top > req->bottom || i->bottom < req->top) {
continue;
}
std::vector<MapTreeBounds> foundSubtrees;
input->Seek(i->filePointer);
int oldLimit = input->PushLimit(i->length);

View file

@ -61,8 +61,6 @@ extern "C" JNIEXPORT jboolean JNICALL Java_net_osmand_NativeLibrary_initBinaryMa
BinaryMapFile* fl = initBinaryMapFile(inputName);
if(fl == NULL) {
osmand_log_print(LOG_WARN, "File %s was not initialized", inputName.c_str());
} else {
osmand_log_print(LOG_INFO, "File %s is initialized.", fl->inputName.c_str());
}
return fl != NULL;
}