diff options
author | Sergey Magidovich <mgsergio@mapswithme.com> | 2016-02-19 16:46:59 +0300 |
---|---|---|
committer | Sergey Yershov <yershov@corp.mail.ru> | 2016-03-23 16:45:27 +0300 |
commit | 060374379265ae5dc00166dc21391f2f12972a2a (patch) | |
tree | cb76bf7238da8a7d79d9044e82d86fe5594ce10d /platform | |
parent | 7f050eb375c206d01960673c550e21db7c62d392 (diff) |
Store seconds since epoch in mwm as version.
Diffstat (limited to 'platform')
-rw-r--r-- | platform/local_country_file_utils.cpp | 4 | ||||
-rw-r--r-- | platform/mwm_version.cpp | 60 | ||||
-rw-r--r-- | platform/mwm_version.hpp | 26 | ||||
-rw-r--r-- | platform/platform_tests/mwm_version_test.cpp | 62 | ||||
-rw-r--r-- | platform/platform_tests/platform_tests.pro | 1 | ||||
-rw-r--r-- | platform/platform_tests_support/scoped_mwm.cpp | 2 |
6 files changed, 133 insertions, 22 deletions
diff --git a/platform/local_country_file_utils.cpp b/platform/local_country_file_utils.cpp index e23f3a7e5c..7e6a0a56b3 100644 --- a/platform/local_country_file_utils.cpp +++ b/platform/local_country_file_utils.cpp @@ -270,8 +270,8 @@ void FindAllLocalMapsAndCleanup(int64_t latestVersion, string const & dataDir, platform.GetReader(file + DATA_FILE_EXTENSION, GetSpecialFilesSearchScope())); // Assume that empty path means the resource file. - LocalCountryFile worldFile(string(), CountryFile(file), - version::ReadVersionTimestamp(reader)); + LocalCountryFile worldFile{string(), CountryFile(file), + version::ReadVersionDate(reader)}; worldFile.m_files = MapOptions::Map; if (i != localFiles.end()) { diff --git a/platform/mwm_version.cpp b/platform/mwm_version.cpp index d5acde1b16..f3dc45fda6 100644 --- a/platform/mwm_version.cpp +++ b/platform/mwm_version.cpp @@ -5,16 +5,42 @@ #include "coding/varint.hpp" #include "coding/writer.hpp" +#include "base/assert.hpp" +#include "base/gmtime.hpp" +#include "base/string_utils.hpp" +#include "base/timegm.hpp" #include "base/timer.hpp" #include "defines.hpp" -#include "std/ctime.hpp" +#include "std/array.hpp" namespace version { namespace { +uint64_t VersionToSecondsSinceEpoch(uint32_t version) +{ + auto constexpr partsCount = 3; + // From left to right YY MM DD. + array<int, partsCount> parts{}; // Initialize with zeros. + for (auto i = partsCount - 1; i >= 0; --i) + { + parts[i] = version % 100; + version /= 100; + } + ASSERT_EQUAL(version, 0, ("Version is too big.")); + + ASSERT_LESS_OR_EQUAL(parts[1], 12, ("Month should be in range [1, 12]")); + ASSERT_LESS_OR_EQUAL(parts[2], 31, ("Day should be in range [1, 31]")); + + std::tm tm{}; + tm.tm_year = parts[0] + 100; + tm.tm_mon = parts[1] - 1; + tm.tm_mday = parts[2]; + + return my::TimeTToSecondsSinceEpoch(base::TimeGM(tm)); +} char const MWM_PROLOG[] = "MWM"; @@ -27,29 +53,39 @@ void ReadVersionT(TSource & src, MwmVersion & version) if (strcmp(prolog, MWM_PROLOG) != 0) { - version.format = Format::v2; - version.timestamp = - my::GenerateTimestamp(2011 - 1900 /* number of years since 1900 */, - 10 /* number of month since January */, 1 /* month day */); + version.SetFormat(Format::v2); + version.SetSecondsSinceEpoch(VersionToSecondsSinceEpoch(111101)); return; } // Read format value "as-is". It's correctness will be checked later // with the correspondent return value. - version.format = static_cast<Format>(ReadVarUint<uint32_t>(src)); - version.timestamp = ReadVarUint<uint32_t>(src); + version.SetFormat(static_cast<Format>(ReadVarUint<uint32_t>(src))); + if (version.GetFormat() < Format::v8) + version.SetSecondsSinceEpoch(VersionToSecondsSinceEpoch(ReadVarUint<uint64_t>(src))); + else + version.SetSecondsSinceEpoch(ReadVarUint<uint32_t>(src)); } } // namespace -MwmVersion::MwmVersion() : format(Format::unknownFormat), timestamp(0) {} +uint32_t MwmVersion::GetVersion() const +{ + auto const tm = my::GmTime(my::SecondsSinceEpochToTimeT(m_secondsSinceEpoch)); + return my::GenerateYYMMDD(tm.tm_year, tm.tm_mon, tm.tm_mday); +} + +string DebugPrint(Format f) +{ + return "v" + strings::to_string(static_cast<uint32_t>(f) + 1); +} -void WriteVersion(Writer & w, uint32_t versionDate) +void WriteVersion(Writer & w, uint64_t secondsSinceEpoch) { w.Write(MWM_PROLOG, ARRAY_SIZE(MWM_PROLOG)); // write inner data version WriteVarUint(w, static_cast<uint32_t>(Format::lastFormat)); - WriteVarUint(w, versionDate); + WriteVarUint(w, secondsSinceEpoch); } void ReadVersion(ReaderSrc & src, MwmVersion & version) { ReadVersionT(src, version); } @@ -65,13 +101,13 @@ bool ReadVersion(FilesContainerR const & container, MwmVersion & version) return true; } -uint32_t ReadVersionTimestamp(ModelReaderPtr const & reader) +uint32_t ReadVersionDate(ModelReaderPtr const & reader) { MwmVersion version; if (!ReadVersion(FilesContainerR(reader), version)) return 0; - return version.timestamp; + return version.GetVersion(); } bool IsSingleMwm(int64_t version) diff --git a/platform/mwm_version.hpp b/platform/mwm_version.hpp index db6870f950..0f18e0b74d 100644 --- a/platform/mwm_version.hpp +++ b/platform/mwm_version.hpp @@ -1,6 +1,7 @@ #pragma once #include "std/cstdint.hpp" +#include "std/string.hpp" class FilesContainerR; class ReaderSrc; @@ -19,20 +20,31 @@ enum class Format v5, // July 2015 (feature id is the index in vector now). v6, // October 2015 (offsets vector is in mwm now). v7, // November 2015 (supply different search index formats). - v8, // January 2016 (long strings in metadata). + v8, // February 2016 (long strings in metadata; store seconds since epoch in MwmVersion). lastFormat = v8 }; -struct MwmVersion +string DebugPrint(Format f); + +class MwmVersion { - MwmVersion(); +public: + Format GetFormat() const { return m_format; } + uint64_t GetSecondsSinceEpoch() const { return m_secondsSinceEpoch; } + /// \return version as YYMMDD. + uint32_t GetVersion() const; + + void SetFormat(Format format) { m_format = format; } + void SetSecondsSinceEpoch(uint64_t secondsSinceEpoch) { m_secondsSinceEpoch = secondsSinceEpoch; } - Format format; - uint32_t timestamp; +private: + /// Data layout format in mwm file. + Format m_format{Format::unknownFormat}; + uint64_t m_secondsSinceEpoch{0}; }; /// Writes latest format and current timestamp to the writer. -void WriteVersion(Writer & w, uint32_t versionDate); +void WriteVersion(Writer & w, uint64_t secondsSinceEpoch); /// Reads mwm version from src. void ReadVersion(ReaderSrc & src, MwmVersion & version); @@ -43,7 +55,7 @@ void ReadVersion(ReaderSrc & src, MwmVersion & version); bool ReadVersion(FilesContainerR const & container, MwmVersion & version); /// Helper function that is used in FindAllLocalMaps. -uint32_t ReadVersionTimestamp(ModelReaderPtr const & reader); +uint32_t ReadVersionDate(ModelReaderPtr const & reader); /// \returns true if version is version of an mwm which was generated after small mwm update. /// This means it contains routing file as well. diff --git a/platform/platform_tests/mwm_version_test.cpp b/platform/platform_tests/mwm_version_test.cpp new file mode 100644 index 0000000000..3acc598a2e --- /dev/null +++ b/platform/platform_tests/mwm_version_test.cpp @@ -0,0 +1,62 @@ +#include "testing/testing.hpp" + +#include "coding/reader_wrapper.hpp" +#include "coding/varint.hpp" +#include "coding/writer.hpp" + +#include "platform/mwm_version.hpp" + +#include "std/string.hpp" + +namespace +{ +string WriteMwmVersion(version::Format const format, uint64_t const version) +{ + string data; + MemWriter<string> writer(data); + WriterSink<MemWriter<string>> sink(writer); + + char const prolog[] = "MWM"; + sink.Write(prolog, ARRAY_SIZE(prolog)); + + WriteVarUint(sink, static_cast<uint32_t>(format)); + WriteVarUint(sink, version); + + return data; +} + +version::MwmVersion ReadMwmVersion(string const & data) +{ + MemReader reader(data.data(), data.size()); + ReaderSrc source(reader); + + version::MwmVersion version; + version::ReadVersion(source, version); + + return version; +} +} // namespace + +UNIT_TEST(MwmVersion_OldFormat) +{ + auto const secondsSinceEpoch = 1455235200; // 160212 + auto const dataVersion = 160212; + // Before Format::v8 there was a data version written to mwm. + auto const data = WriteMwmVersion(version::Format::v7, dataVersion); + auto const mwmVersion = ReadMwmVersion(data); + TEST_EQUAL(mwmVersion.GetSecondsSinceEpoch(), secondsSinceEpoch, ()); + TEST_EQUAL(mwmVersion.GetFormat(), version::Format::v7, ()); + TEST_EQUAL(mwmVersion.GetVersion(), dataVersion, ()); +} + +UNIT_TEST(MwmVersion_NewFormat) +{ + auto const secondsSinceEpoch = 1455870947; // 160219 + auto const dataVersion = 160219; + // After Format::v8 seconds since epoch are stored in mwm. + auto const data = WriteMwmVersion(version::Format::v8, secondsSinceEpoch); + auto const mwmVersion = ReadMwmVersion(data); + TEST_EQUAL(mwmVersion.GetSecondsSinceEpoch(), secondsSinceEpoch, ()); + TEST_EQUAL(mwmVersion.GetFormat(), version::Format::v8, ()); + TEST_EQUAL(mwmVersion.GetVersion(), dataVersion, ()); +} diff --git a/platform/platform_tests/platform_tests.pro b/platform/platform_tests/platform_tests.pro index 2047466119..af6ffa5709 100644 --- a/platform/platform_tests/platform_tests.pro +++ b/platform/platform_tests/platform_tests.pro @@ -32,4 +32,5 @@ SOURCES += \ local_country_file_tests.cpp \ location_test.cpp \ measurement_tests.cpp \ + mwm_version_test.cpp \ platform_test.cpp \ diff --git a/platform/platform_tests_support/scoped_mwm.cpp b/platform/platform_tests_support/scoped_mwm.cpp index f4a3b1fe1e..c7bc9e413f 100644 --- a/platform/platform_tests_support/scoped_mwm.cpp +++ b/platform/platform_tests_support/scoped_mwm.cpp @@ -26,7 +26,7 @@ ScopedMwm::ScopedMwm(string const & relativePath) : m_file(relativePath, "") // Each writer must be in it's own scope to avoid conflicts on the final write. { FileWriter versionWriter = container.GetWriter(VERSION_FILE_TAG); - version::WriteVersion(versionWriter, my::TodayAsYYMMDD()); + version::WriteVersion(versionWriter, my::SecondsSinceEpoch()); } FileWriter w = container.GetWriter(HEADER_FILE_TAG); |