Store StickerPhotoSize in unique_ptr to optimize Photo size.

This commit is contained in:
levlam 2023-01-23 00:57:40 +03:00
parent 201af22ef2
commit 345709f1ff
6 changed files with 54 additions and 42 deletions

View File

@ -267,21 +267,18 @@ static tl_object_ptr<td_api::animatedChatPhoto> get_animated_chat_photo_object(F
} }
static tl_object_ptr<td_api::chatPhotoSticker> get_chat_photo_sticker_object( static tl_object_ptr<td_api::chatPhotoSticker> get_chat_photo_sticker_object(
const StickerPhotoSize &sticker_photo_size) { const unique_value_ptr<StickerPhotoSize> &sticker_photo_size) {
if (sticker_photo_size == nullptr) {
return nullptr;
}
td_api::object_ptr<td_api::ChatPhotoStickerType> type; td_api::object_ptr<td_api::ChatPhotoStickerType> type;
switch (sticker_photo_size.type) { switch (sticker_photo_size->type) {
case StickerPhotoSize::Type::Sticker: case StickerPhotoSize::Type::Sticker:
if (!sticker_photo_size.sticker_set_id.is_valid()) { type = td_api::make_object<td_api::chatPhotoStickerTypeRegularOrMask>(sticker_photo_size->sticker_set_id.get(),
return nullptr; sticker_photo_size->sticker_id);
}
type = td_api::make_object<td_api::chatPhotoStickerTypeRegularOrMask>(sticker_photo_size.sticker_set_id.get(),
sticker_photo_size.sticker_id);
break; break;
case StickerPhotoSize::Type::CustomEmoji: case StickerPhotoSize::Type::CustomEmoji:
if (!sticker_photo_size.custom_emoji_id.is_valid()) { type = td_api::make_object<td_api::chatPhotoStickerTypeCustomEmoji>(sticker_photo_size->custom_emoji_id.get());
return nullptr;
}
type = td_api::make_object<td_api::chatPhotoStickerTypeCustomEmoji>(sticker_photo_size.custom_emoji_id.get());
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
@ -302,7 +299,7 @@ static tl_object_ptr<td_api::chatPhotoSticker> get_chat_photo_sticker_object(
UNREACHABLE(); UNREACHABLE();
return nullptr; return nullptr;
} }
}(sticker_photo_size.background_colors); }(sticker_photo_size->background_colors);
return td_api::make_object<td_api::chatPhotoSticker>(std::move(type), std::move(background_fill)); return td_api::make_object<td_api::chatPhotoSticker>(std::move(type), std::move(background_fill));
} }
@ -382,12 +379,14 @@ Photo get_photo(Td *td, tl_object_ptr<telegram_api::photo> &&photo, DialogId own
continue; continue;
} }
animation.visit(overloaded( animation.visit(overloaded(
[&](const AnimationSize &animation_size) { [&](AnimationSize &&animation_size) {
if (animation_size.type != 0 && animation_size.dimensions.width == animation_size.dimensions.height) { if (animation_size.type != 0 && animation_size.dimensions.width == animation_size.dimensions.height) {
res.animations.push_back(std::move(animation_size)); res.animations.push_back(std::move(animation_size));
} }
}, },
[&](const StickerPhotoSize &sticker_photo_size) { res.sticker_photo_size = std::move(sticker_photo_size); })); [&](unique_ptr<StickerPhotoSize> &&sticker_photo_size) {
res.sticker_photo_size = std::move(sticker_photo_size);
}));
} }
return res; return res;
@ -636,8 +635,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const Photo &photo) {
if (!photo.animations.empty()) { if (!photo.animations.empty()) {
string_builder << ", animations = " << format::as_array(photo.animations); string_builder << ", animations = " << format::as_array(photo.animations);
} }
if (photo.sticker_photo_size.custom_emoji_id.is_valid()) { if (photo.sticker_photo_size != nullptr) {
string_builder << ", custom emoji size = " << photo.sticker_photo_size; string_builder << ", sticker = " << *photo.sticker_photo_size;
} }
return string_builder << ']'; return string_builder << ']';
} }

View File

