private List <MailMessageData> GetFilteredConversations(IDaoFactory daoFactory, MailSearchFilterData filter, out bool hasMore) { var conversations = new List <MailMessageData>(); var skipFlag = false; var chunkIndex = 0; if (filter.FromDate.HasValue && filter.FromMessage.HasValue && filter.FromMessage.Value > 0) { skipFlag = true; } var prevFlag = filter.PrevFlag.GetValueOrDefault(false); var tenantInfo = CoreContext.TenantManager.GetTenant(Tenant); var utcNow = DateTime.UtcNow; var pageSize = filter.PageSize.GetValueOrDefault(25); var daoMailInfo = daoFactory.CreateMailInfoDao(Tenant, User); while (conversations.Count < pageSize + 1) { filter.PageSize = CHUNK_SIZE * pageSize; IMessagesExp exp = null; if (!filter.IsDefault() && FactoryIndexer <MailWrapper> .Support && FactoryIndexer.CheckState(false)) { filter.Page = chunkIndex * CHUNK_SIZE * pageSize; // Elastic Limit from {index of last message} to {count of messages} List <MailWrapper> mailWrappers; if (FilterChainMessagesExp.TryGetFullTextSearchChains(filter, User, out mailWrappers)) { if (!mailWrappers.Any()) { break; } var ids = mailWrappers.Select(c => c.Id).ToList(); var query = SimpleMessagesExp.CreateBuilder(Tenant, User) .SetMessageIds(ids) .SetOrderBy(filter.Sort); if (prevFlag) { query.SetOrderAsc(!(filter.SortOrder == Defines.ASCENDING)); } else { query.SetOrderAsc(filter.SortOrder == Defines.ASCENDING); } exp = query .Build(); } } else { filter.Page = chunkIndex; // MySQL Limit from {page by size} to {size} exp = new FilterChainMessagesExp(filter, Tenant, User); } chunkIndex++; var listMessages = daoMailInfo.GetMailInfoList(exp, true) .ConvertAll(m => MessageEngine.ToMailMessage(m, tenantInfo, utcNow)); if (0 == listMessages.Count) { break; } if (skipFlag && filter.FromMessage.HasValue) { var messageData = listMessages.FirstOrDefault(m => m.Id == filter.FromMessage.Value); if (messageData != null) { // Skip chain messages by FromMessage. listMessages = listMessages.Where( m => !(m.ChainId.Equals(messageData.ChainId) && m.MailboxId == messageData.MailboxId)) .ToList(); } skipFlag = false; } foreach (var messageData in listMessages) { var existingChainIndex = conversations.FindIndex( c => c.ChainId == messageData.ChainId && c.MailboxId == messageData.MailboxId); if (existingChainIndex > -1) { if (conversations[existingChainIndex].Date < messageData.Date) { conversations[existingChainIndex] = messageData; } } else { conversations.Add(messageData); } } if (conversations.Count > pageSize) { break; } } hasMore = conversations.Count > pageSize; if (hasMore) { conversations = conversations.Take(pageSize).ToList(); } if (prevFlag) { conversations.Reverse(); } return(conversations); }