/* 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 { base::optional count; base::optional skippedBefore; base::optional skippedAfter; base::flat_set messageIds; }; struct SparseIdsSliceUpdate { const base::flat_set *messages = nullptr; MsgRange range; base::optional count; }; class SparseIdsList { public: void addNew(MsgId messageId); void addExisting(MsgId messageId, MsgRange noSkipRange); void addSlice( std::vector &&messageIds, MsgRange noSkipRange, base::optional count); void removeOne(MsgId messageId); void removeAll(); void invalidateBottom(); rpl::producer query(SparseIdsListQuery &&query) const; rpl::producer sliceUpdated() 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; } }; template int uniteAndAdd( SparseIdsSliceUpdate &update, base::flat_set::iterator uniteFrom, base::flat_set::iterator uniteTill, const Range &messages, MsgRange noSkipRange); template int addRangeItemsAndCountNew( SparseIdsSliceUpdate &update, const Range &messages, MsgRange noSkipRange); template void addRange( const Range &messages, MsgRange noSkipRange, base::optional count, bool incrementCount = false); SparseIdsListResult queryFromSlice( const SparseIdsListQuery &query, const Slice &slice) const; base::optional _count; base::flat_set _slices; rpl::event_stream _sliceUpdated; }; } // namespace Storage