aboutsummaryrefslogtreecommitdiffhomepage
path: root/td/telegram/NotificationGroupInfo.cpp
blob: 774b099c49c40ca15449459d3be8d7a75667881a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2026
//
// 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/NotificationGroupInfo.h"

#include "td/telegram/NotificationManager.h"

#include "td/utils/logging.h"

namespace td {

bool NotificationGroupInfo::set_last_notification(int32 last_notification_date, NotificationId last_notification_id,
                                                  const char *source) {
  if (is_removed_notification_id(last_notification_id)) {
    last_notification_id = NotificationId();
    last_notification_date = 0;
  }
  if (last_notification_date_ != last_notification_date || last_notification_id_ != last_notification_id) {
    VLOG(notifications) << "Set " << group_id_ << " last notification to " << last_notification_id << " sent at "
                        << last_notification_date << " from " << source;
    if (last_notification_date_ != last_notification_date) {
      last_notification_date_ = last_notification_date;
      is_key_changed_ = true;
    }
    last_notification_id_ = last_notification_id;
    return true;
  }
  return false;
}

bool NotificationGroupInfo::set_max_removed_notification_id(NotificationId max_removed_notification_id,
                                                            NotificationObjectId max_removed_object_id,
                                                            const char *source) {
  if (max_removed_notification_id.get() <= max_removed_notification_id_.get()) {
    return false;
  }
  if (max_removed_object_id > max_removed_object_id_) {
    VLOG(notifications) << "Set max_removed_object_id in " << group_id_ << " to " << max_removed_object_id << " from "
                        << source;
    max_removed_object_id_ = max_removed_object_id;
  }

  VLOG(notifications) << "Set max_removed_notification_id in " << group_id_ << " to " << max_removed_notification_id
                      << " from " << source;
  max_removed_notification_id_ = max_removed_notification_id;

  if (last_notification_id_.is_valid() && is_removed_notification_id(last_notification_id_)) {
    last_notification_id_ = NotificationId();
    last_notification_date_ = 0;
    is_key_changed_ = true;
  }

  return true;
}

void NotificationGroupInfo::drop_max_removed_notification_id() {
  if (!max_removed_notification_id_.is_valid()) {
    return;
  }

  VLOG(notifications) << "Drop max_removed_notification_id in " << group_id_;
  max_removed_object_id_ = {};
  max_removed_notification_id_ = NotificationId();
}

bool NotificationGroupInfo::is_removed_notification(NotificationId notification_id,
                                                    NotificationObjectId object_id) const {
  return is_removed_notification_id(notification_id) || is_removed_object_id(object_id);
}

bool NotificationGroupInfo::is_removed_notification_id(NotificationId notification_id) const {
  return notification_id.get() <= max_removed_notification_id_.get();
}

bool NotificationGroupInfo::is_removed_object_id(NotificationObjectId object_id) const {
  return object_id <= max_removed_object_id_;
}

bool NotificationGroupInfo::is_used_notification_id(NotificationId notification_id) const {
  return notification_id.get() <= max_removed_notification_id_.get() ||
         notification_id.get() <= last_notification_id_.get();
}

void NotificationGroupInfo::try_reuse() {
  CHECK(is_valid());
  CHECK(last_notification_date_ == 0);
  if (!try_reuse_) {
    try_reuse_ = true;
    is_key_changed_ = true;
  }
}

void NotificationGroupInfo::add_group_key_if_changed(vector<NotificationGroupKey> &group_keys, DialogId dialog_id) {
  if (!is_key_changed_) {
    return;
  }
  is_key_changed_ = false;

  group_keys.emplace_back(group_id_, try_reuse_ ? DialogId() : dialog_id, last_notification_date_);
}

NotificationGroupId NotificationGroupInfo::get_reused_group_id() {
  if (!try_reuse_) {
    return {};
  }
  if (is_key_changed_) {
    LOG(ERROR) << "Failed to reuse changed " << group_id_;
    return {};
  }
  try_reuse_ = false;
  if (!is_valid()) {
    LOG(ERROR) << "Failed to reuse invalid " << group_id_;
    return {};
  }
  CHECK(last_notification_id_ == NotificationId());
  CHECK(last_notification_date_ == 0);
  auto result = group_id_;
  group_id_ = NotificationGroupId();
  max_removed_notification_id_ = NotificationId();
  max_removed_object_id_ = {};
  return result;
}

StringBuilder &operator<<(StringBuilder &string_builder, const NotificationGroupInfo &group_info) {
  return string_builder << group_info.group_id_ << " with last " << group_info.last_notification_id_ << " sent at "
                        << group_info.last_notification_date_ << ", max removed "
                        << group_info.max_removed_notification_id_ << '/' << group_info.max_removed_object_id_;
}

}  // namespace td