Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--map/bookmark_manager.cpp28
-rw-r--r--map/bookmark_manager.hpp2
-rw-r--r--map/user_mark_id_storage.cpp51
-rw-r--r--map/user_mark_id_storage.hpp13
4 files changed, 80 insertions, 14 deletions
diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp
index 575569ed63..431ce1b022 100644
--- a/map/bookmark_manager.cpp
+++ b/map/bookmark_manager.cpp
@@ -1336,11 +1336,10 @@ void BookmarkManager::CreateCategories(KMLDataCollection && dataCollection, bool
auto & fileData = *data.second;
auto & categoryData = fileData.m_categoryData;
- if ((categoryData.m_id != kml::kInvalidMarkGroupId) &&
- (UserMarkIdStorage::Instance().IsJustCreated() ||
- fileData.m_deviceId != GetPlatform().UniqueClientId()))
+ if (!UserMarkIdStorage::Instance().CheckIds(fileData) || HasDuplicatedIds(fileData))
{
LOG(LINFO, ("Bookmarks ids were reset for file", fileName));
+ //TODO: notify subscribers(like search subsystem). This KML could have been indexed.
ResetIds(fileData);
}
@@ -1395,6 +1394,29 @@ void BookmarkManager::CreateCategories(KMLDataCollection && dataCollection, bool
}
}
+bool BookmarkManager::HasDuplicatedIds(kml::FileData const & fileData) const
+{
+ CHECK_THREAD_CHECKER(m_threadChecker, ());
+ if (fileData.m_categoryData.m_id == kml::kInvalidMarkGroupId)
+ return false;
+
+ if (m_categories.find(fileData.m_categoryData.m_id) != m_categories.cend())
+ return true;
+
+ for (auto const & b : fileData.m_bookmarksData)
+ {
+ if (m_bookmarks.count(b.m_id) > 0)
+ return true;
+ }
+
+ for (auto const & t : fileData.m_tracksData)
+ {
+ if (m_tracks.count(t.m_id) > 0)
+ return true;
+ }
+ return false;
+}
+
std::unique_ptr<kml::FileData> BookmarkManager::CollectBmGroupKMLData(BookmarkCategory const * group) const
{
auto kmlData = std::make_unique<kml::FileData>();
diff --git a/map/bookmark_manager.hpp b/map/bookmark_manager.hpp
index 8a69608d1e..f85c9f1af1 100644
--- a/map/bookmark_manager.hpp
+++ b/map/bookmark_manager.hpp
@@ -443,6 +443,8 @@ private:
bool CanConvert() const;
void FinishConversion(ConversionHandler const & handler, bool result);
+ bool HasDuplicatedIds(kml::FileData const & fileData) const;
+
ThreadChecker m_threadChecker;
Callbacks m_callbacks;
diff --git a/map/user_mark_id_storage.cpp b/map/user_mark_id_storage.cpp
index b9ee26b049..62ca1a9654 100644
--- a/map/user_mark_id_storage.cpp
+++ b/map/user_mark_id_storage.cpp
@@ -14,10 +14,10 @@ std::string const kLastBookmarkCategoryId = "LastBookmarkCategoryId";
} // namespace
UserMarkIdStorage::UserMarkIdStorage()
- : m_isJustCreated(false)
- , m_lastUserMarkId(0)
+ : m_lastUserMarkId(0)
{
- m_isJustCreated = !(HasKey(kLastBookmarkCategoryId) && HasKey(kLastBookmarkId) && HasKey(kLastTrackId));
+ m_isJustCreated = !(HasKey(kLastBookmarkCategoryId) && HasKey(kLastBookmarkId) &&
+ HasKey(kLastTrackId));
if (m_isJustCreated)
{
ResetCategoryId();
@@ -30,6 +30,11 @@ UserMarkIdStorage::UserMarkIdStorage()
LoadLastTrackId();
LoadLastCategoryId();
}
+
+ m_initialLastBookmarkId = m_lastBookmarkId;
+ m_initialLastTrackId = m_lastTrackId;
+ m_initialLastCategoryId = m_lastCategoryId;
+
LOG(LINFO, ("lastBookmarkId =", m_lastBookmarkId, "lastTrackId =", m_lastTrackId,
"lastCategoryId =", m_lastCategoryId));
}
@@ -47,11 +52,6 @@ UserMark::Type UserMarkIdStorage::GetMarkType(kml::MarkId id)
return static_cast<UserMark::Type>(id >> (sizeof(id) * 8 - kMarkIdTypeBitsCount));
}
-bool UserMarkIdStorage::IsJustCreated() const
-{
- return m_isJustCreated;
-}
-
void UserMarkIdStorage::ResetBookmarkId()
{
m_lastBookmarkId = 0;
@@ -73,6 +73,41 @@ void UserMarkIdStorage::ResetCategoryId()
LOG(LINFO, ("Reset category id"));
}
+bool UserMarkIdStorage::CheckIds(kml::FileData const & fileData) const
+{
+ // File has no ids. Check passed.
+ if (fileData.m_categoryData.m_id == kml::kInvalidMarkGroupId)
+ return true;
+
+ // Storage is just created. Check failed.
+ if (m_isJustCreated)
+ return false;
+
+ // File was created on another device. Check failed.
+ if (fileData.m_deviceId != GetPlatform().UniqueClientId())
+ return false;
+
+ // There are ids of categories, bookmarks or tracks with values
+ // more than last stored maximums. Check failed.
+ if (fileData.m_categoryData.m_id > m_initialLastCategoryId)
+ return false;
+
+ for (auto const & b : fileData.m_bookmarksData)
+ {
+ if (b.m_id > m_initialLastBookmarkId)
+ return false;
+ }
+
+ for (auto const & t : fileData.m_tracksData)
+ {
+ if (t.m_id > m_initialLastTrackId)
+ return false;
+ }
+
+ // No one corner case. Check passed.
+ return true;
+}
+
kml::MarkId UserMarkIdStorage::GetNextUserMarkId(UserMark::Type type)
{
static_assert(UserMark::Type::USER_MARK_TYPES_COUNT <= (1 << kMarkIdTypeBitsCount),
diff --git a/map/user_mark_id_storage.hpp b/map/user_mark_id_storage.hpp
index c23457b99f..9d0a00feab 100644
--- a/map/user_mark_id_storage.hpp
+++ b/map/user_mark_id_storage.hpp
@@ -2,6 +2,8 @@
#include "map/user_mark.hpp"
+#include "kml/types.hpp"
+
#include <atomic>
class UserMarkIdStorage
@@ -11,12 +13,12 @@ public:
static UserMark::Type GetMarkType(kml::MarkId id);
- bool IsJustCreated() const;
-
kml::MarkId GetNextUserMarkId(UserMark::Type type);
kml::TrackId GetNextTrackId();
kml::MarkGroupId GetNextCategoryId();
+ bool CheckIds(kml::FileData const & fileData) const;
+
void ResetBookmarkId();
void ResetTrackId();
void ResetCategoryId();
@@ -37,12 +39,17 @@ private:
bool HasKey(std::string const & name);
- std::atomic<bool> m_isJustCreated;
+ bool m_isJustCreated;
+ //TODO: do we really need atomics here?
std::atomic<uint64_t> m_lastBookmarkId;
std::atomic<uint64_t> m_lastTrackId;
std::atomic<uint64_t> m_lastUserMarkId;
std::atomic<uint64_t> m_lastCategoryId;
+ uint64_t m_initialLastBookmarkId;
+ uint64_t m_initialLastTrackId;
+ uint64_t m_initialLastCategoryId;
+
bool m_testModeEnabled = false;
};