Add MessagesManager::get_message_notification_group_keys_from_database.

GitOrigin-RevId: 8ad93b1dc1782b5f0bf94d70ca8deba55a6ea58f
This commit is contained in:
levlam 2018-11-29 00:51:25 +03:00
parent 9e3171ca7a
commit 113e264a5f
7 changed files with 127 additions and 42 deletions

View File

@ -537,6 +537,7 @@ set(TDLIB_SOURCE
td/telegram/net/TempAuthKeyWatchdog.h td/telegram/net/TempAuthKeyWatchdog.h
td/telegram/Notification.h td/telegram/Notification.h
td/telegram/NotificationGroupId.h td/telegram/NotificationGroupId.h
td/telegram/NotificationGroupKey.h
td/telegram/NotificationId.h td/telegram/NotificationId.h
td/telegram/NotificationManager.h td/telegram/NotificationManager.h
td/telegram/NotificationSettings.h td/telegram/NotificationSettings.h

View File

@ -97,9 +97,8 @@ class DialogDbImpl : public DialogDbSyncInterface {
"BY dialog_order DESC, dialog_id DESC LIMIT ?3")); "BY dialog_order DESC, dialog_id DESC LIMIT ?3"));
TRY_RESULT( TRY_RESULT(
get_dialogs_by_last_notification_date_stmt, get_dialogs_by_last_notification_date_stmt,
db_.get_statement("SELECT data, dialog_id, last_notification_date FROM dialogs WHERE " db_.get_statement("SELECT data FROM dialogs WHERE last_notification_date < ?1 OR (last_notification_date = ?1 "
"last_notification_date < ?1 OR (last_notification_date = ?1 AND dialog_id < ?2) ORDER " "AND dialog_id < ?2) ORDER BY last_notification_date DESC, dialog_id DESC LIMIT ?3"));
"BY last_notification_date DESC, dialog_id DESC LIMIT ?3"));
TRY_RESULT(get_dialog_by_notification_group_id_stmt, TRY_RESULT(get_dialog_by_notification_group_id_stmt,
db_.get_statement("SELECT data FROM dialogs WHERE notification_group_id = ?1")); db_.get_statement("SELECT data FROM dialogs WHERE notification_group_id = ?1"));
@ -207,12 +206,7 @@ class DialogDbImpl : public DialogDbSyncInterface {
std::vector<BufferSlice> dialogs; std::vector<BufferSlice> dialogs;
TRY_STATUS(get_dialogs_by_last_notification_date_stmt_.step()); TRY_STATUS(get_dialogs_by_last_notification_date_stmt_.step());
while (get_dialogs_by_last_notification_date_stmt_.has_row()) { while (get_dialogs_by_last_notification_date_stmt_.has_row()) {
BufferSlice data(get_dialogs_by_last_notification_date_stmt_.view_blob(0)); dialogs.emplace_back(get_dialogs_by_last_notification_date_stmt_.view_blob(0));
auto loaded_dialog_id = get_dialogs_by_last_notification_date_stmt_.view_int64(1);
auto loaded_dialog_last_notification_date = get_dialogs_by_last_notification_date_stmt_.view_int32(2);
LOG(INFO) << "Load chat " << loaded_dialog_id << " with last notification date "
<< loaded_dialog_last_notification_date;
dialogs.emplace_back(std::move(data));
TRY_STATUS(get_dialogs_by_last_notification_date_stmt_.step()); TRY_STATUS(get_dialogs_by_last_notification_date_stmt_.step());
} }

View File

@ -17467,6 +17467,10 @@ vector<Notification> MessagesManager::get_message_notifications_from_database(Di
NotificationId from_notification_id, NotificationId from_notification_id,
int32 limit) { int32 limit) {
CHECK(d != nullptr); CHECK(d != nullptr);
if (!G()->parameters().use_message_db) {
return {};
}
auto result = G()->td_db()->get_messages_db_sync()->get_messages_from_notification_id(d->dialog_id, auto result = G()->td_db()->get_messages_db_sync()->get_messages_from_notification_id(d->dialog_id,
from_notification_id, limit); from_notification_id, limit);
if (result.is_error()) { if (result.is_error()) {
@ -17485,6 +17489,36 @@ vector<Notification> MessagesManager::get_message_notifications_from_database(Di
return res; return res;
} }
vector<NotificationGroupKey> MessagesManager::get_message_notification_group_keys_from_database(
int32 from_last_notification_date, DialogId from_dialog_id, int32 limit) {
if (!G()->parameters().use_message_db) {
return {};
}
Result<std::vector<BufferSlice>> r_dialogs =
G()->td_db()->get_dialog_db_sync()->get_dialogs_by_last_notification_date(from_last_notification_date,
from_dialog_id, limit);
r_dialogs.ensure();
auto dialogs = r_dialogs.move_as_ok();
vector<NotificationGroupKey> group_keys;
group_keys.reserve(dialogs.size());
for (auto &dialog : dialogs) {
Dialog *d = on_load_dialog_from_database(DialogId(), std::move(dialog));
if (d == nullptr) {
continue;
}
CHECK(d->dialog_id.is_valid());
CHECK(d->last_notification_date != 0);
CHECK(d->message_notification_group_id.is_valid());
group_keys.emplace_back(d->message_notification_group_id, d->dialog_id, d->last_notification_date);
VLOG(notifications) << "Load " << group_keys.back() << " from database";
}
return group_keys;
}
int32 MessagesManager::get_dialog_pending_notification_count(Dialog *d) { int32 MessagesManager::get_dialog_pending_notification_count(Dialog *d) {
CHECK(d != nullptr); CHECK(d != nullptr);
if (is_dialog_muted(d)) { if (is_dialog_muted(d)) {

View File

@ -25,6 +25,7 @@
#include "td/telegram/net/NetQuery.h" #include "td/telegram/net/NetQuery.h"
#include "td/telegram/Notification.h" #include "td/telegram/Notification.h"
#include "td/telegram/NotificationGroupId.h" #include "td/telegram/NotificationGroupId.h"
#include "td/telegram/NotificationGroupKey.h"
#include "td/telegram/NotificationId.h" #include "td/telegram/NotificationId.h"
#include "td/telegram/NotificationSettings.h" #include "td/telegram/NotificationSettings.h"
#include "td/telegram/ReplyMarkup.h" #include "td/telegram/ReplyMarkup.h"
@ -664,6 +665,9 @@ class MessagesManager : public Actor {
}; };
MessageNotificationGroup get_message_notification_group_force(NotificationGroupId group_id); MessageNotificationGroup get_message_notification_group_force(NotificationGroupId group_id);
vector<NotificationGroupKey> get_message_notification_group_keys_from_database(int32 from_last_notification_date,
DialogId from_dialog_id, int32 limit);
void on_binlog_events(vector<BinlogEvent> &&events); void on_binlog_events(vector<BinlogEvent> &&events);
void get_payment_form(FullMessageId full_message_id, Promise<tl_object_ptr<td_api::paymentForm>> &&promise); void get_payment_form(FullMessageId full_message_id, Promise<tl_object_ptr<td_api::paymentForm>> &&promise);

View File

@ -0,0 +1,43 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018
//
// 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/DialogId.h"
#include "td/telegram/NotificationGroupId.h"
#include "td/utils/common.h"
#include "td/utils/StringBuilder.h"
namespace td {
struct NotificationGroupKey {
NotificationGroupId group_id;
DialogId dialog_id;
int32 last_notification_date = 0;
NotificationGroupKey() = default;
NotificationGroupKey(NotificationGroupId group_id, DialogId dialog_id, int32 last_notification_date)
: group_id(group_id), dialog_id(dialog_id), last_notification_date(last_notification_date) {
}
bool operator<(const NotificationGroupKey &other) const {
if (last_notification_date != other.last_notification_date) {
return last_notification_date > other.last_notification_date;
}
if (dialog_id != other.dialog_id) {
return dialog_id.get() > other.dialog_id.get();
}
return group_id.get() > other.group_id.get();
}
};
inline StringBuilder &operator<<(StringBuilder &string_builder, const NotificationGroupKey &group_key) {
return string_builder << '[' << group_key.group_id << ',' << group_key.dialog_id << ','
<< group_key.last_notification_date << ']';
}
} // namespace td

View File

@ -17,6 +17,7 @@
#include "td/utils/misc.h" #include "td/utils/misc.h"
#include <algorithm> #include <algorithm>
#include <limits>
#include <tuple> #include <tuple>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
@ -86,6 +87,10 @@ void NotificationManager::start_up() {
on_notification_cloud_delay_changed(); on_notification_cloud_delay_changed();
on_notification_default_delay_changed(); on_notification_default_delay_changed();
last_loaded_notification_date_ = std::numeric_limits<int32>::max();
load_message_notification_groups_from_database(false);
// TODO send updateActiveNotifications // TODO send updateActiveNotifications
} }
@ -103,7 +108,8 @@ NotificationManager::NotificationGroups::iterator NotificationManager::get_group
return groups_.end(); return groups_.end();
} }
NotificationManager::NotificationGroups::iterator NotificationManager::get_group_force(NotificationGroupId group_id) { NotificationManager::NotificationGroups::iterator NotificationManager::get_group_force(NotificationGroupId group_id,
bool send_update) {
auto group_it = get_group(group_id); auto group_it = get_group(group_id);
if (group_it != groups_.end()) { if (group_it != groups_.end()) {
return group_it; return group_it;
@ -114,23 +120,44 @@ NotificationManager::NotificationGroups::iterator NotificationManager::get_group
return groups_.end(); return groups_.end();
} }
NotificationGroupKey group_key; NotificationGroupKey group_key(group_id, message_group.dialog_id, 0);
group_key.group_id = group_id;
group_key.dialog_id = message_group.dialog_id;
group_key.last_notification_date = 0;
for (auto &notification : message_group.notifications) { for (auto &notification : message_group.notifications) {
if (notification.date >= group_key.last_notification_date) { if (notification.date > group_key.last_notification_date) {
group_key.last_notification_date = notification.date; group_key.last_notification_date = notification.date;
} }
} }
std::reverse(message_group.notifications.begin(), message_group.notifications.end());
NotificationGroup group; NotificationGroup group;
group.total_count = message_group.total_count; group.total_count = message_group.total_count;
group.notifications = std::move(message_group.notifications); group.notifications = std::move(message_group.notifications);
// TODO send update about the new group, if needed
return groups_.emplace(std::move(group_key), std::move(group)).first; return groups_.emplace(std::move(group_key), std::move(group)).first;
} }
void NotificationManager::load_message_notification_groups_from_database(bool send_update) {
if (last_loaded_notification_date_ == 0) {
// everything was already loaded
return;
}
vector<NotificationGroupKey> group_keys = td_->messages_manager_->get_message_notification_group_keys_from_database(
last_loaded_notification_date_, last_loaded_notification_dialog_id_, max_notification_group_count_);
if (group_keys.empty()) {
last_loaded_notification_date_ = 0;
last_loaded_notification_dialog_id_ = DialogId();
return;
}
last_loaded_notification_date_ = group_keys.back().last_notification_date;
last_loaded_notification_dialog_id_ = group_keys.back().dialog_id;
for (auto &group_key : group_keys) {
get_group_force(group_key.group_id, send_update);
}
}
int32 NotificationManager::get_max_notification_group_size() const { int32 NotificationManager::get_max_notification_group_size() const {
return max_notification_group_size_; return max_notification_group_size_;
} }
@ -159,7 +186,7 @@ NotificationGroupId NotificationManager::get_next_notification_group_id() {
return current_notification_group_id_; return current_notification_group_id_;
} }
NotificationManager::NotificationGroupKey NotificationManager::get_last_updated_group_key() const { NotificationGroupKey NotificationManager::get_last_updated_group_key() const {
int32 left = max_notification_group_count_; int32 left = max_notification_group_count_;
auto it = groups_.begin(); auto it = groups_.begin();
while (it != groups_.end() && left > 1) { while (it != groups_.end() && left > 1) {
@ -228,10 +255,7 @@ void NotificationManager::add_notification(NotificationGroupId group_id, DialogI
auto group_it = get_group_force(group_id); auto group_it = get_group_force(group_id);
if (group_it == groups_.end()) { if (group_it == groups_.end()) {
NotificationGroupKey group_key; NotificationGroupKey group_key(group_id, dialog_id, 0);
group_key.group_id = group_id;
group_key.dialog_id = dialog_id;
group_key.last_notification_date = 0;
group_it = std::move(groups_.emplace(group_key, NotificationGroup()).first); group_it = std::move(groups_.emplace(group_key, NotificationGroup()).first);
} }

View File

@ -5,11 +5,11 @@
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// //
#pragma once #pragma once
#include "td/telegram/DialogId.h" #include "td/telegram/DialogId.h"
#include "td/telegram/MessageId.h" #include "td/telegram/MessageId.h"
#include "td/telegram/Notification.h" #include "td/telegram/Notification.h"
#include "td/telegram/NotificationGroupId.h" #include "td/telegram/NotificationGroupId.h"
#include "td/telegram/NotificationGroupKey.h"
#include "td/telegram/NotificationId.h" #include "td/telegram/NotificationId.h"
#include "td/telegram/NotificationType.h" #include "td/telegram/NotificationType.h"
#include "td/telegram/td_api.h" #include "td/telegram/td_api.h"
@ -101,26 +101,6 @@ class NotificationManager : public Actor {
unique_ptr<NotificationType> type; unique_ptr<NotificationType> type;
}; };
struct NotificationGroupKey {
NotificationGroupId group_id;
DialogId dialog_id;
int32 last_notification_date = 0;
bool operator<(const NotificationGroupKey &other) const {
if (last_notification_date != other.last_notification_date) {
return last_notification_date > other.last_notification_date;
}
if (dialog_id != other.dialog_id) {
return dialog_id.get() > other.dialog_id.get();
}
return group_id.get() > other.group_id.get();
}
friend StringBuilder &operator<<(StringBuilder &string_builder, const NotificationGroupKey &group_key) {
return string_builder << '[' << group_key.group_id << ',' << group_key.dialog_id << ','
<< group_key.last_notification_date << ']';
}
};
struct NotificationGroup { struct NotificationGroup {
int32 total_count = 0; int32 total_count = 0;
@ -150,7 +130,9 @@ class NotificationManager : public Actor {
NotificationGroups::iterator get_group(NotificationGroupId group_id); NotificationGroups::iterator get_group(NotificationGroupId group_id);
NotificationGroups::iterator get_group_force(NotificationGroupId group_id); NotificationGroups::iterator get_group_force(NotificationGroupId group_id, bool send_update = true);
void load_message_notification_groups_from_database(bool send_update);
NotificationGroupKey get_last_updated_group_key() const; NotificationGroupKey get_last_updated_group_key() const;
@ -191,6 +173,9 @@ class NotificationManager : public Actor {
int32 notification_cloud_delay_ms_ = DEFAULT_ONLINE_CLOUD_DELAY_MS; int32 notification_cloud_delay_ms_ = DEFAULT_ONLINE_CLOUD_DELAY_MS;
int32 notification_default_delay_ms_ = DEFAULT_DEFAULT_DELAY_MS; int32 notification_default_delay_ms_ = DEFAULT_DEFAULT_DELAY_MS;
int32 last_loaded_notification_date_ = 0;
DialogId last_loaded_notification_dialog_id_;
bool running_get_difference_ = false; bool running_get_difference_ = false;
std::unordered_set<int32> running_get_chat_difference_; std::unordered_set<int32> running_get_chat_difference_;