From 233984f1e391566ba59643c0438f085f6c98ab4e Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 2 May 2023 19:07:02 +0300 Subject: [PATCH] Move iterators to class OrderedMessages. --- td/telegram/MessagesManager.cpp | 47 +++++------ td/telegram/MessagesManager.h | 127 ------------------------------ td/telegram/OrderedMessage.h | 133 ++++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+), 150 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 529f5d7c5..52db35e0a 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -10042,7 +10042,7 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ } if (!d->last_database_message_id.is_valid()) { CHECK(d->last_message_id.is_valid()); - MessagesConstIterator it(d, d->last_message_id); + auto it = d->ordered_messages.get_const_iterator(d->last_message_id); MessageId new_first_database_message_id; while (*it != nullptr) { auto message_id = (*it)->message_id; @@ -10070,7 +10070,7 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ << d->debug_set_dialog_last_database_message_id; CHECK(d->first_database_message_id.is_valid()); { - MessagesConstIterator it(d, d->first_database_message_id); + auto it = d->ordered_messages.get_const_iterator(d->first_database_message_id); if (*it != nullptr && ((*it)->message_id == d->first_database_message_id || (*it)->have_next)) { MessageId new_first_database_message_id = d->first_database_message_id; while (*it != nullptr) { @@ -10087,7 +10087,7 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ } } { - MessagesConstIterator it(d, d->last_database_message_id); + auto it = d->ordered_messages.get_const_iterator(d->last_database_message_id); if (*it != nullptr && ((*it)->message_id == d->last_database_message_id || (*it)->have_next)) { MessageId new_last_database_message_id = d->last_database_message_id; while (*it != nullptr) { @@ -12378,7 +12378,7 @@ bool MessagesManager::has_incoming_notification(DialogId dialog_id, const Messag int32 MessagesManager::calc_new_unread_count_from_last_unread(Dialog *d, MessageId max_message_id, MessageType type) const { CHECK(!max_message_id.is_scheduled()); - MessagesConstIterator it(d, max_message_id); + auto it = d->ordered_messages.get_const_iterator(max_message_id); if (*it == nullptr || (*it)->message_id != max_message_id) { return -1; } @@ -12403,7 +12403,7 @@ int32 MessagesManager::calc_new_unread_count_from_the_end(Dialog *d, MessageId m int32 hint_unread_count) const { CHECK(!max_message_id.is_scheduled()); int32 unread_count = 0; - MessagesConstIterator it(d, MessageId::max()); + auto it = d->ordered_messages.get_const_iterator(MessageId::max()); while (*it != nullptr && (*it)->message_id > max_message_id) { auto message_id = (*it)->message_id; if (message_id.get_type() == type && has_incoming_notification(d->dialog_id, get_message(d, message_id))) { @@ -13305,7 +13305,8 @@ void MessagesManager::ttl_read_history_impl(DialogId dialog_id, bool is_outgoing auto *d = get_dialog(dialog_id); CHECK(d != nullptr); auto now = Time::now(); - for (auto it = MessagesIterator(d, from_message_id); *it && (*it)->message_id >= till_message_id; --it) { + for (auto it = d->ordered_messages.get_const_iterator(from_message_id); *it && (*it)->message_id >= till_message_id; + --it) { auto *m = get_message(d, (*it)->message_id); CHECK(m != nullptr); if (m->is_outgoing == is_outgoing) { @@ -14046,7 +14047,7 @@ void MessagesManager::read_secret_chat_outbox_inner(DialogId dialog_id, int32 up Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); - auto end = MessagesConstIterator(d, MessageId::max()); + auto end = d->ordered_messages.get_const_iterator(MessageId::max()); while (*end && (get_message(d, (*end)->message_id)->date > up_to_date || (*end)->message_id.is_yet_unsent())) { --end; } @@ -16202,7 +16203,7 @@ void MessagesManager::fix_dialog_last_notification_id(Dialog *d, bool from_menti if (d->notification_info == nullptr) { return; } - MessagesConstIterator it(d, message_id); + auto it = d->ordered_messages.get_const_iterator(message_id); auto &group_info = get_notification_group_info(d, from_mentions); VLOG(notifications) << "Trying to fix last notification identifier in " << group_info.group_id << " from " << d->dialog_id << " from " << message_id << "/" << group_info.last_notification_id; @@ -16331,7 +16332,7 @@ unique_ptr MessagesManager::do_delete_message(Dialog * << d->being_deleted_message_id << " " << message_id << " " << source; d->being_deleted_message_id = message_id; - const MessagesIterator message_it(d, message_id); + const auto message_it = d->ordered_messages.get_iterator(message_id); CHECK(*message_it != nullptr); CHECK((*message_it)->message_id == message_id); @@ -17267,7 +17268,7 @@ void MessagesManager::mark_dialog_as_read(Dialog *d) { // TODO read forum topics } if (d->server_unread_count + d->local_unread_count > 0 && d->last_message_id.is_valid()) { - MessagesConstIterator it(d, d->last_message_id); + auto it = d->ordered_messages.get_const_iterator(d->last_message_id); while (*it != nullptr) { auto message_id = (*it)->message_id; if (message_id.is_server() || message_id.is_local()) { @@ -21047,7 +21048,7 @@ tl_object_ptr MessagesManager::get_dialog_history(DialogId dia << ", have_full_history = " << d->have_full_history << ", have_full_history_source = " << d->have_full_history_source; - MessagesConstIterator p(d, from_message_id); + auto p = d->ordered_messages.get_const_iterator(from_message_id); LOG(DEBUG) << "Iterator points to " << (*p ? (*p)->message_id : MessageId()); bool from_the_end = (d->last_message_id != MessageId() && from_message_id > d->last_message_id) || from_message_id >= MessageId::max(); @@ -21056,7 +21057,7 @@ tl_object_ptr MessagesManager::get_dialog_history(DialogId dia limit += offset; offset = 0; if (d->last_message_id == MessageId()) { - p = MessagesConstIterator(); + p = OrderedMessages::ConstIterator(); } } else { bool have_a_gap = false; @@ -21069,7 +21070,7 @@ tl_object_ptr MessagesManager::get_dialog_history(DialogId dia } CHECK(cur->message_id > from_message_id); from_message_id = cur->message_id; - p = MessagesConstIterator(d, from_message_id); + p = d->ordered_messages.get_const_iterator(from_message_id); } else { have_a_gap = true; } @@ -21082,7 +21083,7 @@ tl_object_ptr MessagesManager::get_dialog_history(DialogId dia if (have_a_gap) { LOG(INFO) << "Have a gap near message to get chat history from"; - p = MessagesConstIterator(); + p = OrderedMessages::ConstIterator(); } if (*p != nullptr && (*p)->message_id == from_message_id) { if (offset < 0) { @@ -21105,7 +21106,7 @@ tl_object_ptr MessagesManager::get_dialog_history(DialogId dia CHECK(!have_a_gap); limit += offset; offset = 0; - p = MessagesConstIterator(d, from_message_id); + p = d->ordered_messages.get_const_iterator(from_message_id); } if (!have_a_gap && offset < 0) { @@ -22800,7 +22801,7 @@ int64 MessagesManager::get_dialog_message_by_date(DialogId dialog_id, int32 date auto message_id = d->ordered_messages.find_message_by_date(date, get_get_message_date(d)); if (message_id.is_valid() && - (message_id == d->last_message_id || (*MessagesConstIterator(d, message_id))->have_next)) { + (message_id == d->last_message_id || (*d->ordered_messages.get_const_iterator(message_id))->have_next)) { get_dialog_message_by_date_results_[random_id] = {dialog_id, message_id}; promise.set_value(Unit()); return random_id; @@ -23161,7 +23162,7 @@ void MessagesManager::preload_newer_messages(const Dialog *d, MessageId max_mess return; } - MessagesConstIterator p(d, max_message_id); + auto p = d->ordered_messages.get_const_iterator(max_message_id); int32 limit = MAX_GET_HISTORY * 3 / 10; while (*p != nullptr && limit-- > 0) { ++p; @@ -23189,7 +23190,7 @@ void MessagesManager::preload_older_messages(const Dialog *d, MessageId min_mess return; } */ - MessagesConstIterator p(d, min_message_id); + auto p = d->ordered_messages.get_const_iterator(min_message_id); int32 limit = MAX_GET_HISTORY * 3 / 10 + 1; while (*p != nullptr && limit-- > 0) { min_message_id = (*p)->message_id; @@ -34810,7 +34811,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq bool is_attached = false; if (auto_attach) { - auto it = MessagesIterator(d, message_id); + auto it = d->ordered_messages.get_iterator(message_id); OrderedMessage *previous_message = *it; if (previous_message != nullptr) { auto previous_message_id = previous_message->message_id; @@ -34982,7 +34983,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq } if (!is_attached && !have_next && !have_previous) { - MessagesIterator it(d, m->message_id); + auto it = d->ordered_messages.get_iterator(m->message_id); if (*it != nullptr && (*it)->have_next) { // need to drop a connection between messages auto previous_message = *it; @@ -35721,7 +35722,7 @@ void MessagesManager::do_delete_message_log_event(const DeleteMessageLogEvent &l void MessagesManager::attach_message_to_previous(Dialog *d, MessageId message_id, const char *source) { CHECK(d != nullptr); CHECK(message_id.is_valid()); - MessagesIterator it(d, message_id); + auto it = d->ordered_messages.get_iterator(message_id); OrderedMessage *m = *it; CHECK(m != nullptr); CHECK(m->message_id == message_id); @@ -35743,7 +35744,7 @@ void MessagesManager::attach_message_to_previous(Dialog *d, MessageId message_id void MessagesManager::attach_message_to_next(Dialog *d, MessageId message_id, const char *source) { CHECK(d != nullptr); CHECK(message_id.is_valid()); - MessagesIterator it(d, message_id); + auto it = d->ordered_messages.get_iterator(message_id); OrderedMessage *m = *it; CHECK(m != nullptr); CHECK(m->message_id == message_id); @@ -40049,7 +40050,7 @@ void MessagesManager::suffix_load_update_first_message_id(const Dialog *d, Suffi queries->suffix_load_first_message_id_ = d->last_message_id; } - auto it = MessagesConstIterator(d, queries->suffix_load_first_message_id_); + auto it = d->ordered_messages.get_const_iterator(queries->suffix_load_first_message_id_); CHECK(*it != nullptr); CHECK((*it)->message_id == queries->suffix_load_first_message_id_); while ((*it)->have_previous) { diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 13fc96d29..8caa32fae 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -1574,133 +1574,6 @@ class MessagesManager final : public Actor { } }; - class MessagesIteratorBase { - vector stack_; - - protected: - MessagesIteratorBase() = default; - - // points iterator to message with greatest identifier which is less or equal than message_id - MessagesIteratorBase(const OrderedMessage *root, MessageId message_id) { - CHECK(!message_id.is_scheduled()); - - size_t last_right_pos = 0; - while (root != nullptr) { - // LOG(DEBUG) << "Have root->message_id = " << root->message_id; - stack_.push_back(root); - if (root->message_id <= message_id) { - // LOG(DEBUG) << "Go right"; - last_right_pos = stack_.size(); - root = root->right.get(); - } else { - // LOG(DEBUG) << "Go left"; - root = root->left.get(); - } - } - stack_.resize(last_right_pos); - } - - const OrderedMessage *operator*() const { - return stack_.empty() ? nullptr : stack_.back(); - } - - ~MessagesIteratorBase() = default; - - public: - MessagesIteratorBase(const MessagesIteratorBase &) = default; - MessagesIteratorBase &operator=(const MessagesIteratorBase &) = default; - MessagesIteratorBase(MessagesIteratorBase &&other) = default; - MessagesIteratorBase &operator=(MessagesIteratorBase &&other) = default; - - void operator++() { - if (stack_.empty()) { - return; - } - - const OrderedMessage *cur = stack_.back(); - if (!cur->have_next) { - stack_.clear(); - return; - } - if (cur->right == nullptr) { - while (true) { - stack_.pop_back(); - if (stack_.empty()) { - return; - } - const OrderedMessage *new_cur = stack_.back(); - if (new_cur->left.get() == cur) { - return; - } - cur = new_cur; - } - } - - cur = cur->right.get(); - while (cur != nullptr) { - stack_.push_back(cur); - cur = cur->left.get(); - } - } - - void operator--() { - if (stack_.empty()) { - return; - } - - const OrderedMessage *cur = stack_.back(); - if (!cur->have_previous) { - stack_.clear(); - return; - } - if (cur->left == nullptr) { - while (true) { - stack_.pop_back(); - if (stack_.empty()) { - return; - } - const OrderedMessage *new_cur = stack_.back(); - if (new_cur->right.get() == cur) { - return; - } - cur = new_cur; - } - } - - cur = cur->left.get(); - while (cur != nullptr) { - stack_.push_back(cur); - cur = cur->right.get(); - } - } - }; - - class MessagesIterator final : public MessagesIteratorBase { - public: - MessagesIterator() = default; - - MessagesIterator(Dialog *d, MessageId message_id) - : MessagesIteratorBase(d->ordered_messages.messages_.get(), message_id) { - } - - OrderedMessage *operator*() const { - return const_cast(MessagesIteratorBase::operator*()); - } - }; - - class MessagesConstIterator final : public MessagesIteratorBase { - public: - MessagesConstIterator() = default; - - MessagesConstIterator(const Dialog *d, MessageId message_id) - : MessagesIteratorBase(d->ordered_messages.messages_.get(), message_id) { - } - - const OrderedMessage *operator*() const { - return MessagesIteratorBase::operator*(); - } - }; - struct PendingSecretMessage { enum class Type : int32 { NewMessage, DeleteMessages, DeleteHistory }; Type type = Type::NewMessage; diff --git a/td/telegram/OrderedMessage.h b/td/telegram/OrderedMessage.h index 064d362db..a6e55e33e 100644 --- a/td/telegram/OrderedMessage.h +++ b/td/telegram/OrderedMessage.h @@ -29,6 +29,139 @@ struct OrderedMessage { struct OrderedMessages { unique_ptr messages_; + class IteratorBase { + vector stack_; + + protected: + IteratorBase() = default; + + // points iterator to message with greatest identifier which is less or equal than message_id + IteratorBase(const OrderedMessage *root, MessageId message_id) { + CHECK(!message_id.is_scheduled()); + + size_t last_right_pos = 0; + while (root != nullptr) { + // LOG(DEBUG) << "Have root->message_id = " << root->message_id; + stack_.push_back(root); + if (root->message_id <= message_id) { + // LOG(DEBUG) << "Go right"; + last_right_pos = stack_.size(); + root = root->right.get(); + } else { + // LOG(DEBUG) << "Go left"; + root = root->left.get(); + } + } + stack_.resize(last_right_pos); + } + + const OrderedMessage *operator*() const { + return stack_.empty() ? nullptr : stack_.back(); + } + + ~IteratorBase() = default; + + public: + IteratorBase(const IteratorBase &) = default; + IteratorBase &operator=(const IteratorBase &) = default; + IteratorBase(IteratorBase &&other) = default; + IteratorBase &operator=(IteratorBase &&other) = default; + + void operator++() { + if (stack_.empty()) { + return; + } + + const OrderedMessage *cur = stack_.back(); + if (!cur->have_next) { + stack_.clear(); + return; + } + if (cur->right == nullptr) { + while (true) { + stack_.pop_back(); + if (stack_.empty()) { + return; + } + const OrderedMessage *new_cur = stack_.back(); + if (new_cur->left.get() == cur) { + return; + } + cur = new_cur; + } + } + + cur = cur->right.get(); + while (cur != nullptr) { + stack_.push_back(cur); + cur = cur->left.get(); + } + } + + void operator--() { + if (stack_.empty()) { + return; + } + + const OrderedMessage *cur = stack_.back(); + if (!cur->have_previous) { + stack_.clear(); + return; + } + if (cur->left == nullptr) { + while (true) { + stack_.pop_back(); + if (stack_.empty()) { + return; + } + const OrderedMessage *new_cur = stack_.back(); + if (new_cur->right.get() == cur) { + return; + } + cur = new_cur; + } + } + + cur = cur->left.get(); + while (cur != nullptr) { + stack_.push_back(cur); + cur = cur->right.get(); + } + } + }; + + class Iterator final : public IteratorBase { + public: + Iterator() = default; + + Iterator(OrderedMessage *root, MessageId message_id) : IteratorBase(root, message_id) { + } + + OrderedMessage *operator*() const { + return const_cast(IteratorBase::operator*()); + } + }; + + class ConstIterator final : public IteratorBase { + public: + ConstIterator() = default; + + ConstIterator(const OrderedMessage *root, MessageId message_id) : IteratorBase(root, message_id) { + } + + const OrderedMessage *operator*() const { + return IteratorBase::operator*(); + } + }; + + Iterator get_iterator(MessageId message_id) { + return Iterator(messages_.get(), message_id); + } + + ConstIterator get_const_iterator(MessageId message_id) const { + return ConstIterator(messages_.get(), message_id); + } + OrderedMessage *insert(MessageId message_id); void erase(MessageId message_id);