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

View File

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

View File

@ -72,7 +72,7 @@ template <class StorerT>
void store(const Photo &photo, StorerT &storer) {
bool has_minithumbnail = !photo.minithumbnail.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();
STORE_FLAG(photo.has_stickers);
STORE_FLAG(has_minithumbnail);

View File

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

View File

@ -16,6 +16,7 @@
#include "td/utils/Status.h"
#include "td/utils/tl_parsers.h"
#include "td/utils/tl_storers.h"
#include "td/utils/unique_value_ptr.h"
#include "td/utils/Variant.h"
#include <type_traits>
@ -172,6 +173,18 @@ void parse(unique_ptr<T> &ptr, ParserT &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>
void store(const FlatHashSet<Key, Hash, KeyEqual> &s, StorerT &storer) {
storer.store_binary(narrow_cast<int32>(s.size()));