Feat: slice sort stable

pull/44/head
zijiren233 2 years ago
parent a54996aca5
commit 57a1c88eae

@ -5,9 +5,10 @@ import (
"fmt"
"os"
"path/filepath"
"time"
"slices"
"github.com/hashicorp/go-hclog"
"github.com/maruel/natural"
log "github.com/sirupsen/logrus"
"github.com/synctv-org/synctv/cmd/flags"
"github.com/synctv-org/synctv/internal/conf"
@ -18,7 +19,6 @@ import (
"github.com/synctv-org/synctv/internal/settings"
"github.com/synctv-org/synctv/utils"
"github.com/zijiren233/gencontainer/refreshcache"
"github.com/zijiren233/gencontainer/vec"
)
var ProviderGroupSettings = make(map[model.SettingGroup]*ProviderGroupSetting)
@ -34,17 +34,23 @@ type ProviderGroupSetting struct {
var (
Oauth2EnabledCache = refreshcache.NewRefreshCache[[]provider.OAuth2Provider](func(context.Context, ...any) ([]provider.OAuth2Provider, error) {
a := vec.New[provider.OAuth2Provider](vec.WithCmpEqual[provider.OAuth2Provider](func(v1, v2 provider.OAuth2Provider) bool {
return v1 == v2
}), vec.WithCmpLess[provider.OAuth2Provider](func(v1, v2 provider.OAuth2Provider) bool {
return v1 < v2
}))
ps := providers.EnabledProvider()
r := make([]provider.OAuth2Provider, 0, ps.Len())
providers.EnabledProvider().Range(func(key provider.OAuth2Provider, value provider.ProviderInterface) bool {
a.Push(key)
r = append(r, key)
return true
})
return a.SortStable().Slice(), nil
}, time.Hour)
slices.SortStableFunc(r, func(a, b provider.OAuth2Provider) int {
if a == b {
return 0
} else if natural.Less(string(a), string(b)) {
return -1
} else {
return 1
}
})
return r, nil
}, 0)
)
func InitProvider(ctx context.Context) (err error) {

@ -9,11 +9,14 @@ import (
"github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/settings"
"github.com/zijiren233/gencontainer/synccache"
"github.com/zijiren233/gencontainer/vec"
)
var roomCache *synccache.SyncCache[string, *Room]
func RangeRoomCache(f func(key string, value *synccache.Entry[*Room]) bool) {
roomCache.Range(f)
}
func CreateRoom(name, password string, maxCount int64, conf ...db.CreateRoomConfig) (*Room, error) {
r, err := db.CreateRoom(name, password, maxCount, conf...)
if err != nil {
@ -146,40 +149,6 @@ func GetAllRoomsInCacheWithoutHidden() []*Room {
return rooms
}
type RoomInfo struct {
RoomId string `json:"roomId"`
RoomName string `json:"roomName"`
PeopleNum int64 `json:"peopleNum"`
NeedPassword bool `json:"needPassword"`
CreatorID string `json:"creatorId"`
Creator string `json:"creator"`
CreatedAt int64 `json:"createdAt"`
Status model.RoomStatus `json:"status"`
}
func GetRoomHeapInCacheWithoutHidden() []*RoomInfo {
rooms := vec.New[*RoomInfo](vec.WithCmpLess[*RoomInfo](func(v1, v2 *RoomInfo) bool {
return v1.PeopleNum > v2.PeopleNum
}), vec.WithCmpEqual[*RoomInfo](func(v1, v2 *RoomInfo) bool {
return v1.RoomId == v2.RoomId
}))
roomCache.Range(func(key string, value *synccache.Entry[*Room]) bool {
v := value.Value()
if !v.Settings.Hidden {
rooms.Push(&RoomInfo{
RoomId: v.ID,
RoomName: v.Name,
PeopleNum: v.PeopleNum(),
NeedPassword: v.NeedPassword(),
Creator: GetUserName(v.CreatorID),
CreatedAt: v.CreatedAt.UnixMilli(),
})
}
return true
})
return rooms.SortStable().Slice()
}
func SetRoomStatus(roomID string, status model.RoomStatus) error {
err := db.SetRoomStatus(roomID, status)
if err != nil {

@ -5,9 +5,11 @@ import (
"errors"
"fmt"
"net/http"
"slices"
"time"
"github.com/gin-gonic/gin"
"github.com/maruel/natural"
"github.com/synctv-org/synctv/internal/db"
dbModel "github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/op"
@ -16,6 +18,7 @@ import (
"github.com/synctv-org/synctv/server/model"
"github.com/synctv-org/synctv/utils"
"github.com/zijiren233/gencontainer/refreshcache"
"github.com/zijiren233/gencontainer/synccache"
"gorm.io/gorm"
)
@ -63,8 +66,41 @@ func CreateRoom(ctx *gin.Context) {
}))
}
var roomHotCache = refreshcache.NewRefreshCache[[]*op.RoomInfo](func(context.Context, ...any) ([]*op.RoomInfo, error) {
return op.GetRoomHeapInCacheWithoutHidden(), nil
var roomHotCache = refreshcache.NewRefreshCache[[]*model.RoomListResp](func(context.Context, ...any) ([]*model.RoomListResp, error) {
rooms := make([]*model.RoomListResp, 0)
op.RangeRoomCache(func(key string, value *synccache.Entry[*op.Room]) bool {
v := value.Value()
if !v.Settings.Hidden {
rooms = append(rooms, &model.RoomListResp{
RoomId: v.ID,
RoomName: v.Name,
PeopleNum: v.PeopleNum(),
NeedPassword: v.NeedPassword(),
Creator: op.GetUserName(v.CreatorID),
CreatedAt: v.CreatedAt.UnixMilli(),
})
}
return true
})
slices.SortStableFunc(rooms, func(a, b *model.RoomListResp) int {
if a.PeopleNum == b.PeopleNum {
if a.RoomName == b.RoomName {
return 0
}
if natural.Less(a.RoomName, b.RoomName) {
return -1
} else {
return 1
}
} else if a.PeopleNum > b.PeopleNum {
return -1
} else {
return 1
}
})
return rooms, nil
}, time.Second*3)
func RoomHotList(ctx *gin.Context) {
@ -74,12 +110,15 @@ func RoomHotList(ctx *gin.Context) {
return
}
r, _ := roomHotCache.Get(ctx)
rs := utils.GetPageItems(r, page, pageSize)
r, err := roomHotCache.Get(ctx)
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
return
}
ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{
"total": len(r),
"list": rs,
"list": utils.GetPageItems(r, page, pageSize),
}))
}

@ -6,9 +6,9 @@ import (
"regexp"
json "github.com/json-iterator/go"
"github.com/synctv-org/synctv/internal/op"
"github.com/gin-gonic/gin"
"github.com/synctv-org/synctv/internal/model"
dbModel "github.com/synctv-org/synctv/internal/model"
)
@ -68,7 +68,16 @@ func (c *CreateRoomReq) Validate() error {
return nil
}
type RoomListResp = op.RoomInfo
type RoomListResp struct {
RoomId string `json:"roomId"`
RoomName string `json:"roomName"`
PeopleNum int64 `json:"peopleNum"`
NeedPassword bool `json:"needPassword"`
CreatorID string `json:"creatorId"`
Creator string `json:"creator"`
CreatedAt int64 `json:"createdAt"`
Status model.RoomStatus `json:"status"`
}
type LoginRoomReq struct {
RoomId string `json:"roomId"`

Loading…
Cancel
Save