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
const (
TopicListDefault = iota
TopicListMostViewed
)
type TopicListHolder struct {
List []*TopicsRow
ForumList []Forum
@ -18,10 +23,10 @@ type TopicListHolder struct {
}
type TopicListInt interface {
GetListByCanSee(canSee []int, page int, orderby string, 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)
GetListByForum(f *Forum, page int, orderby string) (topicList []*TopicsRow, paginator Paginator, err error)
GetList(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 int, filterIDs []int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error)
GetListByForum(f *Forum, page int, orderby int) (topicList []*TopicsRow, paginator Paginator, err error)
GetList(page int, orderby int, filterIDs []int) (topicList []*TopicsRow, forumList []Forum, paginator Paginator, err error)
}
type DefaultTopicList struct {
@ -104,7 +109,7 @@ func (tList *DefaultTopicList) Tick() error {
canSeeHolders := make(map[string]*TopicListHolder)
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 {
return err
}
@ -130,7 +135,7 @@ func (tList *DefaultTopicList) Tick() error {
// TODO: Add Topics() method to *Forum?
// 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
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
}
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 {
page = 1
}
// 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 ok bool
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)
}
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?
// We need a list of the visible forums for Quick Topic
// ? - 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 {
filteredForums = forumList
}
if len(filteredForums) == 1 && orderby == "" {
if len(filteredForums) == 1 && orderby == 0 {
topicList, pagi, err = tList.GetListByForum(&filteredForums[0], page, orderby)
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
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?
cCanSee, err := Forums.GetAllVisibleIDs()
if err != nil {
@ -309,7 +314,7 @@ func (tList *DefaultTopicList) GetList(page int, orderby string, filterIDs []int
topicCount += fcopy.TopicCount
}
}
if len(forumList) == 1 && orderby == "" {
if len(forumList) == 1 && orderby == 0 {
topicList, pagi, err = tList.GetListByForum(&forumList[0], page, orderby)
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: 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("qlist: %+v\n",qlist)
var orderq string
if orderby == "most-viewed" {
if orderby == TopicListMostViewed {
orderq = "views DESC,lastReplyAt DESC,createdBy DESC"
} else {
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
// 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 {
h.lastTick = tickStart
return err // TODO: Do we get ErrNoRows here?
@ -152,7 +152,7 @@ func wsTopicListTick(h *WsHubImpl) error {
canSeeRenders := make(map[string][]byte)
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 {
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/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...
tList, _, _, err := c.TopicList.GetListByCanSee(group.CanSee, 1, "", nil)
tList, _, _, err := c.TopicList.GetListByCanSee(group.CanSee, 1, 0, nil)
if err != nil {
return err
}
ctList := make([]*c.TopicsRow, len(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 {
return err
}
@ -89,7 +89,7 @@ func afterDBInit() (err error) {
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 {
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.OGDesc = forum.Desc
topicList, pagi, err := c.TopicList.GetListByForum(forum, page, "")
topicList, pagi, err := c.TopicList.GetListByForum(forum, page, 0)
if err != nil {
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 {
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 {
return TopicListCommon(w, r, user, h, "mostviewed", "most-viewed")
return TopicListCommon(w, r, user, h, "mostviewed", c.TopicListMostViewed)
}
// 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.Zone = "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
var topicList []*c.TopicsRow
var forumList []c.Forum
var paginator c.Paginator
var pagi c.Paginator
q := r.FormValue("q")
if q != "" && c.RepliesSearch != nil {
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 {
if inSlice(canSee, 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?
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?
for _, t := range topicList {
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)
t.ForumName = forum.Name
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
if r.FormValue("js") == "1" {
outBytes, err := wsTopicList(topicList, paginator.LastPage).MarshalJSON()
outBytes, err := wsTopicList(topicList, pagi.LastPage).MarshalJSON()
if err != nil {
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")
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)
}
// TODO: Pass a struct back rather than passing back so many variables
if user.IsSuperAdmin {
topicList, forumList, paginator, err = c.TopicList.GetList(page, tsorder, fids)
topicList, forumList, pagi, err = c.TopicList.GetList(page, tsorder, fids)
} 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 {
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
if r.FormValue("js") == "1" {
outBytes, err := wsTopicList(topicList, paginator.LastPage).MarshalJSON()
outBytes, err := wsTopicList(topicList, pagi.LastPage).MarshalJSON()
if err != nil {
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
}
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)
}