Just compute scheduled ids instead of a lookup.

This commit is contained in:
John Preston 2022-03-11 11:25:30 +04:00
parent 1833fac094
commit 5be72e8ce2
4 changed files with 35 additions and 28 deletions

View file

@ -23,6 +23,19 @@ namespace {
constexpr auto kRequestTimeLimit = 60 * crl::time(1000); constexpr auto kRequestTimeLimit = 60 * crl::time(1000);
[[nodiscard]] MsgId RemoteToLocalMsgId(MsgId id) {
Expects(IsServerMsgId(id));
return ServerMaxMsgId + id + 1;
}
[[nodiscard]] MsgId LocalToRemoteMsgId(MsgId id) {
Expects(id > ServerMaxMsgId);
Expects(id < ServerMaxMsgId + ScheduledMsgIdsRange);
return (id - ServerMaxMsgId - 1);
}
[[nodiscard]] bool TooEarlyForRequest(crl::time received) { [[nodiscard]] bool TooEarlyForRequest(crl::time received) {
return (received > 0) && (received + kRequestTimeLimit > crl::now()); return (received > 0) && (received + kRequestTimeLimit > crl::now());
} }
@ -32,7 +45,7 @@ constexpr auto kRequestTimeLimit = 60 * crl::time(1000);
&& (item->date() > base::unixtime::now()); && (item->date() > base::unixtime::now());
} }
MTPMessage PrepareMessage(const MTPMessage &message) { [[nodiscard]] MTPMessage PrepareMessage(const MTPMessage &message) {
return message.match([&](const MTPDmessageEmpty &data) { return message.match([&](const MTPDmessageEmpty &data) {
return MTP_messageEmpty( return MTP_messageEmpty(
data.vflags(), data.vflags(),
@ -112,15 +125,16 @@ void ScheduledMessages::clearOldRequests() {
} }
} }
MsgId ScheduledMessages::lookupId(not_null<HistoryItem*> item) const { MsgId ScheduledMessages::localMessageId(MsgId remoteId) const {
Expects(item->isScheduled()); return RemoteToLocalMsgId(remoteId);
}
const auto i = _data.find(item->history()); MsgId ScheduledMessages::lookupId(not_null<const HistoryItem*> item) const {
Assert(i != end(_data)); Expects(item->isScheduled());
const auto &list = i->second; Expects(!item->isSending());
const auto j = list.idByItem.find(item); Expects(!item->hasFailed());
Assert(j != end(list.idByItem));
return j->second; return LocalToRemoteMsgId(item->id);
} }
HistoryItem *ScheduledMessages::lookupItem(PeerId peer, MsgId msg) const { HistoryItem *ScheduledMessages::lookupItem(PeerId peer, MsgId msg) const {
@ -314,13 +328,11 @@ void ScheduledMessages::apply(
Assert(i != end(_data)); Assert(i != end(_data));
auto &list = i->second; auto &list = i->second;
const auto j = list.itemById.find(id); const auto j = list.itemById.find(id);
if (j != end(list.itemById)) { if (j != end(list.itemById) || !IsServerMsgId(id)) {
local->destroy(); local->destroy();
} else { } else {
Assert(!list.itemById.contains(local->id)); Assert(!list.itemById.contains(local->id));
Assert(!list.idByItem.contains(local)); local->setRealId(localMessageId(id));
local->setRealId(local->history()->scheduledMessageId(id));
list.idByItem.emplace(local, id);
list.itemById.emplace(id, local); list.itemById.emplace(id, local);
} }
} }
@ -466,8 +478,12 @@ HistoryItem *ScheduledMessages::append(
return existing; return existing;
} }
if (!IsServerMsgId(id)) {
LOG(("API Error: Bad id in scheduled messages: %1.").arg(id));
return nullptr;
}
const auto item = _session->data().addNewMessage( const auto item = _session->data().addNewMessage(
history->scheduledMessageId(id), localMessageId(id),
PrepareMessage(message), PrepareMessage(message),
MessageFlags(), // localFlags MessageFlags(), // localFlags
NewMessageType::Existing); NewMessageType::Existing);
@ -477,7 +493,6 @@ HistoryItem *ScheduledMessages::append(
} }
list.items.emplace_back(item); list.items.emplace_back(item);
list.itemById.emplace(id, item); list.itemById.emplace(id, item);
list.idByItem.emplace(item, id);
return item; return item;
} }
@ -524,10 +539,7 @@ void ScheduledMessages::remove(not_null<const HistoryItem*> item) {
auto &list = i->second; auto &list = i->second;
if (!item->isSending() && !item->hasFailed()) { if (!item->isSending() && !item->hasFailed()) {
const auto j = list.idByItem.find(item); list.itemById.remove(lookupId(item));
Assert(j != end(list.idByItem));
list.itemById.remove(j->second);
list.idByItem.erase(j);
} }
const auto k = ranges::find(list.items, item, &OwnedItem::get); const auto k = ranges::find(list.items, item, &OwnedItem::get);
Assert(k != list.items.end()); Assert(k != list.items.end());
@ -550,8 +562,7 @@ uint64 ScheduledMessages::countListHash(const List &list) const {
return !item->isSending() && !item->hasFailed(); return !item->isSending() && !item->hasFailed();
}) | ranges::views::reverse; }) | ranges::views::reverse;
for (const auto &item : serverside) { for (const auto &item : serverside) {
const auto j = list.idByItem.find(item.get()); HashUpdate(hash, lookupId(item.get()).bare);
HashUpdate(hash, j->second.bare);
if (const auto edited = item->Get<HistoryMessageEdited>()) { if (const auto edited = item->Get<HistoryMessageEdited>()) {
HashUpdate(hash, edited->date); HashUpdate(hash, edited->date);
} else { } else {

View file

@ -28,7 +28,7 @@ public:
ScheduledMessages &operator=(const ScheduledMessages &other) = delete; ScheduledMessages &operator=(const ScheduledMessages &other) = delete;
~ScheduledMessages(); ~ScheduledMessages();
[[nodiscard]] MsgId lookupId(not_null<HistoryItem*> item) const; [[nodiscard]] MsgId lookupId(not_null<const HistoryItem*> item) const;
[[nodiscard]] HistoryItem *lookupItem(PeerId peer, MsgId msg) const; [[nodiscard]] HistoryItem *lookupItem(PeerId peer, MsgId msg) const;
[[nodiscard]] HistoryItem *lookupItem(FullMsgId itemId) const; [[nodiscard]] HistoryItem *lookupItem(FullMsgId itemId) const;
[[nodiscard]] int count(not_null<History*> history) const; [[nodiscard]] int count(not_null<History*> history) const;
@ -57,7 +57,6 @@ private:
struct List { struct List {
std::vector<OwnedItem> items; std::vector<OwnedItem> items;
base::flat_map<MsgId, not_null<HistoryItem*>> itemById; base::flat_map<MsgId, not_null<HistoryItem*>> itemById;
base::flat_map<not_null<HistoryItem*>, MsgId> idByItem;
}; };
struct Request { struct Request {
mtpRequestId requestId = 0; mtpRequestId requestId = 0;
@ -82,6 +81,8 @@ private:
[[nodiscard]] uint64 countListHash(const List &list) const; [[nodiscard]] uint64 countListHash(const List &list) const;
void clearOldRequests(); void clearOldRequests();
[[nodiscard]] MsgId localMessageId(MsgId remoteId) const;
const not_null<Main::Session*> _session; const not_null<Main::Session*> _session;
base::Timer _clearTimer; base::Timer _clearTimer;

View file

@ -1760,10 +1760,6 @@ MsgId History::nextNonHistoryEntryId() {
return owner().nextNonHistoryEntryId(); return owner().nextNonHistoryEntryId();
} }
MsgId History::scheduledMessageId(MsgId remoteScheduledMsgId) const {
return ServerMaxMsgId + remoteScheduledMsgId + 1;
}
bool History::folderKnown() const { bool History::folderKnown() const {
return _folder.has_value(); return _folder.has_value();
} }

View file

@ -439,7 +439,6 @@ public:
[[nodiscard]] std::pair<Element*, int> findItemAndOffset(int top) const; [[nodiscard]] std::pair<Element*, int> findItemAndOffset(int top) const;
[[nodiscard]] MsgId nextNonHistoryEntryId(); [[nodiscard]] MsgId nextNonHistoryEntryId();
[[nodiscard]] MsgId scheduledMessageId(MsgId remoteScheduledMsgId) const;
bool folderKnown() const override; bool folderKnown() const override;
Data::Folder *folder() const override; Data::Folder *folder() const override;