From 9315a96fe37a54b41008aeb140ea27cc8bf183ef Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Thu, 16 Aug 2012 23:23:42 +0200 Subject: [PATCH] Speedup initialization --- .../osmand/binary/BinaryMapIndexReader.java | 26 ++++--- .../binary/BinaryMapPoiReaderAdapter.java | 34 +++------- .../plus/AmenityIndexRepositoryBinary.java | 7 +- .../net/osmand/plus/SearchByNameFilter.java | 7 +- .../osmand/plus/activities/MapActivity.java | 17 ++--- Osmand-kernel/osmand/src/binaryRead.cpp | 67 ++++++++++--------- 6 files changed, 85 insertions(+), 73 deletions(-) diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java index 8259583a16..48a6ce9237 100644 --- a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java +++ b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java @@ -1114,11 +1114,16 @@ public class BinaryMapIndexReader { return req.getSearchResults(); } + public void initCategories(PoiRegion poiIndex) throws IOException { + poiAdapter.initCategories(poiIndex); + } + public List searchPoiByName(SearchRequest req) throws IOException { if (req.nameQuery == null || req.nameQuery.length() == 0) { throw new IllegalArgumentException(); } for (PoiRegion poiIndex : poiIndexes) { + poiAdapter.initCategories(poiIndex); codedIS.seek(poiIndex.filePointer); int old = codedIS.pushLimit(poiIndex.length); poiAdapter.searchPoiByName(poiIndex, req); @@ -1127,31 +1132,32 @@ public class BinaryMapIndexReader { return req.getSearchResults(); } - public Map> searchPoiCategoriesByName(String query, Map> map) { + public Map> searchPoiCategoriesByName(String query, Map> map) throws IOException { if (query == null || query.length() == 0) { throw new IllegalArgumentException(); } Collator collator = Collator.getInstance(); collator.setStrength(Collator.PRIMARY); for (PoiRegion poiIndex : poiIndexes) { - for(int i= 0; i< poiIndex.categories.size(); i++){ + poiAdapter.initCategories(poiIndex); + for (int i = 0; i < poiIndex.categories.size(); i++) { String cat = poiIndex.categories.get(i); AmenityType catType = poiIndex.categoriesType.get(i); - if(CollatorStringMatcher.cmatches(collator, cat, query, StringMatcherMode.CHECK_STARTS_FROM_SPACE)){ + if (CollatorStringMatcher.cmatches(collator, cat, query, StringMatcherMode.CHECK_STARTS_FROM_SPACE)) { map.put(catType, null); } else { List subcats = poiIndex.subcategories.get(i); - for(int j=0; j< subcats.size(); j++){ - if(CollatorStringMatcher.cmatches(collator, subcats.get(j), query, StringMatcherMode.CHECK_STARTS_FROM_SPACE)){ - if(!map.containsKey(catType)){ + for (int j = 0; j < subcats.size(); j++) { + if (CollatorStringMatcher.cmatches(collator, subcats.get(j), query, StringMatcherMode.CHECK_STARTS_FROM_SPACE)) { + if (!map.containsKey(catType)) { map.put(catType, new ArrayList()); } List list = map.get(catType); - if(list != null){ + if (list != null) { list.add(subcats.get(j)); } } - + } } } @@ -1165,6 +1171,7 @@ public class BinaryMapIndexReader { req.numberOfAcceptedSubtrees = 0; req.numberOfReadSubtrees = 0; for (PoiRegion poiIndex : poiIndexes) { + poiAdapter.initCategories(poiIndex); codedIS.seek(poiIndex.filePointer); int old = codedIS.pushLimit(poiIndex.length); poiAdapter.searchPoiIndex(req.left, req.right, req.top, req.bottom, req, poiIndex); @@ -1383,6 +1390,9 @@ public class BinaryMapIndexReader { this.interrupted = interrupted; } + public boolean limitExceeded() { + return limit != -1 && searchResults.size() > limit; + } public boolean isCancelled() { if(this.interrupted){ return interrupted; diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryMapPoiReaderAdapter.java b/DataExtractionOSM/src/net/osmand/binary/BinaryMapPoiReaderAdapter.java index c308e17df0..4f4001c028 100644 --- a/DataExtractionOSM/src/net/osmand/binary/BinaryMapPoiReaderAdapter.java +++ b/DataExtractionOSM/src/net/osmand/binary/BinaryMapPoiReaderAdapter.java @@ -133,6 +133,7 @@ public class BinaryMapPoiReaderAdapter { oldLimit = codedIS.pushLimit(length); readCategory(region); codedIS.popLimit(oldLimit); + break; case OsmandOdb.OsmAndPoiIndex.BOXES_FIELD_NUMBER : codedIS.skipRawBytes(codedIS.getBytesUntilLimit()); return; @@ -166,8 +167,13 @@ public class BinaryMapPoiReaderAdapter { } } - protected void initCategories(PoiRegion region){ - + public void initCategories(PoiRegion region) throws IOException { + if(region.categories.isEmpty()) { + codedIS.seek(region.filePointer); + int oldLimit = codedIS.pushLimit(region.length); + readPoiIndex(region, true); + codedIS.popLimit(oldLimit); + } } protected void searchPoiByName( PoiRegion region, SearchRequest req) throws IOException { @@ -178,7 +184,6 @@ 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; @@ -195,15 +200,6 @@ 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()]; @@ -242,7 +238,7 @@ public class BinaryMapPoiReaderAdapter { int oldLim = codedIS.pushLimit(len); readPoiData(matcher, req, region); codedIS.popLimit(oldLim); - if(req.isCancelled()){ + if(req.isCancelled() || req.limitExceeded()){ return; } } @@ -369,7 +365,6 @@ public class BinaryMapPoiReaderAdapter { } int length ; int oldLimit ; - boolean readCategories = region.categories.isEmpty(); TIntLongHashMap offsetsMap = new TIntLongHashMap(); while(true){ if(req.isCancelled()){ @@ -380,15 +375,6 @@ 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 : length = readInt(); oldLimit = codedIS.pushLimit(length); @@ -428,7 +414,7 @@ public class BinaryMapPoiReaderAdapter { int y = 0; int zoom = 0; while(true){ - if(req.isCancelled()){ + if(req.isCancelled() || req.limitExceeded()){ return; } int t = codedIS.readTag(); diff --git a/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryBinary.java b/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryBinary.java index c48b29378d..9a4b726d69 100644 --- a/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryBinary.java +++ b/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryBinary.java @@ -61,7 +61,12 @@ public class AmenityIndexRepositoryBinary implements AmenityIndexRepository { public Map> searchAmenityCategoriesByName(String query, Map> map) { - return index.searchPoiCategoriesByName(query, map); + try { + return index.searchPoiCategoriesByName(query, map); + } catch (IOException e) { + log.error("Error searching amenities", e); //$NON-NLS-1$ + } + return map; } diff --git a/OsmAnd/src/net/osmand/plus/SearchByNameFilter.java b/OsmAnd/src/net/osmand/plus/SearchByNameFilter.java index 214ba707af..d0a507e438 100644 --- a/OsmAnd/src/net/osmand/plus/SearchByNameFilter.java +++ b/OsmAnd/src/net/osmand/plus/SearchByNameFilter.java @@ -41,11 +41,16 @@ public class SearchByNameFilter extends PoiFilter { protected List searchAmenities(double lat, double lon, double topLatitude, double bottomLatitude, double leftLongitude, double rightLongitude, final ResultMatcher matcher) { searchedAmenities.clear(); + final int limit = distanceInd == 0 ? 500 : -1; List result = application.getResourceManager().searchAmenitiesByName(query, topLatitude, leftLongitude, bottomLatitude, rightLongitude, lat, lon, new ResultMatcher() { + boolean elimit = false; @Override public boolean publish(Amenity object) { + if(limit != -1 && searchedAmenities.size() > limit) { + elimit = true; + } if(matcher.publish(object)) { searchedAmenities.add(object); return true; @@ -55,7 +60,7 @@ public class SearchByNameFilter extends PoiFilter { @Override public boolean isCancelled() { - return matcher.isCancelled(); + return matcher.isCancelled() || elimit; } }); MapUtils.sortListOfMapObject(result, lat, lon); diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index bf365739dc..7e8197ff2f 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -855,14 +855,15 @@ public class MapActivity extends AccessibleActivity implements IMapLocationListe } } int currentMapRotation = settings.ROTATE_MAP.get(); - if (location.hasBearing() && currentMapRotation == OsmandSettings.ROTATE_MAP_BEARING) { - mapView.setRotate(-location.getBearing()); - } else if (!location.hasBearing() && routingHelper.isFollowingMode() - && currentMapRotation == OsmandSettings.ROTATE_MAP_BEARING) { - if (Math.abs(MapUtils.degreesDiff(mapView.getRotate(), -previousSensorValue)) > 15 - && now - lastTimeSensorRotation > 1500) { - lastTimeSensorRotation = now; - mapView.setRotate(-previousSensorValue); + if (currentMapRotation == OsmandSettings.ROTATE_MAP_BEARING) { + if (location.hasBearing()) { + mapView.setRotate(-location.getBearing()); + } else if (routingHelper.isFollowingMode() && settings.USE_COMPASS_IN_NAVIGATION.get()) { + if (Math.abs(MapUtils.degreesDiff(mapView.getRotate(), -previousSensorValue)) > 15 + && now - lastTimeSensorRotation > 1500) { + lastTimeSensorRotation = now; + mapView.setRotate(-previousSensorValue); + } } } mapView.setLatLon(location.getLatitude(), location.getLongitude()); diff --git a/Osmand-kernel/osmand/src/binaryRead.cpp b/Osmand-kernel/osmand/src/binaryRead.cpp index a751b8818d..cf856b75d8 100644 --- a/Osmand-kernel/osmand/src/binaryRead.cpp +++ b/Osmand-kernel/osmand/src/binaryRead.cpp @@ -131,18 +131,17 @@ bool readMapLevel(CodedInputStream* input, MapRoot* root, bool initSubtrees) { break; } case OsmAndMapIndex_MapRootLevel::kBoxesFieldNumber: { - if(!initSubtrees){ - input->Skip(input->BytesUntilLimit()); - return true; - } MapTreeBounds bounds; readInt(input, &bounds.length); bounds.filePointer = input->getTotalBytesRead(); - int oldLimit = input->PushLimit(bounds.length); - readMapTreeBounds(input, &bounds, root); - root->bounds.push_back(bounds); - input->Skip(input->BytesUntilLimit()); - input->PopLimit(oldLimit); + if(initSubtrees){ + int oldLimit = input->PushLimit(bounds.length); + readMapTreeBounds(input, &bounds, root); + root->bounds.push_back(bounds); + input->PopLimit(oldLimit); + } else { + input->Skip(input->BytesUntilLimit()); + } break; } @@ -381,7 +380,6 @@ bool readMapIndex(CodedInputStream* input, MapIndex* mapIndex, bool onlyInitEnco mapIndex->levels.push_back(mapLevel); } input->Seek(mapLevel.filePointer + mapLevel.length); - break; } default: { @@ -843,20 +841,6 @@ bool readMapDataBlocks(CodedInputStream* input, SearchQuery* req, MapTreeBounds* bool sortTreeBounds (const MapTreeBounds& i,const MapTreeBounds& j) { return (i.mapDataBlockdecodingRules.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::iterator i = root->bounds.begin(); i != root->bounds.end(); i++) { @@ -866,14 +850,12 @@ 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 foundSubtrees; input->Seek(i->filePointer); int oldLimit = input->PushLimit(i->length); searchMapTreeBounds(input, &(*i), root, req, &foundSubtrees); input->PopLimit(oldLimit); - sort(foundSubtrees.begin(), foundSubtrees.end(), sortTreeBounds); uint32_t length; for (std::vector::iterator tree = foundSubtrees.begin(); @@ -907,11 +889,6 @@ ResultPublisher* searchObjectsForRendering(SearchQuery* q, bool skipDuplicates, bool basemapExists = false; for (; i != openFiles.end() && !q->publisher->isCancelled(); i++) { BinaryMapFile* file = i->second; - lseek(file->fd, 0, SEEK_SET); - FileInputStream input(file->fd); - input.SetCloseOnDelete(false); - CodedInputStream cis(&input); - cis.SetTotalBytesLimit(INT_MAX, INT_MAX >> 2); if (q->req != NULL) { q->req->clearState(); } @@ -928,6 +905,34 @@ ResultPublisher* searchObjectsForRendering(SearchQuery* q, bool skipDuplicates, if (mapLevel->right >= q->left && q->right >= mapLevel->left && mapLevel->bottom >= q->top && q->bottom >= mapLevel->top) { osmand_log_print(LOG_INFO, "Search map %s", mapIndex->name.c_str()); + // lazy initializing rules + if (mapIndex->decodingRules.size() == 0) { + lseek(file->fd, 0, SEEK_SET); + FileInputStream input(file->fd); + input.SetCloseOnDelete(false); + CodedInputStream cis(&input); + cis.Seek(mapIndex->filePointer); + int oldLimit = cis.PushLimit(mapIndex->length); + readMapIndex(&cis, mapIndex, true); + cis.PopLimit(oldLimit); + } + // lazy initializing subtrees + if (mapLevel->bounds.size() == 0) { + lseek(file->fd, 0, SEEK_SET); + FileInputStream input(file->fd); + input.SetCloseOnDelete(false); + CodedInputStream cis(&input); + cis.Seek(mapLevel->filePointer); + cis.SetTotalBytesLimit(INT_MAX, INT_MAX >> 2); + int oldLimit = cis.PushLimit(mapLevel->length); + readMapLevel(&cis, mapLevel, true); + cis.PopLimit(oldLimit); + } + lseek(file->fd, 0, SEEK_SET); + FileInputStream input(file->fd); + input.SetCloseOnDelete(false); + CodedInputStream cis(&input); + cis.SetTotalBytesLimit(INT_MAX, INT_MAX >> 2); searchMapData(&cis, &(*mapLevel), &(*mapIndex), q); } }