diff --git a/store/sqlstore/post_store.go b/store/sqlstore/post_store.go index cafca3d666..0364ca3802 100644 --- a/store/sqlstore/post_store.go +++ b/store/sqlstore/post_store.go @@ -819,33 +819,31 @@ func (s *SqlPostStore) prepareThreadedResponse(posts []*postWithExtra, extended, } } } - var users []*model.User + // usersMap is the global profile map of all participants from all threads. + usersMap := make(map[string]*model.User, len(userIds)) if extended { - var err error - users, err = s.User().GetProfileByIds(context.Background(), userIds, &store.UserGetByIdsOpts{}, true) + users, err := s.User().GetProfileByIds(context.Background(), userIds, &store.UserGetByIdsOpts{}, true) if err != nil { return nil, err } + for _, user := range users { + usersMap[user.Id] = user + } } else { for _, userId := range userIds { - users = append(users, &model.User{Id: userId}) + usersMap[userId] = &model.User{Id: userId} } } + processPost := func(p *postWithExtra) error { p.Post.ReplyCount = p.ThreadReplyCount if p.IsFollowing != nil { p.Post.IsFollowing = model.NewBool(*p.IsFollowing) } - for _, th := range p.ThreadParticipants { - var participant *model.User - for _, u := range users { - if u.Id == th { - participant = u - break - } - } - if participant == nil { - return errors.New("cannot find thread participant with id=" + th) + for _, userID := range p.ThreadParticipants { + participant, ok := usersMap[userID] + if !ok { + return errors.New("cannot find thread participant with id=" + userID) } p.Post.Participants = append(p.Post.Participants, participant) } diff --git a/store/sqlstore/thread_store.go b/store/sqlstore/thread_store.go index 8a1cce8f20..9592a1eee9 100644 --- a/store/sqlstore/thread_store.go +++ b/store/sqlstore/thread_store.go @@ -291,7 +291,10 @@ func (s *SqlThreadStore) GetThreadsForUser(userId, teamId string, opts model.Get } totalUnreadThreads := totalUnreadThreadsResult.Data.(int64) + // userIds is the de-duped list of participant ids from all threads. var userIds []string + // userIdMap is the map of participant ids from all threads. + // Used to generate userIds userIdMap := map[string]bool{} result := &model.Threads{ @@ -315,30 +318,30 @@ func (s *SqlThreadStore) GetThreadsForUser(userId, teamId string, opts model.Get } } } - var users []*model.User + // usersMap is the global profile map of all participants from all threads. + usersMap := make(map[string]*model.User, len(userIds)) if opts.Extended { - var err error - users, err = s.User().GetProfileByIds(context.Background(), userIds, &store.UserGetByIdsOpts{}, true) + users, err := s.User().GetProfileByIds(context.Background(), userIds, &store.UserGetByIdsOpts{}, true) if err != nil { return nil, errors.Wrapf(err, "failed to get threads for user id=%s", userId) } + for _, user := range users { + usersMap[user.Id] = user + } } else { for _, userId := range userIds { - users = append(users, &model.User{Id: userId}) + usersMap[userId] = &model.User{Id: userId} } } + result.Threads = make([]*model.ThreadResponse, 0, len(threads)) for _, thread := range threads { - var participants []*model.User + participants := make([]*model.User, 0, len(thread.Participants)) + // We get the user profiles for only a single thread filtered from the + // global users map. for _, participantId := range thread.Participants { - var participant *model.User - for _, u := range users { - if u.Id == participantId { - participant = u - break - } - } - if participant == nil { + participant, ok := usersMap[participantId] + if !ok { return nil, errors.New("cannot find thread participant with id=" + participantId) } participants = append(participants, participant)