Speedup initialization

This commit is contained in:
Victor Shcherb 2012-08-16 23:23:42 +02:00
parent b7553405f9
commit 9315a96fe3
6 changed files with 85 additions and 73 deletions

View file

@ -1114,11 +1114,16 @@ public class BinaryMapIndexReader {
return req.getSearchResults();
}
public void initCategories(PoiRegion poiIndex) throws IOException {
poiAdapter.initCategories(poiIndex);
}
public List<Amenity> searchPoiByName(SearchRequest<Amenity> 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<AmenityType, List<String>> searchPoiCategoriesByName(String query, Map<AmenityType, List<String>> map) {
public Map<AmenityType, List<String>> searchPoiCategoriesByName(String query, Map<AmenityType, List<String>> 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<String> 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<String>());
}
List<String> 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;

View file

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

View file

@ -61,7 +61,12 @@ public class AmenityIndexRepositoryBinary implements AmenityIndexRepository {
public Map<AmenityType, List<String>> searchAmenityCategoriesByName(String query, Map<AmenityType, List<String>> 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;
}

View file

@ -41,11 +41,16 @@ public class SearchByNameFilter extends PoiFilter {
protected List<Amenity> searchAmenities(double lat, double lon, double topLatitude,
double bottomLatitude, double leftLongitude, double rightLongitude, final ResultMatcher<Amenity> matcher) {
searchedAmenities.clear();
final int limit = distanceInd == 0 ? 500 : -1;
List<Amenity> result = application.getResourceManager().searchAmenitiesByName(query,
topLatitude, leftLongitude, bottomLatitude, rightLongitude, lat, lon, new ResultMatcher<Amenity>() {
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);

View file

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

View file

@ -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.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++) {
@ -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<MapTreeBounds> 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<MapTreeBounds>::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);
}
}