Cache: Save more chats and less users

This commit is contained in:
Alexander Zinchuk 2022-02-11 15:13:12 +01:00
parent f5a019e02a
commit 94cdf97b0b
4 changed files with 68 additions and 39 deletions

View File

@ -20,8 +20,9 @@ export const LEGACY_SESSION_KEY = 'GramJs:sessionId';
export const GLOBAL_STATE_CACHE_DISABLED = false; export const GLOBAL_STATE_CACHE_DISABLED = false;
export const GLOBAL_STATE_CACHE_KEY = 'tt-global-state'; export const GLOBAL_STATE_CACHE_KEY = 'tt-global-state';
export const GLOBAL_STATE_CACHE_CHAT_LIST_LIMIT = 30; export const GLOBAL_STATE_CACHE_USER_LIST_LIMIT = 500;
export const GLOBAL_STATE_CACHE_USER_LIST_LIMIT = 5000; export const GLOBAL_STATE_CACHE_CHAT_LIST_LIMIT = 200;
export const GLOBAL_STATE_CACHE_CHATS_WITH_MESSAGES_LIMIT = 30;
export const MEDIA_CACHE_DISABLED = false; export const MEDIA_CACHE_DISABLED = false;
export const MEDIA_CACHE_NAME = 'tt-media'; export const MEDIA_CACHE_NAME = 'tt-media';

View File

