You can now filter the active memory pane by type.

Add excludes for the analytics language pane too.
Try to avoid rid queries when we already have the rids.
Use GetListByCanSee instead of GetList for preloads to increase the chances of getting something useful.
Provisionally extend topic preloading to the first three topic list pages.

Add the panel_statistics_memory_type_total phrase.
Add the panel_statistics_memory_type_stack phrase.
Add the panel_statistics_memory_type_heap phrase.
This commit is contained in:
Azareal 2019-05-19 11:01:11 +10:00
parent 8a719bd13d
commit a56ed113dd
13 changed files with 122 additions and 35 deletions

View File

@ -307,6 +307,14 @@ type PanelAnalyticsStdUnit struct {
Unit string
TimeType string
}
type PanelAnalyticsActiveMemory struct {
Graph PanelTimeGraph
ViewItems []PanelAnalyticsItemUnit
TimeRange string
Unit string
TimeType string
MemType int
}
type PanelStats struct {
Users int

View File

@ -252,7 +252,7 @@ func compileCommons(c *tmpl.CTemplateSet, header *Header, header2 *Header, out T
var replyList []*ReplyUser
reply := Reply{1, 1, "Yo!", 1, Config.DefaultGroup, now, 0, 0, 1, "::1", true, 1, 1, ""}
ru := &ReplyUser{ClassName: "", Reply: reply, CreatedByName: "Alice", Avatar: avatar, URLPrefix: "", URLName: "", Level: 0, Attachments: miniAttach}
ru.Init(topic.ID)
ru.Init()
replyList = append(replyList, ru)
tpage := TopicPage{htitle("Topic Name"), replyList, topic, &Forum{ID: 1, Name: "Hahaha"}, poll, Paginator{[]int{1}, 1, 1}}
tpage.Forum.Link = BuildForumURL(NameToSlug(tpage.Forum.Name), tpage.Forum.ID)
@ -268,19 +268,19 @@ func compileTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName string
header, header2, _ := tmplInitHeaders(user, user2, user3)
now := time.Now()
poll := Poll{ID: 1, Type: 0, Options: map[int]string{0: "Nothing", 1: "Something"}, Results: map[int]int{0: 5, 1: 2}, QuickOptions: []PollOption{
/*poll := Poll{ID: 1, Type: 0, Options: map[int]string{0: "Nothing", 1: "Something"}, Results: map[int]int{0: 5, 1: 2}, QuickOptions: []PollOption{
PollOption{0, "Nothing"},
PollOption{1, "Something"},
}, VoteCount: 7}
avatar, microAvatar := BuildAvatar(62, "")
}, VoteCount: 7}*/
//avatar, microAvatar := BuildAvatar(62, "")
miniAttach := []*MiniAttachment{&MiniAttachment{Path: "/"}}
var replyList []*ReplyUser
topic := TopicUser{1, "blah", "Blah", "Hey there!", 0, false, false, now, now, 1, 1, 0, "", "127.0.0.1", 1, 0, 1, 0, "classname", poll.ID, "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, avatar, microAvatar, 0, "", "", "", "", "", 58, false, miniAttach, nil}
//topic := TopicUser{1, "blah", "Blah", "Hey there!", 0, false, false, now, now, 1, 1, 0, "", "127.0.0.1", 1, 0, 1, 0, "classname", poll.ID, "weird-data", BuildProfileURL("fake-user", 62), "Fake User", Config.DefaultGroup, avatar, microAvatar, 0, "", "", "", "", "", 58, false, miniAttach, nil}
// TODO: Do we want the UID on this to be 0?
avatar, microAvatar = BuildAvatar(0, "")
//avatar, microAvatar = BuildAvatar(0, "")
reply := Reply{1, 1, "Yo!", 1, Config.DefaultGroup, now, 0, 0, 1, "::1", true, 1, 1, ""}
ru := &ReplyUser{ClassName: "", Reply: reply, CreatedByName: "Alice", Avatar: avatar, URLPrefix: "", URLName: "", Level: 0, Attachments: miniAttach}
ru.Init(topic.ID)
ru := &ReplyUser{ClassName: "", Reply: reply, CreatedByName: "Alice", Avatar: "", URLPrefix: "", URLName: "", Level: 0, Attachments: miniAttach}
ru.Init()
replyList = append(replyList, ru)
// Convienience function to save a line here and there
@ -477,7 +477,7 @@ func compileJSTemplates(wg *sync.WaitGroup, c *tmpl.CTemplateSet, themeName stri
avatar, microAvatar = BuildAvatar(0, "")
reply := Reply{1, 1, "Yo!", 1, Config.DefaultGroup, now, 0, 0, 1, "::1", true, 1, 1, ""}
ru := &ReplyUser{ClassName: "", Reply: reply, CreatedByName: "Alice", Avatar: avatar, URLPrefix: "", URLName: "", Level: 0, Attachments: miniAttach}
ru.Init(topic.ID)
ru.Init()
replyList = append(replyList, ru)
varList = make(map[string]tmpl.VarItem)

View File

@ -422,9 +422,8 @@ func GetRidsForTopic(tid int, offset int) (rids []int, err error) {
return rids, rows.Err()
}
func (ru *ReplyUser) Init(parentID int) error {
func (ru *ReplyUser) Init() error {
ru.UserLink = BuildProfileURL(NameToSlug(ru.CreatedByName), ru.CreatedBy)
ru.ParentID = parentID
ru.ContentLines = strings.Count(ru.Content, "\n")
postGroup, err := Groups.Get(ru.Group)
@ -516,7 +515,7 @@ func (topic *TopicUser) Replies(offset int, pFrag int, user *User) (rlist []*Rep
//log.Print("reply cached serve")
reply = &ReplyUser{ClassName: "", Reply: *re, CreatedByName: ruser.Name, Avatar: ruser.Avatar, URLPrefix: ruser.URLPrefix, URLName: ruser.URLName, Level: ruser.Level}
err := reply.Init(topic.ID)
err := reply.Init()
if err != nil {
return nil, "", err
}
@ -554,7 +553,7 @@ func (topic *TopicUser) Replies(offset int, pFrag int, user *User) (rlist []*Rep
return nil, "", err
}
err = reply.Init(topic.ID)
err = reply.Init()
if err != nil {
return nil, "", err
}
@ -596,8 +595,8 @@ func (topic *TopicUser) Replies(offset int, pFrag int, user *User) (rlist []*Rep
}
defer rows.Close()
var likeRid int
for rows.Next() {
var likeRid int
err := rows.Scan(&likeRid)
if err != nil {
return nil, "", err

View File

@ -2,6 +2,7 @@ package common
import (
//"log"
"database/sql"
"strconv"
"sync"
@ -308,7 +309,16 @@ func (tList *DefaultTopicList) getList(page int, orderby string, argList []inter
//log.Print("rcap: ", rcap)
//log.Print("topic.PostCount: ", topic.PostCount)
//log.Print("topic.PostCount == 2 && rlen < rcap: ", topic.PostCount == 2 && rlen < rcap)
if topic.PostCount == 2 && rlen < rcap {
// Avoid the extra queries on topic list pages, if we already have what we want...
var hRids = false
if tcache != nil {
if t, err := tcache.Get(topic.ID); err == nil {
hRids = len(t.Rids) != 0
}
}
if topic.PostCount == 2 && rlen < rcap && !hRids && page < 5 {
rids, err := GetRidsForTopic(topic.ID, 0)
if err != nil {
return nil, Paginator{nil, 1, 1}, err
@ -324,7 +334,9 @@ func (tList *DefaultTopicList) getList(page int, orderby string, argList []inter
}
if tcache != nil {
_ = tcache.Set(topic.Topic())
if _, err := tcache.Get(topic.ID); err == sql.ErrNoRows {
_ = tcache.Set(topic.Topic())
}
}
}
err = rows.Err()

View File

@ -889,6 +889,9 @@
"panel_statistics_spam_hide":"Hide Spam",
"panel_statistics_spam_show":"Show Spam",
"panel_statistics_memory_type_total":"Total",
"panel_statistics_memory_type_stack":"Stack",
"panel_statistics_memory_type_heap":"Heap",
"panel_statistics_time_range_one_year":"1 year",
"panel_statistics_time_range_three_months":"3 months",

35
main.go
View File

@ -64,17 +64,40 @@ func afterDBInit() (err error) {
count = 0
}
}
// TODO: Use the same cached data for both the topic list and the topic fetches...
tList, _, _, err := c.TopicList.GetList(1, "", nil)
group, err := c.Groups.Get(c.GuestUser.Group)
if err != nil {
return err
}
if count > len(tList) {
count = len(tList)
// TODO: Use the same cached data for both the topic list and the topic fetches...
tList, _, _, err := c.TopicList.GetListByCanSee(group.CanSee, 1, "", nil)
if err != nil {
return err
}
ctList := make([]*c.TopicsRow, len(tList))
copy(ctList, tList)
tList, _, _, err = c.TopicList.GetListByCanSee(group.CanSee, 2, "", nil)
if err != nil {
return err
}
for _, tItem := range tList {
ctList = append(ctList, tItem)
}
tList, _, _, err = c.TopicList.GetListByCanSee(group.CanSee, 3, "", nil)
if err != nil {
return err
}
for _, tItem := range tList {
ctList = append(ctList, tItem)
}
if count > len(ctList) {
count = len(ctList)
}
for i := 0; i < count; i++ {
_, _ = c.Topics.Get(tList[i].ID)
_, _ = c.Topics.Get(ctList[i].ID)
}
}

View File

@ -158,7 +158,7 @@ func analyticsRowsToAverageMap(rows *sql.Rows, labelList []int64, avgMap map[int
return avgMap, rows.Err()
}
func analyticsRowsToAverageMap2(rows *sql.Rows, labelList []int64, avgMap map[int64]int64) (map[int64]int64, error) {
func analyticsRowsToAverageMap2(rows *sql.Rows, labelList []int64, avgMap map[int64]int64, typ int) (map[int64]int64, error) {
defer rows.Close()
for rows.Next() {
var stack, heap int64
@ -175,6 +175,11 @@ func analyticsRowsToAverageMap2(rows *sql.Rows, labelList []int64, avgMap map[in
log.Print("createdAt: ", createdAt)
log.Print("unixCreatedAt: ", unixCreatedAt)
}
if typ == 1 {
heap = 0
} else if typ == 2 {
stack = 0
}
var pAvgMap = make(map[int64]pAvg)
for _, value := range labelList {
if unixCreatedAt > value {
@ -589,7 +594,17 @@ func AnalyticsActiveMemory(w http.ResponseWriter, r *http.Request, user c.User)
if err != nil && err != sql.ErrNoRows {
return c.InternalError(err, w, r)
}
avgMap, err = analyticsRowsToAverageMap2(rows, labelList, avgMap)
var typ int
switch r.FormValue("mtype") {
case "1":
typ = 1
case "2":
typ = 2
default:
typ = 0
}
avgMap, err = analyticsRowsToAverageMap2(rows, labelList, avgMap, typ)
if err != nil {
return c.InternalError(err, w, r)
}
@ -604,7 +619,7 @@ func AnalyticsActiveMemory(w http.ResponseWriter, r *http.Request, user c.User)
}
graph := c.PanelTimeGraph{Series: [][]int64{avgList}, Labels: labelList}
c.DebugLogf("graph: %+v\n", graph)
pi := c.PanelAnalyticsStdUnit{graph, avgItems, timeRange.Range, timeRange.Unit, "time"}
pi := c.PanelAnalyticsActiveMemory{graph, avgItems, timeRange.Range, timeRange.Unit, "time", typ}
return renderTemplate("panel", w, r, basePage.Header, c.Panel{basePage, "panel_analytics_right", "analytics", "panel_analytics_active_memory", pi})
}
@ -1012,19 +1027,35 @@ func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user c.User) c.R
}
ovList := analyticsVMapToOVList(vMap)
ex := strings.Split(r.FormValue("ex"), ",")
var inEx = func(name string) bool {
for _, e := range ex {
if e == name {
return true
}
}
return false
}
var vList [][]int64
var legendList []string
var i int
for _, ovitem := range ovList {
if inEx(ovitem.name) {
continue
}
lName, ok := phrases.GetHumanLangPhrase(ovitem.name)
if !ok {
lName = ovitem.name
}
if inEx(lName) {
continue
}
var viewList []int64
for _, value := range revLabelList {
viewList = append(viewList, ovitem.viewMap[value])
}
vList = append(vList, viewList)
lName, ok := phrases.GetHumanLangPhrase(ovitem.name)
if !ok {
lName = ovitem.name
}
legendList = append(legendList, lName)
if i >= 6 {
break
@ -1038,10 +1069,16 @@ func AnalyticsLanguages(w http.ResponseWriter, r *http.Request, user c.User) c.R
// TODO: Sort this slice
var langItems []c.PanelAnalyticsAgentsItem
for lang, count := range langMap {
if inEx(lang) {
continue
}
lLang, ok := phrases.GetHumanLangPhrase(lang)
if !ok {
lLang = lang
}
if inEx(lLang) {
continue
}
langItems = append(langItems, c.PanelAnalyticsAgentsItem{
Agent: lang,
FriendlyAgent: lLang,

View File

@ -79,8 +79,8 @@ func ViewProfile(w http.ResponseWriter, r *http.Request, user c.User, header *c.
replyLiked := false
replyLikeCount := 0
ru := &c.ReplyUser{Reply: c.Reply{rid, 0, replyContent, replyCreatedBy, replyGroup, replyCreatedAt, replyLastEdit, replyLastEditBy, 0, "", replyLiked, replyLikeCount, 0, ""}, ContentHtml: c.ParseMessage(replyContent, 0, ""), CreatedByName: replyCreatedByName, Avatar: replyAvatar, Level: 0}
ru.Init(puser.ID)
ru := &c.ReplyUser{Reply: c.Reply{rid, puser.ID, replyContent, replyCreatedBy, replyGroup, replyCreatedAt, replyLastEdit, replyLastEditBy, 0, "", replyLiked, replyLikeCount, 0, ""}, ContentHtml: c.ParseMessage(replyContent, 0, ""), CreatedByName: replyCreatedByName, Avatar: replyAvatar, Level: 0}
ru.Init()
group, err := c.Groups.Get(ru.Group)
if err != nil {

View File

@ -1,6 +1,11 @@
<div class="colstack_item colstack_head">
<div class="rowitem">
<h1>{{lang "panel_statistics_active_memory_head"}}</h1>
<select form="timeRangeForm" class="typeSelector to_right autoSubmitRedirect" name="mtype">
<option val="0"{{if eq .MemType 0}} selected{{end}}>{{lang "panel_statistics_memory_type_total"}}</option>
<option val="1"{{if eq .MemType 1}} selected{{end}}>{{lang "panel_statistics_memory_type_stack"}}</option>
<option val="2"{{if eq .MemType 2}} selected{{end}}>{{lang "panel_statistics_memory_type_heap"}}</option>
</select>
{{template "panel_analytics_time_range_month.html" . }}
</div>
</div>

View File

@ -357,7 +357,7 @@
.analytics .colstack_head h1 {
margin-top: 2px;
}
.spamSelector + .timeRangeSelector {
select + .timeRangeSelector {
margin-left: 8px;
}

View File

@ -172,7 +172,7 @@ button, .formbutton, .panel_right_button:not(.has_inner_button), #panel_users .p
color: rgb(200,200,200);
}*/
.spamSelector + .timeRangeSelector {
select + .timeRangeSelector {
margin-left: 8px;
}

View File

@ -133,7 +133,7 @@
margin-top: 0px;
margin-bottom: 0px;
}
.spamSelector + .timeRangeSelector {
select + .timeRangeSelector {
margin-left: 8px;
}

View File

@ -177,7 +177,7 @@
margin-top: 0px;
margin-bottom: 0px;
}
.spamSelector + .timeRangeSelector {
select + .timeRangeSelector {
margin-left: 8px;
}