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
path: root/ugc
diff options
context:
space:
mode:
Diffstat (limited to 'ugc')
-rw-r--r--ugc/api.cpp21
-rw-r--r--ugc/api.hpp3
-rw-r--r--ugc/binary/serdes.cpp2
-rw-r--r--ugc/loader.cpp34
-rw-r--r--ugc/loader.hpp22
-rw-r--r--ugc/serdes_json.hpp28
-rw-r--r--ugc/storage.cpp9
-rw-r--r--ugc/storage.hpp2
-rw-r--r--ugc/types.hpp144
-rw-r--r--ugc/ugc.pro3
-rw-r--r--ugc/ugc_tests/serdes_tests.cpp2
-rw-r--r--ugc/ugc_tests/utils.cpp10
-rw-r--r--ugc/ugc_tests/utils.hpp1
13 files changed, 193 insertions, 88 deletions
diff --git a/ugc/api.cpp b/ugc/api.cpp
index 076df47507..523f47fc4d 100644
--- a/ugc/api.cpp
+++ b/ugc/api.cpp
@@ -1,5 +1,7 @@
#include "ugc/api.hpp"
+#include "indexer/feature.hpp"
+
#include "platform/platform.hpp"
#include <chrono>
@@ -9,7 +11,11 @@ using namespace ugc;
namespace ugc
{
-Api::Api(Index const & index, std::string const & filename) : m_index(index), m_storage(filename) {}
+Api::Api(Index const & index, std::string const & filename)
+ : m_storage(filename)
+, m_loader(index)
+{
+}
void Api::GetUGC(FeatureID const & id, UGCCallback callback)
{
@@ -23,17 +29,18 @@ void Api::SetUGCUpdate(FeatureID const & id, UGCUpdate const & ugc)
void Api::GetUGCImpl(FeatureID const & id, UGCCallback callback)
{
- // TODO (@y, @mgsergio): retrieve static UGC
- UGC ugc;
- UGCUpdate update;
-
if (!id.IsValid())
{
- GetPlatform().RunOnGuiThread([ugc, update, callback] { callback(ugc, update); });
+ GetPlatform().RunOnGuiThread([callback] { callback({}, {}); });
return;
}
- // ugc = MakeTestUGC1();
+ UGC ugc;
+ UGCUpdate update;
+
+ m_storage.GetUGCUpdate(id, update);
+ m_loader.GetUGC(id, ugc);
+
GetPlatform().RunOnGuiThread([ugc, update, callback] { callback(ugc, update); });
}
diff --git a/ugc/api.hpp b/ugc/api.hpp
index 4f578ce53e..a9b50777b2 100644
--- a/ugc/api.hpp
+++ b/ugc/api.hpp
@@ -2,6 +2,7 @@
#include "base/worker_thread.hpp"
+#include "ugc/loader.hpp"
#include "ugc/storage.hpp"
#include "ugc/types.hpp"
@@ -28,8 +29,8 @@ private:
void SetUGCUpdateImpl(FeatureID const & id, UGCUpdate const & ugc);
- Index const & m_index;
base::WorkerThread m_thread;
Storage m_storage;
+ Loader m_loader;
};
} // namespace ugc
diff --git a/ugc/binary/serdes.cpp b/ugc/binary/serdes.cpp
index fdecacaff8..b239b0edce 100644
--- a/ugc/binary/serdes.cpp
+++ b/ugc/binary/serdes.cpp
@@ -15,6 +15,8 @@ class BaseCollector
public:
virtual ~BaseCollector() = default;
+ void VisitVarUint(uint32_t, char const * /* name */ = nullptr) {}
+ void VisitVarUint(uint64_t, char const * /* name */ = nullptr) {}
virtual void VisitRating(float const f, char const * /* name */ = nullptr) {}
virtual void operator()(string const & /* s */, char const * /* name */ = nullptr) {}
virtual void operator()(Sentiment const /* sentiment */, char const * /* name */ = nullptr) {}
diff --git a/ugc/loader.cpp b/ugc/loader.cpp
new file mode 100644
index 0000000000..b28d9e3461
--- /dev/null
+++ b/ugc/loader.cpp
@@ -0,0 +1,34 @@
+#include "ugc/loader.hpp"
+
+#include "ugc/types.hpp"
+
+#include "indexer/feature.hpp"
+#include "indexer/index.hpp"
+
+#include "defines.hpp"
+
+namespace ugc
+{
+Loader::Loader(Index const & index) : m_index(index) {}
+
+void Loader::GetUGC(FeatureID const & featureId, UGC & result)
+{
+ UGC ugc;
+ auto const & handle = m_index.GetMwmHandleById(featureId.m_mwmId);
+
+ if (!handle.IsAlive())
+ return;
+
+ auto const & value = *handle.GetValue<MwmValue>();
+
+ if (!value.m_cont.IsExist(UGC_FILE_TAG))
+ return;
+
+ auto readerPtr = value.m_cont.GetReader(UGC_FILE_TAG);
+
+ if (!m_d.Deserialize(*readerPtr.GetPtr(), featureId.m_index, ugc))
+ return;
+
+ result = std::move(ugc);
+}
+} // namespace ugc
diff --git a/ugc/loader.hpp b/ugc/loader.hpp
new file mode 100644
index 0000000000..45e332bd0c
--- /dev/null
+++ b/ugc/loader.hpp
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "ugc/binary/serdes.hpp"
+
+class Index;
+struct FeatureID;
+
+namespace ugc
+{
+struct UGC;
+
+class Loader
+{
+public:
+ Loader(Index const & index);
+ void GetUGC(FeatureID const & featureId, UGC & ugc);
+
+private:
+ Index const & m_index;
+ binary::UGCDeserializer m_d;
+};
+} // namespace ugc
diff --git a/ugc/serdes_json.hpp b/ugc/serdes_json.hpp
index 7fc8f36e01..c850db6cbe 100644
--- a/ugc/serdes_json.hpp
+++ b/ugc/serdes_json.hpp
@@ -73,6 +73,12 @@ public:
ToJSONObject(*m_json, name, d);
}
+ template <typename T>
+ void VisitVarUint(T const & t, char const * name = nullptr)
+ {
+ ToJSONObject(*m_json, name, t);
+ }
+
private:
template <typename Fn>
void NewScopeWith(my::JSONPtr json_object, char const * name, Fn && fn)
@@ -95,20 +101,28 @@ private:
Sink & m_sink;
};
-template <typename Source>
class DeserializerJsonV0
{
public:
DECLARE_EXCEPTION(Exception, RootException);
- DeserializerJsonV0(Source & source) : m_source(source)
+ template <typename Source,
+ typename std::enable_if<
+ !std::is_convertible<Source, std::string>::value, Source>::type * = nullptr>
+ DeserializerJsonV0(Source & source)
{
std::string src(source.Size(), '\0');
source.Read(static_cast<void *>(&src[0]), source.Size());
- m_jsonObject.ParseFrom(src.c_str());
+ m_jsonObject.ParseFrom(src);
m_json = m_jsonObject.get();
}
+ DeserializerJsonV0(std::string const & source)
+ : m_jsonObject(source)
+ , m_json(m_jsonObject.get())
+ {
+ }
+
void operator()(bool & d, char const * name = nullptr) { FromJSONObject(m_json, name, d); }
void operator()(uint8_t & d, char const * name = nullptr) { FromJSONObject(m_json, name, d); }
void operator()(uint32_t & d, char const * name = nullptr) { FromJSONObject(m_json, name, d); }
@@ -118,6 +132,7 @@ public:
{
(*this)(key.m_key, name);
}
+
void operator()(Time & t, char const * name = nullptr)
{
uint32_t d = 0;
@@ -167,6 +182,12 @@ public:
f = static_cast<float>(d);
}
+ template <typename T>
+ void VisitVarUint(T & t, char const * name = nullptr)
+ {
+ FromJSONObject(m_json, name, t);
+ }
+
private:
json_t * SaveContext(char const * name = nullptr)
{
@@ -184,6 +205,5 @@ private:
my::Json m_jsonObject;
json_t * m_json = nullptr;
- Source & m_source;
};
} // namespace ugc
diff --git a/ugc/storage.cpp b/ugc/storage.cpp
index 15fd9babb6..fe966264a7 100644
--- a/ugc/storage.cpp
+++ b/ugc/storage.cpp
@@ -10,12 +10,13 @@ Storage::Storage(std::string const & filename)
Load();
}
-UGCUpdate const * Storage::GetUGCUpdate(FeatureID const & id) const
+void Storage::GetUGCUpdate(FeatureID const & id, UGCUpdate & ugc) const
{
auto const it = m_ugc.find(id);
- if (it != end(m_ugc))
- return &it->second;
- return nullptr;
+ if (it == end(m_ugc))
+ return;
+
+ ugc = it->second;
}
void Storage::SetUGCUpdate(FeatureID const & id, UGCUpdate const & ugc)
diff --git a/ugc/storage.hpp b/ugc/storage.hpp
index 2086dbad15..c6df8c5f67 100644
--- a/ugc/storage.hpp
+++ b/ugc/storage.hpp
@@ -14,7 +14,7 @@ class Storage
public:
explicit Storage(std::string const & filename);
- UGCUpdate const * GetUGCUpdate(FeatureID const & id) const;
+ void GetUGCUpdate(FeatureID const & id, UGCUpdate & ugc) const;
void SetUGCUpdate(FeatureID const & id, UGCUpdate const & ugc);
void Save();
diff --git a/ugc/types.hpp b/ugc/types.hpp
index 2e6f278756..fd60258bba 100644
--- a/ugc/types.hpp
+++ b/ugc/types.hpp
@@ -4,6 +4,7 @@
#include "coding/hex.hpp"
+#include "base/math.hpp"
#include "base/visitor.hpp"
#include <chrono>
@@ -30,14 +31,14 @@ struct TranslationKey
bool operator==(TranslationKey const & rhs) const { return m_key == rhs.m_key; }
bool operator<(TranslationKey const & rhs) const { return m_key < rhs.m_key; }
- friend std::string DebugPrint(TranslationKey const & key)
- {
- return "TranslationKey [ " + key.m_key + " ]";
- }
-
std::string m_key;
};
+std::string DebugPrint(TranslationKey const & key)
+{
+ return "TranslationKey [ " + key.m_key + " ]";
+}
+
enum class Sentiment
{
Positive,
@@ -86,18 +87,18 @@ struct RatingRecord
return m_key == rhs.m_key && m_value == rhs.m_value;
}
- friend std::string DebugPrint(RatingRecord const & ratingRecord)
- {
- std::ostringstream os;
- os << "RatingRecord [ " << DebugPrint(ratingRecord.m_key) << " " << ratingRecord.m_value
- << " ]";
- return os.str();
- }
-
TranslationKey m_key{};
float m_value{};
};
+std::string DebugPrint(RatingRecord const & ratingRecord)
+{
+ std::ostringstream os;
+ os << "RatingRecord [ " << DebugPrint(ratingRecord.m_key) << " " << ratingRecord.m_value
+ << " ]";
+ return os.str();
+}
+
using Ratings = std::vector<RatingRecord>;
struct UID
@@ -110,17 +111,18 @@ struct UID
DECLARE_VISITOR(visitor(m_hi, "hi"), visitor(m_lo, "lo"));
bool operator==(UID const & rhs) const { return m_hi == rhs.m_hi && m_lo == rhs.m_lo; }
- friend std::string DebugPrint(UID const & uid)
- {
- std::ostringstream os;
- os << "UID [ " << uid.ToString() << " ]";
- return os.str();
- }
uint64_t m_hi{};
uint64_t m_lo{};
};
+std::string DebugPrint(UID const & uid)
+{
+ std::ostringstream os;
+ os << "UID [ " << uid.ToString() << " ]";
+ return os.str();
+}
+
using Author = std::string;
struct Text
@@ -132,18 +134,18 @@ struct Text
bool operator==(Text const & rhs) const { return m_lang == rhs.m_lang && m_text == rhs.m_text; }
- friend std::string DebugPrint(Text const & text)
- {
- std::ostringstream os;
- os << "Text [ " << StringUtf8Multilang::GetLangByCode(text.m_lang) << ": " << text.m_text
- << " ]";
- return os.str();
- }
-
std::string m_text;
uint8_t m_lang = StringUtf8Multilang::kDefaultCode;
};
+std::string DebugPrint(Text const & text)
+{
+ std::ostringstream os;
+ os << "Text [ " << StringUtf8Multilang::GetLangByCode(text.m_lang) << ": " << text.m_text
+ << " ]";
+ return os.str();
+}
+
struct Review
{
using ReviewId = uint64_t;
@@ -164,18 +166,6 @@ struct Review
m_rating == rhs.m_rating && m_time == rhs.m_time;
}
- friend std::string DebugPrint(Review const & review)
- {
- std::ostringstream os;
- os << "Review [ ";
- os << "id:" << review.m_id << ", ";
- os << "text:" << DebugPrint(review.m_text) << ", ";
- os << "author:" << review.m_author << ", ";
- os << "rating:" << review.m_rating << ", ";
- os << "days since epoch:" << ToDaysSinceEpoch(review.m_time) << " ]";
- return os.str();
- }
-
ReviewId m_id{};
Text m_text{};
Author m_author{};
@@ -183,6 +173,18 @@ struct Review
Time m_time{};
};
+std::string DebugPrint(Review const & review)
+{
+ std::ostringstream os;
+ os << "Review [ ";
+ os << "id:" << review.m_id << ", ";
+ os << "text:" << DebugPrint(review.m_text) << ", ";
+ os << "author:" << review.m_author << ", ";
+ os << "rating:" << review.m_rating << ", ";
+ os << "days since epoch:" << ToDaysSinceEpoch(review.m_time) << " ]";
+ return os.str();
+}
+
using Reviews = std::vector<Review>;
struct Attribute
@@ -199,49 +201,56 @@ struct Attribute
return m_key == rhs.m_key && m_value == rhs.m_value;
}
- friend std::string DebugPrint(Attribute const & attribute)
- {
- std::ostringstream os;
- os << "Attribute [ key:" << DebugPrint(attribute.m_key)
- << ", value:" << DebugPrint(attribute.m_value) << " ]";
- return os.str();
- }
-
TranslationKey m_key{};
TranslationKey m_value{};
};
+std::string DebugPrint(Attribute const & attribute)
+{
+ std::ostringstream os;
+ os << "Attribute [ key:" << DebugPrint(attribute.m_key)
+ << ", value:" << DebugPrint(attribute.m_value) << " ]";
+ return os.str();
+}
+
struct UGC
{
UGC() = default;
- UGC(Ratings const & records, Reviews const & reviews, float const totalRating, uint32_t votes)
- : m_ratings(records), m_reviews(reviews), m_totalRating(totalRating), m_votes(votes)
+ UGC(Ratings const & records, Reviews const & reviews, float const totalRating, uint32_t basedOn)
+ : m_ratings(records), m_reviews(reviews), m_totalRating(totalRating), m_basedOn(basedOn)
{
}
DECLARE_VISITOR(visitor(m_ratings, "ratings"), visitor(m_reviews, "reviews"),
- visitor.VisitRating(m_totalRating, "totalRating"))
+ visitor.VisitRating(m_totalRating, "total_rating"),
+ visitor.VisitVarUint(m_basedOn, "based_on"))
bool operator==(UGC const & rhs) const
{
- return m_ratings == rhs.m_ratings && m_reviews == rhs.m_reviews;
+ return m_ratings == rhs.m_ratings && m_reviews == rhs.m_reviews &&
+ my::AlmostEqualAbs(m_totalRating, rhs.m_totalRating, 1e-6f) && m_basedOn == rhs.m_basedOn;
}
- friend std::string DebugPrint(UGC const & ugc)
+ bool IsValid() const
{
- std::ostringstream os;
- os << "UGC [ ";
- os << "records:" << ::DebugPrint(ugc.m_ratings) << ", ";
- os << "reviews:" << ::DebugPrint(ugc.m_reviews) << " ]";
- return os.str();
+ return (!m_ratings.empty() || !m_reviews.empty()) && m_totalRating > 1e-6 && m_basedOn > 0;
}
Ratings m_ratings;
Reviews m_reviews;
float m_totalRating{};
- uint32_t m_votes{};
+ uint32_t m_basedOn{};
};
+std::string DebugPrint(UGC const & ugc)
+{
+ std::ostringstream os;
+ os << "UGC [ ";
+ os << "records:" << ::DebugPrint(ugc.m_ratings) << ", ";
+ os << "reviews:" << ::DebugPrint(ugc.m_reviews) << " ]";
+ return os.str();
+}
+
struct UGCUpdate
{
UGCUpdate() = default;
@@ -257,14 +266,9 @@ struct UGCUpdate
return m_ratings == rhs.m_ratings && m_text == rhs.m_text && m_time == rhs.m_time;
}
- friend std::string DebugPrint(UGCUpdate const & ugcUpdate)
+ bool IsValid() const
{
- std::ostringstream os;
- os << "UGCUpdate [ ";
- os << "records:" << ::DebugPrint(ugcUpdate.m_ratings) << ", ";
- os << "text:" << DebugPrint(ugcUpdate.m_text) << ", ";
- os << "days since epoch:" << ToDaysSinceEpoch(ugcUpdate.m_time) << " ]";
- return os.str();
+ return (!m_ratings.empty() || !m_text.m_text.empty()) && m_time != Time();
}
Ratings m_ratings;
@@ -272,6 +276,16 @@ struct UGCUpdate
Time m_time{};
};
+std::string DebugPrint(UGCUpdate const & ugcUpdate)
+{
+ std::ostringstream os;
+ os << "UGCUpdate [ ";
+ os << "records:" << ::DebugPrint(ugcUpdate.m_ratings) << ", ";
+ os << "text:" << DebugPrint(ugcUpdate.m_text) << ", ";
+ os << "days since epoch:" << ToDaysSinceEpoch(ugcUpdate.m_time) << " ]";
+ return os.str();
+}
+
struct ReviewFeedback
{
ReviewFeedback() = default;
diff --git a/ugc/ugc.pro b/ugc/ugc.pro
index 3142108058..a08da10f90 100644
--- a/ugc/ugc.pro
+++ b/ugc/ugc.pro
@@ -15,11 +15,14 @@ HEADERS += \
binary/serdes.hpp \
binary/ugc_holder.hpp \
binary/visitors.hpp \
+ loader.hpp \
serdes.hpp \
+ serdes_json.hpp \
storage.hpp \
types.hpp \
SOURCES += \
api.cpp \
binary/serdes.cpp \
+ loader.cpp \
storage.cpp \
diff --git a/ugc/ugc_tests/serdes_tests.cpp b/ugc/ugc_tests/serdes_tests.cpp
index 6cdc967a7d..b3f5c0154f 100644
--- a/ugc/ugc_tests/serdes_tests.cpp
+++ b/ugc/ugc_tests/serdes_tests.cpp
@@ -22,7 +22,7 @@ using Buffer = vector<uint8_t>;
using ToBin = Serializer<MemWriter<Buffer>>;
using FromBin = DeserializerV0<ReaderSource<MemReader>>;
using ToJson = SerializerJson<MemWriter<Buffer>>;
-using FromJson = DeserializerJsonV0<ReaderSource<MemReader>>;
+using FromJson = DeserializerJsonV0;
Ratings GetTestRating()
{
diff --git a/ugc/ugc_tests/utils.cpp b/ugc/ugc_tests/utils.cpp
index 0693173410..11b178df42 100644
--- a/ugc/ugc_tests/utils.cpp
+++ b/ugc/ugc_tests/utils.cpp
@@ -19,13 +19,13 @@ UGC MakeTestUGC1(Time now)
Reviews reviews;
reviews.emplace_back(20 /* id */, Text("Damn good coffee", StringUtf8Multilang::kEnglishCode),
- Author(UID(987654321 /* hi */, 123456789 /* lo */), "Cole"),
+ Author("Cole"),
5.0 /* rating */, FromDaysAgo(now, 10));
reviews.emplace_back(
67812 /* id */, Text("Clean place, reasonably priced", StringUtf8Multilang::kDefaultCode),
- Author(UID(0 /* hi */, 315 /* lo */), "Cooper"), 5.0 /* rating */, FromDaysAgo(now, 1));
+ Author("Cooper"), 5.0 /* rating */, FromDaysAgo(now, 1));
- return UGC(records, reviews, 4.5 /* rating */);
+ return UGC(records, reviews, 4.5 /* rating */, 4000000000 /* votes */);
}
UGC MakeTestUGC2(Time now)
@@ -38,9 +38,9 @@ UGC MakeTestUGC2(Time now)
vector<Review> reviews;
reviews.emplace_back(
119 /* id */, Text("This pie's so good it is a crime", StringUtf8Multilang::kDefaultCode),
- Author(UID(0 /* hi */, 315 /* lo */), "Cooper"), 5.0 /* rating */, FromDaysAgo(now, 1));
+ Author("Cooper"), 5.0 /* rating */, FromDaysAgo(now, 1));
- return UGC(records, reviews, 5.0 /* rating */);
+ return UGC(records, reviews, 5.0 /* rating */, 1 /* votes */);
}
UGCUpdate MakeTestUGCUpdate(Time now)
diff --git a/ugc/ugc_tests/utils.hpp b/ugc/ugc_tests/utils.hpp
index 82cb5b8588..cc4507bb8c 100644
--- a/ugc/ugc_tests/utils.hpp
+++ b/ugc/ugc_tests/utils.hpp
@@ -6,5 +6,6 @@ namespace ugc
{
UGC MakeTestUGC1(Time now = Clock::now());
UGC MakeTestUGC2(Time now = Clock::now());
+
UGCUpdate MakeTestUGCUpdate(Time now = Clock::now());
} // namespace ugc