diff --git a/CMakeLists.txt b/CMakeLists.txt index 4304a45fe..b31df8905 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -428,6 +428,7 @@ set(TDLIB_SOURCE td/telegram/NotificationSound.cpp td/telegram/NotificationType.cpp td/telegram/OptionManager.cpp + td/telegram/OrderedMessage.cpp td/telegram/OrderInfo.cpp td/telegram/Payments.cpp td/telegram/PasswordManager.cpp @@ -703,6 +704,7 @@ set(TDLIB_SOURCE td/telegram/NotificationSoundType.h td/telegram/NotificationType.h td/telegram/OptionManager.h + td/telegram/OrderedMessage.h td/telegram/OrderInfo.h td/telegram/PasswordManager.h td/telegram/Payments.h diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 1e27ff30c..ff72965b4 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -16498,7 +16498,7 @@ unique_ptr MessagesManager::do_delete_message(Dialog * CHECK(m == result.get()); d->messages.erase(message_id); - treap_delete_message(&d->ordered_messages, message_id); + OrderedMessage::erase(&d->ordered_messages, message_id); d->being_deleted_message_id = MessageId(); @@ -34220,74 +34220,6 @@ void MessagesManager::unpin_all_dialog_messages_on_server(DialogId dialog_id, ui get_erase_log_event_promise(log_event_id, std::move(promise))); } -MessagesManager::OrderedMessage *MessagesManager::treap_insert_message(unique_ptr *v, - MessageId message_id) { - auto random_y = static_cast(static_cast(message_id.get() * 2101234567u)); - while (*v != nullptr && (*v)->random_y >= random_y) { - if ((*v)->message_id.get() < message_id.get()) { - v = &(*v)->right; - } else if ((*v)->message_id == message_id) { - UNREACHABLE(); - } else { - v = &(*v)->left; - } - } - - auto message = make_unique(); - message->message_id = message_id; - message->random_y = random_y; - - unique_ptr *left = &message->left; - unique_ptr *right = &message->right; - - unique_ptr cur = std::move(*v); - while (cur != nullptr) { - if (cur->message_id.get() < message_id.get()) { - *left = std::move(cur); - left = &((*left)->right); - cur = std::move(*left); - } else { - *right = std::move(cur); - right = &((*right)->left); - cur = std::move(*right); - } - } - CHECK(*left == nullptr); - CHECK(*right == nullptr); - *v = std::move(message); - return v->get(); -} - -void MessagesManager::treap_delete_message(unique_ptr *v, MessageId message_id) { - while (*v != nullptr) { - if ((*v)->message_id.get() < message_id.get()) { - v = &(*v)->right; - } else if ((*v)->message_id.get() > message_id.get()) { - v = &(*v)->left; - } else { - break; - } - } - - unique_ptr result = std::move(*v); - CHECK(result != nullptr); - unique_ptr left = std::move(result->left); - unique_ptr right = std::move(result->right); - - while (left != nullptr || right != nullptr) { - if (left == nullptr || (right != nullptr && right->random_y > left->random_y)) { - *v = std::move(right); - v = &((*v)->left); - right = std::move(*v); - } else { - *v = std::move(left); - v = &((*v)->right); - left = std::move(*v); - } - } - CHECK(*v == nullptr); -} - MessagesManager::Message *MessagesManager::get_message(Dialog *d, MessageId message_id) { return const_cast(get_message(static_cast(d), message_id)); } @@ -35231,7 +35163,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq Message *result_message = message.get(); d->messages.set(message_id, std::move(message)); - OrderedMessage *ordered_message = treap_insert_message(&d->ordered_messages, message_id); + OrderedMessage *ordered_message = OrderedMessage::insert(&d->ordered_messages, message_id); if (!is_attached) { if (have_next) { CHECK(!have_previous); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index a76528c0c..ade5a1205 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -51,6 +51,7 @@ #include "td/telegram/NotificationGroupType.h" #include "td/telegram/NotificationId.h" #include "td/telegram/NotificationSettingsScope.h" +#include "td/telegram/OrderedMessage.h" #include "td/telegram/Photo.h" #include "td/telegram/RecentDialogList.h" #include "td/telegram/ReplyMarkup.h" @@ -1139,18 +1140,6 @@ class MessagesManager final : public Actor { } }; - struct OrderedMessage { - int32 random_y = 0; - - bool have_previous = false; - bool have_next = false; - - MessageId message_id; - - unique_ptr left; - unique_ptr right; - }; - // Do not forget to update MessagesManager::update_message and all make_unique when this class is changed struct Message { MessageId message_id; @@ -2865,10 +2854,6 @@ class MessagesManager final : public Actor { DialogFolder *get_dialog_folder(FolderId folder_id); const DialogFolder *get_dialog_folder(FolderId folder_id) const; - static OrderedMessage *treap_insert_message(unique_ptr *v, MessageId message_id); - - static void treap_delete_message(unique_ptr *v, MessageId message_id); - static Message *get_message(Dialog *d, MessageId message_id); static const Message *get_message(const Dialog *d, MessageId message_id); diff --git a/td/telegram/OrderedMessage.cpp b/td/telegram/OrderedMessage.cpp new file mode 100644 index 000000000..4c7b945f7 --- /dev/null +++ b/td/telegram/OrderedMessage.cpp @@ -0,0 +1,78 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/OrderedMessage.h" + +namespace td { + +OrderedMessage *OrderedMessage::insert(unique_ptr *v, MessageId message_id) { + auto random_y = static_cast(static_cast(message_id.get() * 2101234567u)); + while (*v != nullptr && (*v)->random_y >= random_y) { + if ((*v)->message_id.get() < message_id.get()) { + v = &(*v)->right; + } else if ((*v)->message_id == message_id) { + UNREACHABLE(); + } else { + v = &(*v)->left; + } + } + + auto message = make_unique(); + message->message_id = message_id; + message->random_y = random_y; + + unique_ptr *left = &message->left; + unique_ptr *right = &message->right; + + unique_ptr cur = std::move(*v); + while (cur != nullptr) { + if (cur->message_id.get() < message_id.get()) { + *left = std::move(cur); + left = &((*left)->right); + cur = std::move(*left); + } else { + *right = std::move(cur); + right = &((*right)->left); + cur = std::move(*right); + } + } + CHECK(*left == nullptr); + CHECK(*right == nullptr); + *v = std::move(message); + return v->get(); +} + +void OrderedMessage::erase(unique_ptr *v, MessageId message_id) { + while (*v != nullptr) { + if ((*v)->message_id.get() < message_id.get()) { + v = &(*v)->right; + } else if ((*v)->message_id.get() > message_id.get()) { + v = &(*v)->left; + } else { + break; + } + } + + unique_ptr result = std::move(*v); + CHECK(result != nullptr); + unique_ptr left = std::move(result->left); + unique_ptr right = std::move(result->right); + + while (left != nullptr || right != nullptr) { + if (left == nullptr || (right != nullptr && right->random_y > left->random_y)) { + *v = std::move(right); + v = &((*v)->left); + right = std::move(*v); + } else { + *v = std::move(left); + v = &((*v)->right); + left = std::move(*v); + } + } + CHECK(*v == nullptr); +} + +} // namespace td diff --git a/td/telegram/OrderedMessage.h b/td/telegram/OrderedMessage.h new file mode 100644 index 000000000..1a849d50e --- /dev/null +++ b/td/telegram/OrderedMessage.h @@ -0,0 +1,31 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MessageId.h" + +#include "td/utils/common.h" + +namespace td { + +struct OrderedMessage { + int32 random_y = 0; + + bool have_previous = false; + bool have_next = false; + + MessageId message_id; + + unique_ptr left; + unique_ptr right; + + static OrderedMessage *insert(unique_ptr *v, MessageId message_id); + + static void erase(unique_ptr *v, MessageId message_id); +}; + +} // namespace td