Find unloadable messages using LRU.

This commit is contained in:
levlam 2023-05-06 02:37:53 +03:00
parent b482ffbbeb
commit 22a82c117d
2 changed files with 41 additions and 27 deletions

View File

@ -11629,31 +11629,24 @@ vector<MessageId> MessagesManager::find_dialog_messages(const Dialog *d,
vector<MessageId> MessagesManager::find_unloadable_messages(const Dialog *d, int32 unload_before_date,
bool &has_left_to_unload_messages) const {
vector<MessageId> message_ids;
d->ordered_messages.traverse_messages(
[&](MessageId message_id) {
if (message_ids.size() >= MAX_UNLOADED_MESSAGES) {
has_left_to_unload_messages = true;
return false;
}
return true;
},
[&](MessageId message_id) {
const Message *m = d->messages.get_pointer(message_id);
CHECK(m != nullptr);
if (can_unload_message(d, m)) {
if (m->last_access_date <= unload_before_date) {
message_ids.push_back(message_id);
} else {
has_left_to_unload_messages = true;
}
}
if (has_left_to_unload_messages && m->date > unload_before_date) {
// we aren't interested in unloading too new messages
return false;
}
return true;
});
for (auto it = d->message_lru_list.next; it != &d->message_lru_list; it = it->next) {
if (message_ids.size() >= MAX_UNLOADED_MESSAGES) {
has_left_to_unload_messages = true;
break;
}
const auto *m = static_cast<const Message *>(it);
if (can_unload_message(d, m)) {
if (m->last_access_date <= unload_before_date) {
message_ids.push_back(m->message_id);
} else {
has_left_to_unload_messages = true;
}
}
if (has_left_to_unload_messages && m->date > unload_before_date) {
// we aren't interested in unloading too new messages
break;
}
}
return message_ids;
}
@ -12004,6 +11997,8 @@ void MessagesManager::delete_all_dialog_messages(Dialog *d, bool remove_from_dia
CHECK(message_id == message->message_id);
Message *m = message.get();
static_cast<ListNode *>(m)->remove();
LOG(INFO) << "Delete " << message_id;
deleted_message_ids.push_back(message_id.get());
@ -16439,6 +16434,8 @@ unique_ptr<MessagesManager::Message> MessagesManager::do_delete_message(Dialog *
CHECK(m == result.get());
d->messages.erase(message_id);
static_cast<ListNode *>(result.get())->remove();
d->ordered_messages.erase(message_id, only_from_memory);
d->being_deleted_message_id = MessageId();
@ -34058,7 +34055,13 @@ const MessagesManager::Message *MessagesManager::get_message(const Dialog *d, Me
} else {
result = d->messages.get_pointer(message_id);
if (result != nullptr) {
result->last_access_date = G()->unix_time_cached();
auto unix_time = G()->unix_time_cached();
if (unix_time > result->last_access_date + 5) {
result->last_access_date = unix_time;
auto list_node = const_cast<ListNode *>(static_cast<const ListNode *>(result));
list_node->remove();
d->message_lru_list.put_back(list_node);
}
}
}
LOG(INFO) << "Search for " << message_id << " in " << d->dialog_id << " found " << result;
@ -34890,6 +34893,8 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
Message *result_message = message.get();
d->messages.set(message_id, std::move(message));
d->message_lru_list.put_back(result_message);
d->ordered_messages.insert(message_id, auto_attach, have_previous, have_next, old_last_message_id, source);
if (m->message_id.is_yet_unsent() && !m->message_id.is_scheduled() && m->top_thread_message_id.is_valid() &&

View File

@ -1140,7 +1140,7 @@ class MessagesManager final : public Actor {
};
// Do not forget to update MessagesManager::update_message and all make_unique<Message> when this class is changed
struct Message {
struct Message final : public ListNode {
MessageId message_id;
UserId sender_user_id;
DialogId sender_dialog_id;
@ -1258,6 +1258,13 @@ class MessagesManager final : public Actor {
template <class ParserT>
void parse(ParserT &parser);
Message() = default;
Message(const Message &) = delete;
Message &operator=(const Message &) = delete;
Message(Message &&) = delete;
Message &operator=(Message &&) = delete;
~Message() = default;
};
struct NotificationGroupInfo {
@ -1442,6 +1449,8 @@ class MessagesManager final : public Actor {
WaitFreeHashMap<MessageId, unique_ptr<Message>, MessageIdHash> messages;
mutable ListNode message_lru_list;
OrderedMessages ordered_messages;
unique_ptr<DialogScheduledMessages> scheduled_messages;