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, vector<MessageId> MessagesManager::find_unloadable_messages(const Dialog *d, int32 unload_before_date,
bool &has_left_to_unload_messages) const { bool &has_left_to_unload_messages) const {
vector<MessageId> message_ids; vector<MessageId> message_ids;
d->ordered_messages.traverse_messages( for (auto it = d->message_lru_list.next; it != &d->message_lru_list; it = it->next) {
[&](MessageId message_id) { if (message_ids.size() >= MAX_UNLOADED_MESSAGES) {
if (message_ids.size() >= MAX_UNLOADED_MESSAGES) { has_left_to_unload_messages = true;
has_left_to_unload_messages = true; break;
return false; }
} const auto *m = static_cast<const Message *>(it);
return true; if (can_unload_message(d, m)) {
}, if (m->last_access_date <= unload_before_date) {
[&](MessageId message_id) { message_ids.push_back(m->message_id);
const Message *m = d->messages.get_pointer(message_id); } else {
CHECK(m != nullptr); has_left_to_unload_messages = true;
if (can_unload_message(d, m)) { }
if (m->last_access_date <= unload_before_date) { }
message_ids.push_back(message_id); if (has_left_to_unload_messages && m->date > unload_before_date) {
} else { // we aren't interested in unloading too new messages
has_left_to_unload_messages = true; break;
} }
} }
if (has_left_to_unload_messages && m->date > unload_before_date) {
// we aren't interested in unloading too new messages
return false;
}
return true;
});
return message_ids; 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); CHECK(message_id == message->message_id);
Message *m = message.get(); Message *m = message.get();
static_cast<ListNode *>(m)->remove();
LOG(INFO) << "Delete " << message_id; LOG(INFO) << "Delete " << message_id;
deleted_message_ids.push_back(message_id.get()); 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()); CHECK(m == result.get());
d->messages.erase(message_id); d->messages.erase(message_id);
static_cast<ListNode *>(result.get())->remove();
d->ordered_messages.erase(message_id, only_from_memory); d->ordered_messages.erase(message_id, only_from_memory);
d->being_deleted_message_id = MessageId(); d->being_deleted_message_id = MessageId();
@ -34058,7 +34055,13 @@ const MessagesManager::Message *MessagesManager::get_message(const Dialog *d, Me
} else { } else {
result = d->messages.get_pointer(message_id); result = d->messages.get_pointer(message_id);
if (result != nullptr) { 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; 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(); Message *result_message = message.get();
d->messages.set(message_id, std::move(message)); 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); 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() && 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 // 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; MessageId message_id;
UserId sender_user_id; UserId sender_user_id;
DialogId sender_dialog_id; DialogId sender_dialog_id;
@ -1258,6 +1258,13 @@ class MessagesManager final : public Actor {
template <class ParserT> template <class ParserT>
void parse(ParserT &parser); 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 { struct NotificationGroupInfo {
@ -1442,6 +1449,8 @@ class MessagesManager final : public Actor {
WaitFreeHashMap<MessageId, unique_ptr<Message>, MessageIdHash> messages; WaitFreeHashMap<MessageId, unique_ptr<Message>, MessageIdHash> messages;
mutable ListNode message_lru_list;
OrderedMessages ordered_messages; OrderedMessages ordered_messages;
unique_ptr<DialogScheduledMessages> scheduled_messages; unique_ptr<DialogScheduledMessages> scheduled_messages;