@ -21,6 +21,7 @@
#include "td/utils/common.h" #include "td/utils/common.h"
#include "td/utils/MovableValue.h" #include "td/utils/MovableValue.h"
#include "td/utils/StringBuilder.h" #include "td/utils/StringBuilder.h"
#include "td/utils/unique_value_ptr.h"
namespace td { namespace td {
@ -47,7 +48,7 @@ struct Photo {
vector<AnimationSize> animations; vector<AnimationSize> animations;
StickerPhotoSize sticker_photo_size; unique_value_ptr<StickerPhotoSize> sticker_photo_size;
bool has_stickers = false; bool has_stickers = false;
vector<FileId> sticker_file_ids; vector<FileId> sticker_file_ids;

View File

@ -72,7 +72,7 @@ template <class StorerT>
void store(const Photo &photo, StorerT &storer) { void store(const Photo &photo, StorerT &storer) {
bool has_minithumbnail = !photo.minithumbnail.empty(); bool has_minithumbnail = !photo.minithumbnail.empty();
bool has_animations = !photo.animations.empty(); bool has_animations = !photo.animations.empty();
bool has_sticker_photo_size = photo.sticker_photo_size.custom_emoji_id.is_valid(); bool has_sticker_photo_size = photo.sticker_photo_size != nullptr;
BEGIN_STORE_FLAGS(); BEGIN_STORE_FLAGS();
STORE_FLAG(photo.has_stickers); STORE_FLAG(photo.has_stickers);
STORE_FLAG(has_minithumbnail); STORE_FLAG(has_minithumbnail);

View File

@ -261,10 +261,9 @@ Variant<PhotoSize, string> get_photo_size(FileManager *file_manager, PhotoSizeSo
return std::move(res); return std::move(res);
} }
Variant<AnimationSize, StickerPhotoSize> get_animation_size(Td *td, PhotoSizeSource source, int64 id, int64 access_hash, Variant<AnimationSize, unique_ptr<StickerPhotoSize>> get_animation_size(
std::string file_reference, DcId dc_id, Td *td, PhotoSizeSource source, int64 id, int64 access_hash, std::string file_reference, DcId dc_id,
DialogId owner_dialog_id, DialogId owner_dialog_id, tl_object_ptr<telegram_api::VideoSize> &&size_ptr) {
tl_object_ptr<telegram_api::VideoSize> &&size_ptr) {
CHECK(size_ptr != nullptr); CHECK(size_ptr != nullptr);
switch (size_ptr->get_id()) { switch (size_ptr->get_id()) {
case telegram_api::videoSize::ID: { case telegram_api::videoSize::ID: {
@ -298,33 +297,33 @@ Variant<AnimationSize, StickerPhotoSize> get_animation_size(Td *td, PhotoSizeSou
} }
case telegram_api::videoSizeEmojiMarkup::ID: { case telegram_api::videoSizeEmojiMarkup::ID: {
auto size = move_tl_object_as<telegram_api::videoSizeEmojiMarkup>(size_ptr); auto size = move_tl_object_as<telegram_api::videoSizeEmojiMarkup>(size_ptr);
StickerPhotoSize result; auto result = make_unique<StickerPhotoSize>();
result.type = StickerPhotoSize::Type::CustomEmoji; result->type = StickerPhotoSize::Type::CustomEmoji;
result.custom_emoji_id = CustomEmojiId(size->emoji_id_); result->custom_emoji_id = CustomEmojiId(size->emoji_id_);
result.background_colors = std::move(size->background_colors_); result->background_colors = std::move(size->background_colors_);
if (!result.custom_emoji_id.is_valid() || result.background_colors.empty() || if (!result->custom_emoji_id.is_valid() || result->background_colors.empty() ||
result.background_colors.size() > 4) { result->background_colors.size() > 4) {
LOG(ERROR) << "Receive invalid " << result; LOG(ERROR) << "Receive invalid " << *result;
return {}; return {};
} }
for (auto &color : result.background_colors) { for (auto &color : result->background_colors) {
color &= 0xFFFFFF; color &= 0xFFFFFF;
} }
return std::move(result); return std::move(result);
} }
case telegram_api::videoSizeStickerMarkup::ID: { case telegram_api::videoSizeStickerMarkup::ID: {
auto size = move_tl_object_as<telegram_api::videoSizeStickerMarkup>(size_ptr); auto size = move_tl_object_as<telegram_api::videoSizeStickerMarkup>(size_ptr);
StickerPhotoSize result; auto result = make_unique<StickerPhotoSize>();
result.type = StickerPhotoSize::Type::Sticker; result->type = StickerPhotoSize::Type::Sticker;
result.sticker_set_id = td->stickers_manager_->add_sticker_set(std::move(size->stickerset_)); result->sticker_set_id = td->stickers_manager_->add_sticker_set(std::move(size->stickerset_));
result.sticker_id = size->sticker_id_; result->sticker_id = size->sticker_id_;
result.background_colors = std::move(size->background_colors_); result->background_colors = std::move(size->background_colors_);
if (!result.sticker_set_id.is_valid() || result.sticker_id == 0 || !result.custom_emoji_id.is_valid() || if (!result->sticker_set_id.is_valid() || result->sticker_id == 0 || !result->custom_emoji_id.is_valid() ||
result.background_colors.empty() || result.background_colors.size() > 4) { result->background_colors.empty() || result->background_colors.size() > 4) {
LOG(ERROR) << "Receive invalid " << result; LOG(ERROR) << "Receive invalid " << *result;
return {}; return {};
} }
for (auto &color : result.background_colors) { for (auto &color : result->background_colors) {
color &= 0xFFFFFF; color &= 0xFFFFFF;
} }
return std::move(result); return std::move(result);

View File

@ -55,9 +55,9 @@ Variant<PhotoSize, string> get_photo_size(FileManager *file_manager, PhotoSizeSo
DialogId owner_dialog_id, tl_object_ptr<telegram_api::PhotoSize> &&size_ptr, DialogId owner_dialog_id, tl_object_ptr<telegram_api::PhotoSize> &&size_ptr,
PhotoFormat format); PhotoFormat format);
Variant<AnimationSize, StickerPhotoSize> get_animation_size(Td *td, PhotoSizeSource source, int64 id, int64 access_hash, Variant<AnimationSize, unique_ptr<StickerPhotoSize>> get_animation_size(
string file_reference, DcId dc_id, DialogId owner_dialog_id, Td *td, PhotoSizeSource source, int64 id, int64 access_hash, string file_reference, DcId dc_id,
tl_object_ptr<telegram_api::VideoSize> &&size_ptr); DialogId owner_dialog_id, tl_object_ptr<telegram_api::VideoSize> &&size_ptr);
PhotoSize get_web_document_photo_size(FileManager *file_manager, FileType file_type, DialogId owner_dialog_id, PhotoSize get_web_document_photo_size(FileManager *file_manager, FileType file_type, DialogId owner_dialog_id,
tl_object_ptr<telegram_api::WebDocument> web_document_ptr); tl_object_ptr<telegram_api::WebDocument> web_document_ptr);

View File

@ -16,6 +16,7 @@
#include "td/utils/Status.h" #include "td/utils/Status.h"
#include "td/utils/tl_parsers.h" #include "td/utils/tl_parsers.h"
#include "td/utils/tl_storers.h" #include "td/utils/tl_storers.h"
#include "td/utils/unique_value_ptr.h"
#include "td/utils/Variant.h" #include "td/utils/Variant.h"
#include <type_traits> #include <type_traits>
@ -172,6 +173,18 @@ void parse(unique_ptr<T> &ptr, ParserT &parser) {
parse(*ptr, parser); parse(*ptr, parser);
} }
template <class T, class StorerT>
void store(const unique_value_ptr<T> &ptr, StorerT &storer) {
CHECK(ptr != nullptr);
store(*ptr, storer);
}
template <class T, class ParserT>
void parse(unique_value_ptr<T> &ptr, ParserT &parser) {
CHECK(ptr == nullptr);
ptr = make_unique_value<T>();
parse(*ptr, parser);
}
template <class Key, class Hash, class KeyEqual, class StorerT> template <class Key, class Hash, class KeyEqual, class StorerT>
void store(const FlatHashSet<Key, Hash, KeyEqual> &s, StorerT &storer) { void store(const FlatHashSet<Key, Hash, KeyEqual> &s, StorerT &storer) {
storer.store_binary(narrow_cast<int32>(s.size())); storer.store_binary(narrow_cast<int32>(s.size()));