From c41aca20c86827b122c345b325fb8d08181b918a Mon Sep 17 00:00:00 2001 From: neosu Date: Wed, 21 Sep 2022 17:24:40 +0800 Subject: [PATCH] make get session list less memory --- session/pool.go | 11 +++-- session/static.go | 2 +- utils/slicex/slicex.go | 12 ++++- utils/slicex/slicex_test.go | 91 ++++++++++++++++++++++++++++++++++++- 4 files changed, 110 insertions(+), 6 deletions(-) diff --git a/session/pool.go b/session/pool.go index 0df3dad..8eaa102 100644 --- a/session/pool.go +++ b/session/pool.go @@ -8,6 +8,7 @@ import ( "github.com/metagogs/gogs/config" "github.com/metagogs/gogs/gslog" "github.com/metagogs/gogs/networkentity" + "github.com/metagogs/gogs/utils/slicex" "go.uber.org/zap" ) @@ -33,18 +34,21 @@ type SessionFilter struct { type sessionList struct { mutex sync.Mutex data map[int64]*sessionWrap + list []int64 } func (s *sessionList) Add(w *sessionWrap) { s.mutex.Lock() defer s.mutex.Unlock() s.data[w.SessionID] = w + s.list = append(s.list, w.SessionID) } func (s *sessionList) Delete(id int64) int { s.mutex.Lock() defer s.mutex.Unlock() delete(s.data, id) + s.list = slicex.RemoveSliceItem(s.list, id) return len(s.data) } @@ -52,10 +56,11 @@ func (s *sessionList) Delete(id int64) int { // if we can not get the result, we can check user's all the session list // then we can send message use another session func (s *sessionList) GetList(filter *SessionFilter) ([]int64, []int64) { + if filter == nil { + return s.list, s.list + } result := []int64{} - all := []int64{} for _, v := range s.data { - all = append(all, v.SessionID) if filter != nil { if len(filter.ConnType) > 0 && v.ConnType != filter.ConnType { continue @@ -73,7 +78,7 @@ func (s *sessionList) GetList(filter *SessionFilter) ([]int64, []int64) { result = append(result, v.SessionID) } - return result, all + return result, s.list } type sessionWrap struct { diff --git a/session/static.go b/session/static.go index de5d677..f096b74 100644 --- a/session/static.go +++ b/session/static.go @@ -33,7 +33,7 @@ func BroadcastMessage(users []string, send interface{}, filter *SessionFilter, e continue } if result, _ := GetSessionByUID(u, filter); len(result) > 0 { - go SendMessageByID(result[0], send) + SendMessageByID(result[0], send) } } } diff --git a/utils/slicex/slicex.go b/utils/slicex/slicex.go index f475993..2059363 100644 --- a/utils/slicex/slicex.go +++ b/utils/slicex/slicex.go @@ -1,6 +1,6 @@ package slicex -func InSlice(target string, data []string) bool { +func InSlice[T comparable](target T, data []T) bool { for _, s := range data { if s == target { return true @@ -9,3 +9,13 @@ func InSlice(target string, data []string) bool { return false } + +func RemoveSliceItem[T comparable](list []T, item T) []T { + for i, v := range list { + if v == item { + list = append(list[:i], list[i+1:]...) + break + } + } + return list +} diff --git a/utils/slicex/slicex_test.go b/utils/slicex/slicex_test.go index db27f23..a7b2ea7 100644 --- a/utils/slicex/slicex_test.go +++ b/utils/slicex/slicex_test.go @@ -1,6 +1,9 @@ package slicex -import "testing" +import ( + "reflect" + "testing" +) func TestInSlice(t *testing.T) { type args struct { @@ -44,4 +47,90 @@ func TestInSlice(t *testing.T) { } }) } + + type argsInt struct { + target int + data []int + } + testsInt := []struct { + name string + args argsInt + want bool + }{ + { + name: "test1", + args: argsInt{ + target: 1, + data: []int{1, 2, 3}, + }, + want: true, + }, + { + name: "test2", + args: argsInt{ + target: 4, + data: []int{1, 2, 3}, + }, + want: false, + }, + { + name: "test3", + args: argsInt{ + target: 1, + data: []int{}, + }, + want: false, + }, + } + for _, tt := range testsInt { + t.Run(tt.name, func(t *testing.T) { + if got := InSlice(tt.args.target, tt.args.data); got != tt.want { + t.Errorf("InSlice() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestRemoveSliceItem(t *testing.T) { + type args struct { + list []string + item string + } + tests := []struct { + name string + args args + want []string + }{ + { + name: "test1", + args: args{ + list: []string{"a", "b", "c"}, + item: "b", + }, + want: []string{"a", "c"}, + }, + { + name: "test2", + args: args{ + list: []string{"a", "b", "c"}, + item: "d", + }, + want: []string{"a", "b", "c"}, + }, + { + name: "test3", + args: args{ + list: []string{}, + item: "d", + }, + want: []string{}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := RemoveSliceItem(tt.args.list, tt.args.item); !reflect.DeepEqual(got, tt.want) { + t.Errorf("RemoveSliceItem() = %v, want %v", got, tt.want) + } + }) + } }