@ -10,21 +10,29 @@ import {
DEBUG, DEBUG,
GLOBAL_STATE_CACHE_DISABLED, GLOBAL_STATE_CACHE_DISABLED,
GLOBAL_STATE_CACHE_KEY, GLOBAL_STATE_CACHE_KEY,
GLOBAL_STATE_CACHE_CHAT_LIST_LIMIT,
MIN_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN,
GLOBAL_STATE_CACHE_USER_LIST_LIMIT, GLOBAL_STATE_CACHE_USER_LIST_LIMIT,
GLOBAL_STATE_CACHE_CHAT_LIST_LIMIT,
GLOBAL_STATE_CACHE_CHATS_WITH_MESSAGES_LIMIT,
MIN_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN,
DEFAULT_VOLUME, DEFAULT_VOLUME,
DEFAULT_PLAYBACK_RATE, DEFAULT_PLAYBACK_RATE,
ALL_FOLDER_ID,
ARCHIVED_FOLDER_ID,
} from '../config'; } from '../config';
import { IS_SINGLE_COLUMN_LAYOUT } from '../util/environment'; import { IS_SINGLE_COLUMN_LAYOUT } from '../util/environment';
import { isHeavyAnimating } from '../hooks/useHeavyAnimationCheck'; import { isHeavyAnimating } from '../hooks/useHeavyAnimationCheck';
import { pick } from '../util/iteratees'; import { pick, unique } from '../util/iteratees';
import { selectCurrentMessageList } from '../modules/selectors'; import {
selectCurrentChat,
selectCurrentMessageList,
selectVisibleUsers,
} from '../modules/selectors';
import { hasStoredSession } from '../util/sessions'; import { hasStoredSession } from '../util/sessions';
import { INITIAL_STATE } from './initial'; import { INITIAL_STATE } from './initial';
import { parseLocationHash } from '../util/routing'; import { parseLocationHash } from '../util/routing';
import { LOCATION_HASH } from '../hooks/useHistoryBack'; import { LOCATION_HASH } from '../hooks/useHistoryBack';
import { isUserId } from '../modules/helpers'; import { isUserId } from '../modules/helpers';
import { getOrderedIds } from '../util/folderManager';
const UPDATE_THROTTLE = 5000; const UPDATE_THROTTLE = 5000;
@ -263,10 +271,21 @@ function reduceShowChatInfo(global: GlobalState): boolean {
} }
function reduceUsers(global: GlobalState): GlobalState['users'] { function reduceUsers(global: GlobalState): GlobalState['users'] {
const { users: { byId, statusesById } } = global; const { users: { byId, statusesById }, currentUserId } = global;
const chatIds = (global.chats.listIds.active || []).slice(0, GLOBAL_STATE_CACHE_CHAT_LIST_LIMIT).filter(isUserId); const { chatId: currentChatId } = selectCurrentMessageList(global) || {};
const userIds = Object.keys(byId); const visibleUserIds = selectVisibleUsers(global)?.map(({ id }) => id);
const idsToSave = chatIds.concat(userIds).slice(0, GLOBAL_STATE_CACHE_USER_LIST_LIMIT);
const idsToSave = unique([
...currentUserId ? [currentUserId] : [],
...currentChatId && isUserId(currentChatId) ? [currentChatId] : [],
...visibleUserIds || [],
...global.topPeers.userIds || [],
...getOrderedIds(ALL_FOLDER_ID)?.filter(isUserId) || [],
...getOrderedIds(ARCHIVED_FOLDER_ID)?.filter(isUserId) || [],
...global.contactList?.userIds || [],
...global.globalSearch.recentlyFoundChatIds?.filter(isUserId) || [],
...Object.keys(byId),
]).slice(0, GLOBAL_STATE_CACHE_USER_LIST_LIMIT);
return { return {
byId: pick(byId, idsToSave), byId: pick(byId, idsToSave),
@ -275,29 +294,33 @@ function reduceUsers(global: GlobalState): GlobalState['users'] {
} }
function reduceChats(global: GlobalState): GlobalState['chats'] { function reduceChats(global: GlobalState): GlobalState['chats'] {
const newListIds = (global.chats.listIds.active || []).slice(0, GLOBAL_STATE_CACHE_CHAT_LIST_LIMIT); const { chats: { byId }, currentUserId } = global;
const { chatId: currentChatId } = selectCurrentMessageList(global) || {}; const currentChat = selectCurrentChat(global);
const idsToSave = newListIds.concat(currentChatId ? [currentChatId] : []); const idsToSave = unique([
...currentUserId ? [currentUserId] : [],
...currentChat ? [currentChat.id] : [],
...getOrderedIds(ALL_FOLDER_ID) || [],
...getOrderedIds(ARCHIVED_FOLDER_ID) || [],
...global.globalSearch.recentlyFoundChatIds || [],
...Object.keys(byId),
]).slice(0, GLOBAL_STATE_CACHE_CHAT_LIST_LIMIT);
return { return {
...global.chats, ...global.chats,
byId: pick(global.chats.byId, idsToSave),
listIds: {
active: newListIds,
},
isFullyLoaded: {}, isFullyLoaded: {},
orderedPinnedIds: { byId: pick(global.chats.byId, idsToSave),
active: global.chats.orderedPinnedIds.active,
},
}; };
} }
function reduceMessages(global: GlobalState): GlobalState['messages'] { function reduceMessages(global: GlobalState): GlobalState['messages'] {
const { currentUserId } = global;
const byChatId: GlobalState['messages']['byChatId'] = {}; const byChatId: GlobalState['messages']['byChatId'] = {};
const { chatId: currentChatId } = selectCurrentMessageList(global) || {}; const { chatId: currentChatId } = selectCurrentMessageList(global) || {};
const chatIdsToSave = [
const chatIds = (global.chats.listIds.active || []).slice(0, GLOBAL_STATE_CACHE_CHAT_LIST_LIMIT); ...currentChatId ? [currentChatId] : [],
const chatIdsToSave = chatIds.concat(currentChatId ? [currentChatId] : []); ...currentUserId ? [currentUserId] : [],
...getOrderedIds(ALL_FOLDER_ID)?.slice(0, GLOBAL_STATE_CACHE_CHATS_WITH_MESSAGES_LIMIT) || [],
];
chatIdsToSave.forEach((chatId) => { chatIdsToSave.forEach((chatId) => {
const current = global.messages.byChatId[chatId]; const current = global.messages.byChatId[chatId];

View File

@ -29,7 +29,7 @@ import {
selectChat, selectUser, selectChatListType, selectIsChatPinned, selectChat, selectUser, selectChatListType, selectIsChatPinned,
selectChatFolder, selectSupportChat, selectChatByUsername, selectThreadTopMessageId, selectChatFolder, selectSupportChat, selectChatByUsername, selectThreadTopMessageId,
selectCurrentMessageList, selectThreadInfo, selectCurrentChat, selectLastServiceNotification, selectCurrentMessageList, selectThreadInfo, selectCurrentChat, selectLastServiceNotification,
selectThreadParam, selectChatMessage, selectVisibleUsers,
} from '../../selectors'; } from '../../selectors';
import { buildCollectionByKey, omit } from '../../../util/iteratees'; import { buildCollectionByKey, omit } from '../../../util/iteratees';
import { debounce, pause, throttle } from '../../../util/schedulers'; import { debounce, pause, throttle } from '../../../util/schedulers';
@ -1011,23 +1011,10 @@ async function loadChats(
global = getGlobal(); global = getGlobal();
if (shouldReplace && listType === 'active') { if (shouldReplace && listType === 'active') {
const visibleChats = [];
const visibleUsers = [];
const currentChat = selectCurrentChat(global); const currentChat = selectCurrentChat(global);
if (currentChat) { const visibleChats = currentChat ? [currentChat] : [];
const { threadId } = selectCurrentMessageList(global)!;
visibleChats.push(currentChat);
const messageIds = selectThreadParam(global, currentChat.id, threadId, 'viewportIds');
const messageSenders = messageIds ? messageIds
.map((messageId) => {
const { senderId } = selectChatMessage(global, currentChat.id, messageId) || {};
return senderId ? selectUser(global, senderId) : undefined;
})
.filter(Boolean) : [];
visibleUsers.push(...messageSenders);
}
const visibleUsers = selectVisibleUsers(global) || [];
if (global.currentUserId && global.users.byId[global.currentUserId]) { if (global.currentUserId && global.users.byId[global.currentUserId]) {
visibleUsers.push(global.users.byId[global.currentUserId]); visibleUsers.push(global.users.byId[global.currentUserId]);
} }

View File

@ -904,3 +904,21 @@ export function selectDefaultReaction(global: GlobalState, chatId: string) {
return defaultReaction; return defaultReaction;
} }
// Slow, not to be used in `withGlobal`
export function selectVisibleUsers(global: GlobalState) {
const { chatId, threadId } = selectCurrentMessageList(global) || {};
if (!chatId || !threadId) {
return undefined;
}
const messageIds = selectThreadParam(global, chatId, threadId, 'viewportIds');
if (!messageIds) {
return undefined;
}
return messageIds.map((messageId) => {
const { senderId } = selectChatMessage(global, chatId, messageId) || {};
return senderId ? selectUser(global, senderId) : undefined;
}).filter(Boolean);
}