optimise topic list orderby

filter out forums with no topics from search queries
update go version in go.mod
This commit is contained in:
Azareal 2020-03-03 14:25:18 +10:00
parent d86ea75cdb
commit 2330b5bfeb
6 changed files with 39 additions and 32 deletions

View File

@ -11,6 +11,11 @@ import (
var TopicList TopicListInt var TopicList TopicListInt
const (
TopicListDefault = iota
TopicListMostViewed
)
type TopicListHolder struct { type TopicListHolder struct {
List []*TopicsRow List []*TopicsRow
ForumList []Forum ForumList []Forum
@ -18,10 +23,10 @@ type TopicListHolder struct {
} }
type TopicListInt interface { type TopicListInt interface {
GetListByCanSee(canSee []int, page int, orderby string, filterIDs []int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error) GetListByCanSee(canSee []int, page int, orderby int, filterIDs []int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error)
GetListByGroup(group *Group, page int, orderby string, filterIDs []int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error) GetListByGroup(group *Group, page int, orderby int, filterIDs []int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error)
GetListByForum(f *Forum, page int, orderby string) (topicList []*TopicsRow, paginator Paginator, err error) GetListByForum(f *Forum, page int, orderby int) (topicList []*TopicsRow, paginator Paginator, err error)
GetList(page int, orderby string, filterIDs []int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error) GetList(page int, orderby int, filterIDs []int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error)
} }
type DefaultTopicList struct { type DefaultTopicList struct {
@ -104,7 +109,7 @@ func (tList *DefaultTopicList) Tick() error {
canSeeHolders := make(map[string]*TopicListHolder) canSeeHolders := make(map[string]*TopicListHolder)
for name, canSee := range permTree { for name, canSee := range permTree {
topicList, forumList, paginator, err := tList.GetListByCanSee(canSee, 1, "", nil) topicList, forumList, paginator, err := tList.GetListByCanSee(canSee, 1, 0, nil)
if err != nil { if err != nil {
return err return err
} }
@ -130,7 +135,7 @@ func (tList *DefaultTopicList) Tick() error {
// TODO: Add Topics() method to *Forum? // TODO: Add Topics() method to *Forum?
// TODO: Implement orderby // TODO: Implement orderby
func (tList *DefaultTopicList) GetListByForum(f *Forum, page int, orderby string) (topicList []*TopicsRow, paginator Paginator, err error) { func (tList *DefaultTopicList) GetListByForum(f *Forum, page int, orderby int) (topicList []*TopicsRow, paginator Paginator, err error) {
// TODO: Does forum.TopicCount take the deleted items into consideration for guests? We don't have soft-delete yet, only hard-delete // TODO: Does forum.TopicCount take the deleted items into consideration for guests? We don't have soft-delete yet, only hard-delete
offset, page, lastPage := PageOffset(f.TopicCount, page, Config.ItemsPerPage) offset, page, lastPage := PageOffset(f.TopicCount, page, Config.ItemsPerPage)
@ -189,12 +194,12 @@ func (tList *DefaultTopicList) GetListByForum(f *Forum, page int, orderby string
return topicList, Paginator{pageList, page, lastPage}, nil return topicList, Paginator{pageList, page, lastPage}, nil
} }
func (tList *DefaultTopicList) GetListByGroup(group *Group, page int, orderby string, filterIDs []int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error) { func (tList *DefaultTopicList) GetListByGroup(group *Group, page int, orderby int, filterIDs []int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error) {
if page == 0 { if page == 0 {
page = 1 page = 1
} }
// TODO: Cache the first three pages not just the first along with all the topics on this beaten track // TODO: Cache the first three pages not just the first along with all the topics on this beaten track
if page == 1 && orderby == "" && len(filterIDs) == 0 { if page == 1 && orderby == 0 && len(filterIDs) == 0 {
var hold *TopicListHolder var hold *TopicListHolder
var ok bool var ok bool
if group.ID%2 == 0 { if group.ID%2 == 0 {
@ -216,7 +221,7 @@ func (tList *DefaultTopicList) GetListByGroup(group *Group, page int, orderby st
return tList.GetListByCanSee(group.CanSee, page, orderby, filterIDs) return tList.GetListByCanSee(group.CanSee, page, orderby, filterIDs)
} }
func (tList *DefaultTopicList) GetListByCanSee(canSee []int, page int, orderby string, filterIDs []int) (topicList []*TopicsRow, forumList []Forum, pagi Paginator, err error) { func (tList *DefaultTopicList) GetListByCanSee(canSee []int, page int, orderby int, filterIDs []int) (topicList []*TopicsRow, forumList []Forum, pagi Paginator, err error) {
// TODO: Optimise this by filtering canSee and then fetching the forums? // TODO: Optimise this by filtering canSee and then fetching the forums?
// We need a list of the visible forums for Quick Topic // We need a list of the visible forums for Quick Topic
// ? - Would it be useful, if we could post in social groups from /topics/? // ? - Would it be useful, if we could post in social groups from /topics/?
@ -248,7 +253,7 @@ func (tList *DefaultTopicList) GetListByCanSee(canSee []int, page int, orderby s
} else { } else {
filteredForums = forumList filteredForums = forumList
} }
if len(filteredForums) == 1 && orderby == "" { if len(filteredForums) == 1 && orderby == 0 {
topicList, pagi, err = tList.GetListByForum(&filteredForums[0], page, orderby) topicList, pagi, err = tList.GetListByForum(&filteredForums[0], page, orderby)
return topicList, forumList, pagi, err return topicList, forumList, pagi, err
} }
@ -270,7 +275,7 @@ func (tList *DefaultTopicList) GetListByCanSee(canSee []int, page int, orderby s
} }
// TODO: Reduce the number of returns // TODO: Reduce the number of returns
func (tList *DefaultTopicList) GetList(page int, orderby string, filterIDs []int) (topicList []*TopicsRow, forumList []Forum, pagi Paginator, err error) { func (tList *DefaultTopicList) GetList(page, orderby int, filterIDs []int) (topicList []*TopicsRow, forumList []Forum, pagi Paginator, err error) {
// TODO: Make CanSee a method on *Group with a canSee field? Have a CanSee method on *User to cover the case of superadmins? // TODO: Make CanSee a method on *Group with a canSee field? Have a CanSee method on *User to cover the case of superadmins?
cCanSee, err := Forums.GetAllVisibleIDs() cCanSee, err := Forums.GetAllVisibleIDs()
if err != nil { if err != nil {
@ -309,7 +314,7 @@ func (tList *DefaultTopicList) GetList(page int, orderby string, filterIDs []int
topicCount += fcopy.TopicCount topicCount += fcopy.TopicCount
} }
} }
if len(forumList) == 1 && orderby == "" { if len(forumList) == 1 && orderby == 0 {
topicList, pagi, err = tList.GetListByForum(&forumList[0], page, orderby) topicList, pagi, err = tList.GetListByForum(&forumList[0], page, orderby)
return topicList, forumList, pagi, err return topicList, forumList, pagi, err
} }
@ -327,12 +332,12 @@ func (tList *DefaultTopicList) GetList(page int, orderby string, filterIDs []int
// TODO: Rename this to TopicListStore and pass back a TopicList instance holding the pagination data and topic list rather than passing them back one argument at a time // TODO: Rename this to TopicListStore and pass back a TopicList instance holding the pagination data and topic list rather than passing them back one argument at a time
// TODO: Make orderby an enum of sorts // TODO: Make orderby an enum of sorts
func (tList *DefaultTopicList) getList(page int, orderby string, topicCount int, argList []interface{}, qlist string) (topicList []*TopicsRow, paginator Paginator, err error) { func (tList *DefaultTopicList) getList(page, orderby, topicCount int, argList []interface{}, qlist string) (topicList []*TopicsRow, paginator Paginator, err error) {
//log.Printf("argList: %+v\n",argList) //log.Printf("argList: %+v\n",argList)
//log.Printf("qlist: %+v\n",qlist) //log.Printf("qlist: %+v\n",qlist)
var orderq string var orderq string
if orderby == "most-viewed" { if orderby == TopicListMostViewed {
orderq = "views DESC,lastReplyAt DESC,createdBy DESC" orderq = "views DESC,lastReplyAt DESC,createdBy DESC"
} else { } else {
orderq = "sticky DESC,lastReplyAt DESC,createdBy DESC" orderq = "sticky DESC,lastReplyAt DESC,createdBy DESC"

View File

@ -83,7 +83,7 @@ func wsTopicListTick(h *WsHubImpl) error {
// Don't waste CPU time if nothing has happened // Don't waste CPU time if nothing has happened
// TODO: Get a topic list method which strips stickies? // TODO: Get a topic list method which strips stickies?
tList, _, _, err := TopicList.GetList(1, "", nil) tList, _, _, err := TopicList.GetList(1, 0, nil)
if err != nil { if err != nil {
h.lastTick = tickStart h.lastTick = tickStart
return err // TODO: Do we get ErrNoRows here? return err // TODO: Do we get ErrNoRows here?
@ -152,7 +152,7 @@ func wsTopicListTick(h *WsHubImpl) error {
canSeeRenders := make(map[string][]byte) canSeeRenders := make(map[string][]byte)
for name, canSee := range canSeeMap { for name, canSee := range canSeeMap {
topicList, forumList, _, err := TopicList.GetListByCanSee(canSee, 1, "", nil) topicList, forumList, _, err := TopicList.GetListByCanSee(canSee, 1, 0, nil)
if err != nil { if err != nil {
return err // TODO: Do we get ErrNoRows here? return err // TODO: Do we get ErrNoRows here?
} }

2
go.mod
View File

@ -24,3 +24,5 @@ require (
gopkg.in/sourcemap.v1 v1.0.5 // indirect gopkg.in/sourcemap.v1 v1.0.5 // indirect
gopkg.in/src-d/go-git.v4 v4.7.1 gopkg.in/src-d/go-git.v4 v4.7.1
) )
go 1.13

View File

@ -74,14 +74,14 @@ func afterDBInit() (err error) {
} }
// TODO: Use the same cached data for both the topic list and the topic fetches... // TODO: Use the same cached data for both the topic list and the topic fetches...
tList, _, _, err := c.TopicList.GetListByCanSee(group.CanSee, 1, "", nil) tList, _, _, err := c.TopicList.GetListByCanSee(group.CanSee, 1, 0, nil)
if err != nil { if err != nil {
return err return err
} }
ctList := make([]*c.TopicsRow, len(tList)) ctList := make([]*c.TopicsRow, len(tList))
copy(ctList, tList) copy(ctList, tList)
tList, _, _, err = c.TopicList.GetListByCanSee(group.CanSee, 2, "", nil) tList, _, _, err = c.TopicList.GetListByCanSee(group.CanSee, 2, 0, nil)
if err != nil { if err != nil {
return err return err
} }
@ -89,7 +89,7 @@ func afterDBInit() (err error) {
ctList = append(ctList, tItem) ctList = append(ctList, tItem)
} }
tList, _, _, err = c.TopicList.GetListByCanSee(group.CanSee, 3, "", nil) tList, _, _, err = c.TopicList.GetListByCanSee(group.CanSee, 3, 0, nil)
if err != nil { if err != nil {
return err return err
} }

View File

@ -37,7 +37,7 @@ func ViewForum(w http.ResponseWriter, r *http.Request, user c.User, header *c.He
header.Title = forum.Name header.Title = forum.Name
header.OGDesc = forum.Desc header.OGDesc = forum.Desc
topicList, pagi, err := c.TopicList.GetListByForum(forum, page, "") topicList, pagi, err := c.TopicList.GetListByForum(forum, page, 0)
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }

View File

@ -24,15 +24,15 @@ func TopicList(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header)
if skip || rerr != nil { if skip || rerr != nil {
return rerr return rerr
} }
return TopicListCommon(w, r, user, h, "lastupdated", "") return TopicListCommon(w, r, user, h, "lastupdated", 0)
} }
func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError { func TopicListMostViewed(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header) c.RouteError {
return TopicListCommon(w, r, user, h, "mostviewed", "most-viewed") return TopicListCommon(w, r, user, h, "mostviewed", c.TopicListMostViewed)
} }
// TODO: Implement search // TODO: Implement search
func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header, torder, tsorder string) c.RouteError { func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, h *c.Header, torder string, tsorder int) c.RouteError {
h.Title = phrases.GetTitlePhrase("topics") h.Title = phrases.GetTitlePhrase("topics")
h.Zone = "topics" h.Zone = "topics"
h.Path = "/topics/" h.Path = "/topics/"
@ -70,7 +70,7 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, h *c.H
// TODO: Simplify this block after initially landing search // TODO: Simplify this block after initially landing search
var topicList []*c.TopicsRow var topicList []*c.TopicsRow
var forumList []c.Forum var forumList []c.Forum
var paginator c.Paginator var pagi c.Paginator
q := r.FormValue("q") q := r.FormValue("q")
if q != "" && c.RepliesSearch != nil { if q != "" && c.RepliesSearch != nil {
var canSee []int var canSee []int
@ -96,7 +96,7 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, h *c.H
for _, fid := range fids { for _, fid := range fids {
if inSlice(canSee, fid) { if inSlice(canSee, fid) {
f := c.Forums.DirtyGet(fid) f := c.Forums.DirtyGet(fid)
if f.Name != "" && f.Active && (f.ParentType == "" || f.ParentType == "forum") { if f.Name != "" && f.Active && (f.ParentType == "" || f.ParentType == "forum") && f.TopicCount != 0 {
// TODO: Add a hook here for plugin_guilds? // TODO: Add a hook here for plugin_guilds?
cfids = append(cfids, fid) cfids = append(cfids, fid)
} }
@ -143,7 +143,7 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, h *c.H
// TODO: De-dupe this logic in common/topic_list.go? // TODO: De-dupe this logic in common/topic_list.go?
for _, t := range topicList { for _, t := range topicList {
t.Link = c.BuildTopicURL(c.NameToSlug(t.Title), t.ID) t.Link = c.BuildTopicURL(c.NameToSlug(t.Title), t.ID)
// TODO: Pass forum to something like topic.Forum and use that instead of these two properties? Could be more flexible. // TODO: Pass forum to something like t.Forum and use that instead of these two properties? Could be more flexible.
forum := c.Forums.DirtyGet(t.ParentID) forum := c.Forums.DirtyGet(t.ParentID)
t.ForumName = forum.Name t.ForumName = forum.Name
t.ForumLink = forum.Link t.ForumLink = forum.Link
@ -157,7 +157,7 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, h *c.H
// TODO: Reduce the amount of boilerplate here // TODO: Reduce the amount of boilerplate here
if r.FormValue("js") == "1" { if r.FormValue("js") == "1" {
outBytes, err := wsTopicList(topicList, paginator.LastPage).MarshalJSON() outBytes, err := wsTopicList(topicList, pagi.LastPage).MarshalJSON()
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
@ -166,15 +166,15 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, h *c.H
} }
h.Title = phrases.GetTitlePhrase("topics_search") h.Title = phrases.GetTitlePhrase("topics_search")
pi := c.TopicListPage{h, topicList, forumList, c.Config.DefaultForum, c.TopicListSort{torder, false}, paginator} pi := c.TopicListPage{h, topicList, forumList, c.Config.DefaultForum, c.TopicListSort{torder, false}, pagi}
return renderTemplate("topics", w, r, h, pi) return renderTemplate("topics", w, r, h, pi)
} }
// TODO: Pass a struct back rather than passing back so many variables // TODO: Pass a struct back rather than passing back so many variables
if user.IsSuperAdmin { if user.IsSuperAdmin {
topicList, forumList, paginator, err = c.TopicList.GetList(page, tsorder, fids) topicList, forumList, pagi, err = c.TopicList.GetList(page, tsorder, fids)
} else { } else {
topicList, forumList, paginator, err = c.TopicList.GetListByGroup(group, page, tsorder, fids) topicList, forumList, pagi, err = c.TopicList.GetListByGroup(group, page, tsorder, fids)
} }
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
@ -182,7 +182,7 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, h *c.H
// TODO: Reduce the amount of boilerplate here // TODO: Reduce the amount of boilerplate here
if r.FormValue("js") == "1" { if r.FormValue("js") == "1" {
outBytes, err := wsTopicList(topicList, paginator.LastPage).MarshalJSON() outBytes, err := wsTopicList(topicList, pagi.LastPage).MarshalJSON()
if err != nil { if err != nil {
return c.InternalError(err, w, r) return c.InternalError(err, w, r)
} }
@ -190,6 +190,6 @@ func TopicListCommon(w http.ResponseWriter, r *http.Request, user c.User, h *c.H
return nil return nil
} }
pi := c.TopicListPage{h, topicList, forumList, c.Config.DefaultForum, c.TopicListSort{torder, false}, paginator} pi := c.TopicListPage{h, topicList, forumList, c.Config.DefaultForum, c.TopicListSort{torder, false}, pagi}
return renderTemplate("topics", w, r, h, pi) return renderTemplate("topics", w, r, h, pi)
} }