void OsmAnd::FavoriteLocationsPresenter_P::syncFavoriteLocationMarkers() { QWriteLocker scopedLocker(&_favoriteLocationToMarkerMapLock); const auto favoriteLocations = copyAs< QList< std::shared_ptr<const IFavoriteLocation> > >( owner->collection->getFavoriteLocations()); // Remove all markers that have no corresponding favorite locations anymore auto itObsoleteEntry = mutableIteratorOf(_favoriteLocationToMarkerMap); while (itObsoleteEntry.hasNext()) { const auto& obsoleteEntry = itObsoleteEntry.next(); if (favoriteLocations.contains(obsoleteEntry.key())) continue; _markersCollection->removeMarker(obsoleteEntry.value()); itObsoleteEntry.remove(); } // Create markers for all new favorite locations MapMarkerBuilder markerBuilder; markerBuilder.setBaseOrder(0); markerBuilder.setIsAccuracyCircleSupported(false); markerBuilder.setPinIcon( owner->favoriteLocationPinIconBitmap ? owner->favoriteLocationPinIconBitmap : FavoriteLocationsPresenter::getDefaultFavoriteLocationPinIconBitmap()); markerBuilder.setPinIconAlignment( owner->favoriteLocationPinIconAlignment.isSet() ? *owner->favoriteLocationPinIconAlignment.getValuePtrOrNullptr() : FavoriteLocationsPresenter::getDefaultFavoriteLocationPinIconAlignment()); for (const auto& favoriteLocation : favoriteLocations) { if (_favoriteLocationToMarkerMap.contains(favoriteLocation)) continue; markerBuilder.setPosition(favoriteLocation->getPosition31()); markerBuilder.setPinIconModulationColor(favoriteLocation->getColor()); markerBuilder.setIsHidden(favoriteLocation->isHidden()); const auto marker = markerBuilder.buildAndAddToCollection(_markersCollection); _favoriteLocationToMarkerMap.insert(favoriteLocation, marker); } }
void OsmAnd::CachingRoadLocator_P::clearCacheConditional(const std::function<bool (const std::shared_ptr<const ObfRoutingSectionReader::DataBlock>& dataBlock)> shouldRemoveFromCacheFunctor) { QMutexLocker scopedLocker(&_referencedDataBlocksMapMutex); auto itReferencedDataBlocks = mutableIteratorOf(_referencedDataBlocksMap); while (itReferencedDataBlocks.hasNext()) { auto& referencedDataBlocks = itReferencedDataBlocks.next().value(); if (!shouldRemoveFromCacheFunctor(referencedDataBlocks.first())) continue; for (auto& reference : referencedDataBlocks) { if (shouldRemoveFromCacheFunctor(reference)) _cache.releaseReference(reference->id, reference); } itReferencedDataBlocks.remove(); } }
void OsmAnd::ObfsCollection_P::collectSources() const { QWriteLocker scopedLocker1(&_collectedSourcesLock); QReadLocker scopedLocker2(&_sourcesOriginsLock); // Capture how many invalidations are going to be processed const auto invalidationsToProcess = _collectedSourcesInvalidated.loadAcquire(); if (invalidationsToProcess == 0) return; #if OSMAND_DEBUG const auto collectSources_Begin = std::chrono::high_resolution_clock::now(); #endif // Check all previously collected sources auto itCollectedSourcesEntry = mutableIteratorOf(_collectedSources); while(itCollectedSourcesEntry.hasNext()) { const auto& collectedSourcesEntry = itCollectedSourcesEntry.next(); const auto& originId = collectedSourcesEntry.key(); auto& collectedSources = collectedSourcesEntry.value(); const auto& itSourceOrigin = _sourcesOrigins.constFind(originId); // If current source origin was removed, // remove entire each collected source related to it if (itSourceOrigin == _sourcesOrigins.cend()) { // Ensure that ObfFile is not being read anywhere for(const auto& itCollectedSource : rangeOf(collectedSources)) { const auto obfFile = itCollectedSource.value(); //NOTE: OBF should have been locked here, but since file is gone anyways, this lock is quite useless itCollectedSource.value().reset(); assert(obfFile.use_count() == 1); } itCollectedSourcesEntry.remove(); continue; } // Check for missing files auto itObfFileEntry = mutableIteratorOf(collectedSources); while(itObfFileEntry.hasNext()) { const auto& sourceFilename = itObfFileEntry.next().key(); if (QFile::exists(sourceFilename)) continue; const auto obfFile = itObfFileEntry.value(); //NOTE: OBF should have been locked here, but since file is gone anyways, this lock is quite useless itObfFileEntry.remove(); assert(obfFile.use_count() == 1); } // If all collected sources for current source origin are gone, // remove entire collection attached to source origin ID if (collectedSources.isEmpty()) { itCollectedSourcesEntry.remove(); continue; } } // Find all files uncollected sources for(const auto& itEntry : rangeOf(constOf(_sourcesOrigins))) { const auto& originId = itEntry.key(); const auto& entry = itEntry.value(); auto itCollectedSources = _collectedSources.find(originId); if (itCollectedSources == _collectedSources.end()) itCollectedSources = _collectedSources.insert(originId, QHash<QString, std::shared_ptr<ObfFile> >()); auto& collectedSources = *itCollectedSources; if (entry->type == SourceOriginType::Directory) { const auto& directoryAsSourceOrigin = std::static_pointer_cast<const DirectoryAsSourceOrigin>(entry); QFileInfoList obfFilesInfo; Utilities::findFiles(directoryAsSourceOrigin->directory, QStringList() << QLatin1String("*.obf"), obfFilesInfo, directoryAsSourceOrigin->isRecursive); for(const auto& obfFileInfo : constOf(obfFilesInfo)) { const auto& obfFilePath = obfFileInfo.canonicalFilePath(); if (collectedSources.constFind(obfFilePath) != collectedSources.cend()) continue; auto obfFile = new ObfFile(obfFilePath, obfFileInfo.size()); collectedSources.insert(obfFilePath, std::shared_ptr<ObfFile>(obfFile)); } if (directoryAsSourceOrigin->isRecursive) { QFileInfoList directoriesInfo; Utilities::findDirectories(directoryAsSourceOrigin->directory, QStringList() << QLatin1String("*"), directoriesInfo, true); for(const auto& directoryInfo : constOf(directoriesInfo)) { const auto canonicalPath = directoryInfo.canonicalFilePath(); if (directoryAsSourceOrigin->watchedSubdirectories.contains(canonicalPath)) continue; _fileSystemWatcher->addPath(canonicalPath); directoryAsSourceOrigin->watchedSubdirectories.insert(canonicalPath); } } } else if (entry->type == SourceOriginType::File) { const auto& fileAsSourceOrigin = std::static_pointer_cast<const FileAsSourceOrigin>(entry); if (!fileAsSourceOrigin->fileInfo.exists()) continue; const auto& obfFilePath = fileAsSourceOrigin->fileInfo.canonicalFilePath(); if (collectedSources.constFind(obfFilePath) != collectedSources.cend()) continue; auto obfFile = new ObfFile(obfFilePath, fileAsSourceOrigin->fileInfo.size()); collectedSources.insert(obfFilePath, std::shared_ptr<ObfFile>(obfFile)); } } // Decrement invalidations counter with number of processed onces _collectedSourcesInvalidated.fetchAndAddOrdered(-invalidationsToProcess); #if OSMAND_DEBUG const auto collectSources_End = std::chrono::high_resolution_clock::now(); const std::chrono::duration<float> collectSources_Elapsed = collectSources_End - collectSources_Begin; LogPrintf(LogSeverityLevel::Info, "Collected OBF sources in %fs", collectSources_Elapsed.count()); #endif }