Add generic set type (#21408)

This PR adds a generic set type to get rid of maps used as sets.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
KN4CK3R 2022-10-12 07:18:26 +02:00 committed by GitHub
parent e84558b093
commit 0e57ff7eee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 328 additions and 324 deletions

View file

@ -18,13 +18,11 @@ import (
type ActionList []*Action
func (actions ActionList) getUserIDs() []int64 {
userIDs := make(map[int64]struct{}, len(actions))
userIDs := make(container.Set[int64], len(actions))
for _, action := range actions {
if _, ok := userIDs[action.ActUserID]; !ok {
userIDs[action.ActUserID] = struct{}{}
}
userIDs.Add(action.ActUserID)
}
return container.KeysInt64(userIDs)
return userIDs.Values()
}
func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.User, error) {
@ -48,13 +46,11 @@ func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.
}
func (actions ActionList) getRepoIDs() []int64 {
repoIDs := make(map[int64]struct{}, len(actions))
repoIDs := make(container.Set[int64], len(actions))
for _, action := range actions {
if _, ok := repoIDs[action.RepoID]; !ok {
repoIDs[action.RepoID] = struct{}{}
}
repoIDs.Add(action.RepoID)
}
return container.KeysInt64(repoIDs)
return repoIDs.Values()
}
func (actions ActionList) loadRepositories(ctx context.Context) error {

View file

@ -200,7 +200,7 @@ func CreateOrUpdateIssueNotifications(issueID, commentID, notificationAuthorID,
func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, notificationAuthorID, receiverID int64) error {
// init
var toNotify map[int64]struct{}
var toNotify container.Set[int64]
notifications, err := getNotificationsByIssueID(ctx, issueID)
if err != nil {
return err
@ -212,33 +212,27 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n
}
if receiverID > 0 {
toNotify = make(map[int64]struct{}, 1)
toNotify[receiverID] = struct{}{}
toNotify = make(container.Set[int64], 1)
toNotify.Add(receiverID)
} else {
toNotify = make(map[int64]struct{}, 32)
toNotify = make(container.Set[int64], 32)
issueWatches, err := issues_model.GetIssueWatchersIDs(ctx, issueID, true)
if err != nil {
return err
}
for _, id := range issueWatches {
toNotify[id] = struct{}{}
}
toNotify.AddMultiple(issueWatches...)
if !(issue.IsPull && issues_model.HasWorkInProgressPrefix(issue.Title)) {
repoWatches, err := repo_model.GetRepoWatchersIDs(ctx, issue.RepoID)
if err != nil {
return err
}
for _, id := range repoWatches {
toNotify[id] = struct{}{}
}
toNotify.AddMultiple(repoWatches...)
}
issueParticipants, err := issue.GetParticipantIDsByIssue(ctx)
if err != nil {
return err
}
for _, id := range issueParticipants {
toNotify[id] = struct{}{}
}
toNotify.AddMultiple(issueParticipants...)
// dont notify user who cause notification
delete(toNotify, notificationAuthorID)
@ -248,7 +242,7 @@ func createOrUpdateIssueNotifications(ctx context.Context, issueID, commentID, n
return err
}
for _, id := range issueUnWatches {
delete(toNotify, id)
toNotify.Remove(id)
}
}
@ -499,16 +493,14 @@ func (nl NotificationList) LoadAttributes() error {
}
func (nl NotificationList) getPendingRepoIDs() []int64 {
ids := make(map[int64]struct{}, len(nl))
ids := make(container.Set[int64], len(nl))
for _, notification := range nl {
if notification.Repository != nil {
continue
}
if _, ok := ids[notification.RepoID]; !ok {
ids[notification.RepoID] = struct{}{}
}
ids.Add(notification.RepoID)
}
return container.KeysInt64(ids)
return ids.Values()
}
// LoadRepos loads repositories from database
@ -575,16 +567,14 @@ func (nl NotificationList) LoadRepos() (repo_model.RepositoryList, []int, error)
}
func (nl NotificationList) getPendingIssueIDs() []int64 {
ids := make(map[int64]struct{}, len(nl))
ids := make(container.Set[int64], len(nl))
for _, notification := range nl {
if notification.Issue != nil {
continue
}
if _, ok := ids[notification.IssueID]; !ok {
ids[notification.IssueID] = struct{}{}
}
ids.Add(notification.IssueID)
}
return container.KeysInt64(ids)
return ids.Values()
}
// LoadIssues loads issues from database
@ -661,16 +651,14 @@ func (nl NotificationList) Without(failures []int) NotificationList {
}
func (nl NotificationList) getPendingCommentIDs() []int64 {
ids := make(map[int64]struct{}, len(nl))
ids := make(container.Set[int64], len(nl))
for _, notification := range nl {
if notification.CommentID == 0 || notification.Comment != nil {
continue
}
if _, ok := ids[notification.CommentID]; !ok {
ids[notification.CommentID] = struct{}{}
}
ids.Add(notification.CommentID)
}
return container.KeysInt64(ids)
return ids.Values()
}
// LoadComments loads comments from database

View file

@ -17,13 +17,11 @@ import (
type CommentList []*Comment
func (comments CommentList) getPosterIDs() []int64 {
posterIDs := make(map[int64]struct{}, len(comments))
posterIDs := make(container.Set[int64], len(comments))
for _, comment := range comments {
if _, ok := posterIDs[comment.PosterID]; !ok {
posterIDs[comment.PosterID] = struct{}{}
}
posterIDs.Add(comment.PosterID)
}
return container.KeysInt64(posterIDs)
return posterIDs.Values()
}
func (comments CommentList) loadPosters(ctx context.Context) error {
@ -70,13 +68,11 @@ func (comments CommentList) getCommentIDs() []int64 {
}
func (comments CommentList) getLabelIDs() []int64 {
ids := make(map[int64]struct{}, len(comments))
ids := make(container.Set[int64], len(comments))
for _, comment := range comments {
if _, ok := ids[comment.LabelID]; !ok {
ids[comment.LabelID] = struct{}{}
}
ids.Add(comment.LabelID)
}
return container.KeysInt64(ids)
return ids.Values()
}
func (comments CommentList) loadLabels(ctx context.Context) error { //nolint
@ -120,13 +116,11 @@ func (comments CommentList) loadLabels(ctx context.Context) error { //nolint
}
func (comments CommentList) getMilestoneIDs() []int64 {
ids := make(map[int64]struct{}, len(comments))
ids := make(container.Set[int64], len(comments))
for _, comment := range comments {
if _, ok := ids[comment.MilestoneID]; !ok {
ids[comment.MilestoneID] = struct{}{}
}
ids.Add(comment.MilestoneID)
}
return container.KeysInt64(ids)
return ids.Values()
}
func (comments CommentList) loadMilestones(ctx context.Context) error {
@ -163,13 +157,11 @@ func (comments CommentList) loadMilestones(ctx context.Context) error {
}
func (comments CommentList) getOldMilestoneIDs() []int64 {
ids := make(map[int64]struct{}, len(comments))
ids := make(container.Set[int64], len(comments))
for _, comment := range comments {
if _, ok := ids[comment.OldMilestoneID]; !ok {
ids[comment.OldMilestoneID] = struct{}{}
}
ids.Add(comment.OldMilestoneID)
}
return container.KeysInt64(ids)
return ids.Values()
}
func (comments CommentList) loadOldMilestones(ctx context.Context) error {
@ -206,13 +198,11 @@ func (comments CommentList) loadOldMilestones(ctx context.Context) error {
}
func (comments CommentList) getAssigneeIDs() []int64 {
ids := make(map[int64]struct{}, len(comments))
ids := make(container.Set[int64], len(comments))
for _, comment := range comments {
if _, ok := ids[comment.AssigneeID]; !ok {
ids[comment.AssigneeID] = struct{}{}
}
ids.Add(comment.AssigneeID)
}
return container.KeysInt64(ids)
return ids.Values()
}
func (comments CommentList) loadAssignees(ctx context.Context) error {
@ -259,16 +249,14 @@ func (comments CommentList) loadAssignees(ctx context.Context) error {
// getIssueIDs returns all the issue ids on this comment list which issue hasn't been loaded
func (comments CommentList) getIssueIDs() []int64 {
ids := make(map[int64]struct{}, len(comments))
ids := make(container.Set[int64], len(comments))
for _, comment := range comments {
if comment.Issue != nil {
continue
}
if _, ok := ids[comment.IssueID]; !ok {
ids[comment.IssueID] = struct{}{}
}
ids.Add(comment.IssueID)
}
return container.KeysInt64(ids)
return ids.Values()
}
// Issues returns all the issues of comments
@ -334,16 +322,14 @@ func (comments CommentList) loadIssues(ctx context.Context) error {
}
func (comments CommentList) getDependentIssueIDs() []int64 {
ids := make(map[int64]struct{}, len(comments))
ids := make(container.Set[int64], len(comments))
for _, comment := range comments {
if comment.DependentIssue != nil {
continue
}
if _, ok := ids[comment.DependentIssueID]; !ok {
ids[comment.DependentIssueID] = struct{}{}
}
ids.Add(comment.DependentIssueID)
}
return container.KeysInt64(ids)
return ids.Values()
}
func (comments CommentList) loadDependentIssues(ctx context.Context) error {
@ -439,13 +425,11 @@ func (comments CommentList) loadAttachments(ctx context.Context) (err error) {
}
func (comments CommentList) getReviewIDs() []int64 {
ids := make(map[int64]struct{}, len(comments))
ids := make(container.Set[int64], len(comments))
for _, comment := range comments {
if _, ok := ids[comment.ReviewID]; !ok {
ids[comment.ReviewID] = struct{}{}
}
ids.Add(comment.ReviewID)
}
return container.KeysInt64(ids)
return ids.Values()
}
func (comments CommentList) loadReviews(ctx context.Context) error { //nolint

View file

@ -22,16 +22,16 @@ type IssueList []*Issue
// get the repo IDs to be loaded later, these IDs are for issue.Repo and issue.PullRequest.HeadRepo
func (issues IssueList) getRepoIDs() []int64 {
repoIDs := make(map[int64]struct{}, len(issues))
repoIDs := make(container.Set[int64], len(issues))
for _, issue := range issues {
if issue.Repo == nil {
repoIDs[issue.RepoID] = struct{}{}
repoIDs.Add(issue.RepoID)
}
if issue.PullRequest != nil && issue.PullRequest.HeadRepo == nil {
repoIDs[issue.PullRequest.HeadRepoID] = struct{}{}
repoIDs.Add(issue.PullRequest.HeadRepoID)
}
}
return container.KeysInt64(repoIDs)
return repoIDs.Values()
}
func (issues IssueList) loadRepositories(ctx context.Context) ([]*repo_model.Repository, error) {
@ -79,13 +79,11 @@ func (issues IssueList) LoadRepositories() ([]*repo_model.Repository, error) {
}
func (issues IssueList) getPosterIDs() []int64 {
posterIDs := make(map[int64]struct{}, len(issues))
posterIDs := make(container.Set[int64], len(issues))
for _, issue := range issues {
if _, ok := posterIDs[issue.PosterID]; !ok {
posterIDs[issue.PosterID] = struct{}{}
}
posterIDs.Add(issue.PosterID)
}
return container.KeysInt64(posterIDs)
return posterIDs.Values()
}
func (issues IssueList) loadPosters(ctx context.Context) error {
@ -185,13 +183,11 @@ func (issues IssueList) loadLabels(ctx context.Context) error {
}
func (issues IssueList) getMilestoneIDs() []int64 {
ids := make(map[int64]struct{}, len(issues))
ids := make(container.Set[int64], len(issues))
for _, issue := range issues {
if _, ok := ids[issue.MilestoneID]; !ok {
ids[issue.MilestoneID] = struct{}{}
}
ids.Add(issue.MilestoneID)
}
return container.KeysInt64(ids)
return ids.Values()
}
func (issues IssueList) loadMilestones(ctx context.Context) error {
@ -224,14 +220,11 @@ func (issues IssueList) loadMilestones(ctx context.Context) error {
}
func (issues IssueList) getProjectIDs() []int64 {
ids := make(map[int64]struct{}, len(issues))
ids := make(container.Set[int64], len(issues))
for _, issue := range issues {
projectID := issue.ProjectID()
if _, ok := ids[projectID]; !ok {
ids[projectID] = struct{}{}
}
ids.Add(issue.ProjectID())
}
return container.KeysInt64(ids)
return ids.Values()
}
func (issues IssueList) loadProjects(ctx context.Context) error {

View file

@ -211,7 +211,7 @@ type ReactionOptions struct {
// CreateReaction creates reaction for issue or comment.
func CreateReaction(opts *ReactionOptions) (*Reaction, error) {
if !setting.UI.ReactionsMap[opts.Type] {
if !setting.UI.ReactionsLookup.Contains(opts.Type) {
return nil, ErrForbiddenIssueReaction{opts.Type}
}
@ -316,16 +316,14 @@ func (list ReactionList) GroupByType() map[string]ReactionList {
}
func (list ReactionList) getUserIDs() []int64 {
userIDs := make(map[int64]struct{}, len(list))
userIDs := make(container.Set[int64], len(list))
for _, reaction := range list {
if reaction.OriginalAuthor != "" {
continue
}
if _, ok := userIDs[reaction.UserID]; !ok {
userIDs[reaction.UserID] = struct{}{}
}
userIDs.Add(reaction.UserID)
}
return container.KeysInt64(userIDs)
return userIDs.Values()
}
func valuesUser(m map[int64]*user_model.User) []*user_model.User {

View file

@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/structs"
)
@ -99,9 +100,9 @@ func InsertIssueComments(comments []*issues_model.Comment) error {
return nil
}
issueIDs := make(map[int64]bool)
issueIDs := make(container.Set[int64])
for _, comment := range comments {
issueIDs[comment.IssueID] = true
issueIDs.Add(comment.IssueID)
}
ctx, committer, err := db.TxContext()

View file

@ -13,6 +13,7 @@ import (
"path/filepath"
"time"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
@ -39,7 +40,7 @@ func renameExistingUserAvatarName(x *xorm.Engine) error {
}
log.Info("%d User Avatar(s) to migrate ...", count)
deleteList := make(map[string]struct{})
deleteList := make(container.Set[string])
start := 0
migrated := 0
for {
@ -86,7 +87,7 @@ func renameExistingUserAvatarName(x *xorm.Engine) error {
return fmt.Errorf("[user: %s] user table update: %v", user.LowerName, err)
}
deleteList[filepath.Join(setting.Avatar.Path, oldAvatar)] = struct{}{}
deleteList.Add(filepath.Join(setting.Avatar.Path, oldAvatar))
migrated++
select {
case <-ticker.C:

View file

@ -12,6 +12,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/packages"
"code.gitea.io/gitea/modules/container"
conan_module "code.gitea.io/gitea/modules/packages/conan"
"xorm.io/builder"
@ -88,7 +89,7 @@ func SearchRecipes(ctx context.Context, opts *RecipeSearchOptions) ([]string, er
return nil, err
}
unique := make(map[string]bool)
unique := make(container.Set[string])
for _, info := range results {
recipe := fmt.Sprintf("%s/%s", info.Name, info.Version)
@ -111,7 +112,7 @@ func SearchRecipes(ctx context.Context, opts *RecipeSearchOptions) ([]string, er
}
}
unique[recipe] = true
unique.Add(recipe)
}
recipes := make([]string, 0, len(unique))

View file

@ -68,10 +68,10 @@ func (repos RepositoryList) loadAttributes(ctx context.Context) error {
return nil
}
set := make(map[int64]struct{})
set := make(container.Set[int64])
repoIDs := make([]int64, len(repos))
for i := range repos {
set[repos[i].OwnerID] = struct{}{}
set.Add(repos[i].OwnerID)
repoIDs[i] = repos[i].ID
}
@ -79,7 +79,7 @@ func (repos RepositoryList) loadAttributes(ctx context.Context) error {
users := make(map[int64]*user_model.User, len(set))
if err := db.GetEngine(ctx).
Where("id > 0").
In("id", container.KeysInt64(set)).
In("id", set.Values()).
Find(&users); err != nil {
return fmt.Errorf("find users: %v", err)
}

View file

@ -11,6 +11,7 @@ import (
"strings"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/timeutil"
"xorm.io/builder"
@ -62,7 +63,7 @@ func ValidateTopic(topic string) bool {
// SanitizeAndValidateTopics sanitizes and checks an array or topics
func SanitizeAndValidateTopics(topics []string) (validTopics, invalidTopics []string) {
validTopics = make([]string, 0)
mValidTopics := make(map[string]struct{})
mValidTopics := make(container.Set[string])
invalidTopics = make([]string, 0)
for _, topic := range topics {
@ -72,12 +73,12 @@ func SanitizeAndValidateTopics(topics []string) (validTopics, invalidTopics []st
continue
}
// ignore same topic twice
if _, ok := mValidTopics[topic]; ok {
if mValidTopics.Contains(topic) {
continue
}
if ValidateTopic(topic) {
validTopics = append(validTopics, topic)
mValidTopics[topic] = struct{}{}
mValidTopics.Add(topic)
} else {
invalidTopics = append(invalidTopics, topic)
}

View file

@ -10,6 +10,7 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container"
api "code.gitea.io/gitea/modules/structs"
"xorm.io/builder"
@ -83,37 +84,19 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us
return nil, err
}
uidMap := map[int64]bool{}
i := 0
for _, uid := range userIDs {
if uidMap[uid] {
continue
}
uidMap[uid] = true
userIDs[i] = uid
i++
}
userIDs = userIDs[:i]
userIDs = append(userIDs, additionalUserIDs...)
for _, uid := range additionalUserIDs {
if uidMap[uid] {
continue
}
userIDs[i] = uid
i++
}
userIDs = userIDs[:i]
uniqueUserIDs := make(container.Set[int64])
uniqueUserIDs.AddMultiple(userIDs...)
uniqueUserIDs.AddMultiple(additionalUserIDs...)
// Leave a seat for owner itself to append later, but if owner is an organization
// and just waste 1 unit is cheaper than re-allocate memory once.
users := make([]*user_model.User, 0, len(userIDs)+1)
users := make([]*user_model.User, 0, len(uniqueUserIDs)+1)
if len(userIDs) > 0 {
if err = e.In("id", userIDs).OrderBy(user_model.GetOrderByName()).Find(&users); err != nil {
if err = e.In("id", uniqueUserIDs.Values()).OrderBy(user_model.GetOrderByName()).Find(&users); err != nil {
return nil, err
}
}
if !repo.Owner.IsOrganization() && !uidMap[repo.OwnerID] {
if !repo.Owner.IsOrganization() && !uniqueUserIDs.Contains(repo.OwnerID) {
users = append(users, repo.Owner)
}