/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once namespace Storage { struct SparseIdsListQuery { SparseIdsListQuery( MsgId aroundId, int limitBefore, int limitAfter) : aroundId(aroundId) , limitBefore(limitBefore) , limitAfter(limitAfter) { } MsgId aroundId = 0; int limitBefore = 0; int limitAfter = 0; }; struct SparseIdsListResult { std::optional count; std::optional skippedBefore; std::optional skippedAfter; base::flat_set messageIds; }; struct SparseIdsSliceUpdate { const base::flat_set *messages = nullptr; MsgRange range; std::optional count; }; class SparseIdsList { public: void addNew(MsgId messageId); void addExisting(MsgId messageId, MsgRange noSkipRange); void addSlice( std::vector &&messageIds, MsgRange noSkipRange, std::optional count); void removeOne(MsgId messageId); void removeAll(); void invalidateBottom(); rpl::producer query(SparseIdsListQuery &&query) const; rpl::producer sliceUpdated() const; SparseIdsListResult snapshot(const SparseIdsListQuery &query) const; bool empty() const; private: struct Slice { Slice(base::flat_set &&messages, MsgRange range); template void merge(const Range &moreMessages, MsgRange moreNoSkipRange); base::flat_set messages; MsgRange range; inline bool operator<(const Slice &other) const { return range.from < other.range.from; } }; struct AddResult { int added = 0; }; template AddResult uniteAndAdd( SparseIdsSliceUpdate &update, base::flat_set::iterator uniteFrom, base::flat_set::iterator uniteTill, const Range &messages, MsgRange noSkipRange); template AddResult addRangeItemsAndCountNew( SparseIdsSliceUpdate &update, const Range &messages, MsgRange noSkipRange); template void addRange( const Range &messages, MsgRange noSkipRange, std::optional count, bool incrementCount = false); SparseIdsListResult queryFromSlice( const SparseIdsListQuery &query, const Slice &slice) const; std::optional _count; base::flat_set _slices; rpl::event_stream _sliceUpdated; }; } // namespace Storage