diff --git a/map/gps_track_collection.cpp b/map/gps_track_collection.cpp index 374245da67..005aed34ce 100644 --- a/map/gps_track_collection.cpp +++ b/map/gps_track_collection.cpp @@ -31,6 +31,8 @@ private: } // namespace +size_t const GpsTrackCollection::kInvalidId = numeric_limits::max(); + GpsTrackCollection::GpsTrackCollection(size_t maxSize, hours duration) : m_maxSize(maxSize) , m_duration(duration) diff --git a/map/gps_track_collection.hpp b/map/gps_track_collection.hpp index 093002051b..b96b51092d 100644 --- a/map/gps_track_collection.hpp +++ b/map/gps_track_collection.hpp @@ -11,7 +11,7 @@ class GpsTrackCollection final { public: - static size_t const kInvalidId = numeric_limits::max(); + static size_t const kInvalidId; // = numeric_limits::max(); using TItem = location::GpsTrackInfo; @@ -25,7 +25,7 @@ public: /// @param poppedIds - output, which contains range of identifiers popped items or /// pair(kInvalidId,kInvalidId) if nothing was removed /// @returns the item unique identifier or kInvalidId if point has incorrect time. - size_t Add(TItem const & items, pair & poppedIds); + size_t Add(TItem const & item, pair & poppedIds); /// Adds set of new points in the collection. /// @param items - set of items to be added. @@ -33,7 +33,7 @@ public: /// pair(kInvalidId,kInvalidId) if nothing was removed /// @returns range of identifiers of added items or pair(kInvalidId,kInvalidId) if nothing was added /// @note items which does not conform to timestamp sequence, is not added. - pair Add(vector const & item, pair & poppedIds); + pair Add(vector const & items, pair & poppedIds); /// Get current duration in hours /// @returns current duration in hours diff --git a/map/map_tests/gps_track_collection_test.cpp b/map/map_tests/gps_track_collection_test.cpp new file mode 100644 index 0000000000..494953bb81 --- /dev/null +++ b/map/map_tests/gps_track_collection_test.cpp @@ -0,0 +1,212 @@ +#include "testing/testing.hpp" + +#include "map/gps_track_collection.hpp" + +#include "std/map.hpp" + +namespace +{ + +location::GpsTrackInfo MakeGpsTrackInfo(double timestamp, ms::LatLon const & ll, double speed) +{ + location::GpsTrackInfo info; + info.m_timestamp = timestamp; + info.m_speed = speed; + info.m_latitude = ll.lat; + info.m_longitude = ll.lon; + return info; +} + +} // namespace + +UNIT_TEST(GpsTrackCollection_Simple) +{ + double const timestamp = system_clock::to_time_t(system_clock::now()); + + GpsTrackCollection collection(100, hours(24)); + + map data; + + TEST_EQUAL(100, collection.GetMaxSize(), ()); + + for (size_t i = 0; i < 50; ++i) + { + auto info = MakeGpsTrackInfo(timestamp + i, ms::LatLon(-90 + i, -180 + i), i); + pair poppedId; + size_t addedId = collection.Add(info, poppedId); + TEST_EQUAL(addedId, i, ()); + TEST_EQUAL(poppedId.first, GpsTrackCollection::kInvalidId, ()); + TEST_EQUAL(poppedId.second, GpsTrackCollection::kInvalidId, ()); + data[addedId] = info; + } + + TEST_EQUAL(50, collection.GetSize(), ()); + + collection.ForEach([&data](location::GpsTrackInfo const & info, size_t id)->bool + { + TEST(data.end() != data.find(id), ()); + location::GpsTrackInfo const & originInfo = data[id]; + TEST_EQUAL(info.m_latitude, originInfo.m_latitude, ()); + TEST_EQUAL(info.m_longitude, originInfo.m_longitude, ()); + TEST_EQUAL(info.m_speed, originInfo.m_speed, ()); + TEST_EQUAL(info.m_timestamp, originInfo.m_timestamp, ()); + return true; + }); + + auto res = collection.Clear(); + TEST_EQUAL(res.first, 0, ()); + TEST_EQUAL(res.second, 49, ()); + + TEST_EQUAL(0, collection.GetSize(), ()); +} + +UNIT_TEST(GpsTrackCollection_PopByTimestamp) +{ + double const timestamp = system_clock::to_time_t(system_clock::now()); + double const timestamp_1h = timestamp + 60 * 60; + double const timestamp_25h = timestamp + 25 * 60 * 60; + + GpsTrackCollection collection(100, hours(24)); + + pair poppedId; + size_t addedId = collection.Add(MakeGpsTrackInfo(timestamp, ms::LatLon(-90, -180), 1), poppedId); + TEST_EQUAL(addedId, 0, ()); + TEST_EQUAL(poppedId.first, GpsTrackCollection::kInvalidId, ()); + TEST_EQUAL(poppedId.second, GpsTrackCollection::kInvalidId, ()); + + addedId = collection.Add(MakeGpsTrackInfo(timestamp_1h, ms::LatLon(90, 180), 2), poppedId); + TEST_EQUAL(addedId, 1, ()); + TEST_EQUAL(poppedId.first, GpsTrackCollection::kInvalidId, ()); + TEST_EQUAL(poppedId.second, GpsTrackCollection::kInvalidId, ()); + + TEST_EQUAL(2, collection.GetSize(), ()); + + auto lastInfo = MakeGpsTrackInfo(timestamp_25h, ms::LatLon(45, 60), 3); + addedId = collection.Add(lastInfo, poppedId); + TEST_EQUAL(addedId, 2, ()); + TEST_EQUAL(poppedId.first, 0, ()); + TEST_EQUAL(poppedId.second, 1, ()); + + TEST_EQUAL(1, collection.GetSize(), ()); + + collection.ForEach([&](location::GpsTrackInfo const & info, size_t id)->bool + { + TEST_EQUAL(id, 2, ()) + TEST_EQUAL(info.m_latitude, lastInfo.m_latitude, ()); + TEST_EQUAL(info.m_longitude, lastInfo.m_longitude, ()); + TEST_EQUAL(info.m_speed, lastInfo.m_speed, ()); + TEST_EQUAL(info.m_timestamp, lastInfo.m_timestamp, ()); + return true; + }); + + auto res = collection.Clear(); + TEST_EQUAL(res.first, 2, ()); + TEST_EQUAL(res.second, 2, ()); + + TEST_EQUAL(0, collection.GetSize(), ()); +} + +UNIT_TEST(GpsTrackCollection_PopByCount) +{ + double const timestamp = system_clock::to_time_t(system_clock::now()); + + GpsTrackCollection collection(100, hours(24)); + + map data; + + TEST_EQUAL(100, collection.GetMaxSize(), ()); + + for (size_t i = 0; i < 100; ++i) + { + auto info = MakeGpsTrackInfo(timestamp + i, ms::LatLon(-90 + i, -180 + i), i); + pair poppedId; + size_t addedId = collection.Add(info, poppedId); + TEST_EQUAL(addedId, i, ()); + TEST_EQUAL(poppedId.first, GpsTrackCollection::kInvalidId, ()); + TEST_EQUAL(poppedId.second, GpsTrackCollection::kInvalidId, ()); + data[addedId] = info; + } + + TEST_EQUAL(100, collection.GetSize(), ()); + + auto info = MakeGpsTrackInfo(timestamp + 100, ms::LatLon(45, 60), 110); + pair poppedId; + size_t addedId = collection.Add(info, poppedId); + TEST_EQUAL(addedId, 100, ()); + TEST_EQUAL(poppedId.first, 0, ()); + TEST_EQUAL(poppedId.second, 0, ()); + data[addedId] = info; + + TEST_EQUAL(100, collection.GetSize(), ()); + + data.erase(0); + + collection.ForEach([&data](location::GpsTrackInfo const & info, size_t id)->bool + { + TEST(data.end() != data.find(id), ()); + location::GpsTrackInfo const & originInfo = data[id]; + TEST_EQUAL(info.m_latitude, originInfo.m_latitude, ()); + TEST_EQUAL(info.m_longitude, originInfo.m_longitude, ()); + TEST_EQUAL(info.m_speed, originInfo.m_speed, ()); + TEST_EQUAL(info.m_timestamp, originInfo.m_timestamp, ()); + return true; + }); + + auto res = collection.Clear(); + TEST_EQUAL(res.first, 1, ()); + TEST_EQUAL(res.second, 100, ()); + + TEST_EQUAL(0, collection.GetSize(), ()); +} + +UNIT_TEST(GpsTrackCollection_PopByTimestamp2) +{ + double const timestamp = 0; + double const timestamp_12h = timestamp + 12 * 60 * 60; + double const timestamp_35h = timestamp + 35 * 60 * 60; + + GpsTrackCollection collection(1000, hours(24)); + + TEST_EQUAL(1000, collection.GetMaxSize(), ()); + + for (size_t i = 0; i < 500; ++i) + { + auto info = MakeGpsTrackInfo(timestamp + i, ms::LatLon(-90 + i, -180 + i), i); + pair poppedId; + size_t addedId = collection.Add(info, poppedId); + TEST_EQUAL(addedId, i, ()); + TEST_EQUAL(poppedId.first, GpsTrackCollection::kInvalidId, ()); + TEST_EQUAL(poppedId.second, GpsTrackCollection::kInvalidId, ()); + } + + auto time = collection.GetTimestampRange(); + + TEST_EQUAL(500, collection.GetSize(), ()); + + for (size_t i = 0; i < 500; ++i) + { + auto info = MakeGpsTrackInfo(timestamp_12h + i, ms::LatLon(-90 + i, -180 + i), i); + pair poppedId; + size_t addedId = collection.Add(info, poppedId); + TEST_EQUAL(addedId, 500 + i, ()); + TEST_EQUAL(poppedId.first, GpsTrackCollection::kInvalidId, ()); + TEST_EQUAL(poppedId.second, GpsTrackCollection::kInvalidId, ()); + } + + time = collection.GetTimestampRange(); + + TEST_EQUAL(1000, collection.GetSize(), ()); + + auto info = MakeGpsTrackInfo(timestamp_35h, ms::LatLon(45, 60), 110); + pair poppedId; + size_t addedId = collection.Add(info, poppedId); + TEST_EQUAL(addedId, 1000, ()); + TEST_EQUAL(poppedId.first, 0, ()); + TEST_EQUAL(poppedId.second, 499, ()); + + auto res = collection.Clear(); + TEST_EQUAL(res.first, 500, ()); + TEST_EQUAL(res.second, 1000, ()); + + TEST_EQUAL(0, collection.GetSize(), ()); +} diff --git a/map/map_tests/map_tests.pro b/map/map_tests/map_tests.pro index be6b5a263c..9ddcc3d386 100644 --- a/map/map_tests/map_tests.pro +++ b/map/map_tests/map_tests.pro @@ -32,6 +32,7 @@ SOURCES += \ ge0_parser_tests.cpp \ geourl_test.cpp \ gps_track_container_test.cpp \ + gps_track_collection_test.cpp \ kmz_unarchive_test.cpp \ mwm_url_tests.cpp \