use string builder in buildFlexiWhere

add string builder growth hints
track favicon perf
This commit is contained in:
Azareal 2020-03-05 09:56:45 +10:00
parent 68c6b2f50a
commit c31ca03a0d
6 changed files with 48 additions and 18 deletions

View File

@ -56,6 +56,8 @@ func init() {
}) })
} }
const AlertsGrowHint = len(`{"msgs":[],"count":,"tc":}`) + 1 + 7
// TODO: See if we can json.Marshal instead? // TODO: See if we can json.Marshal instead?
func escapeTextInJson(in string) string { func escapeTextInJson(in string) string {
in = strings.Replace(in, "\"", "\\\"", -1) in = strings.Replace(in, "\"", "\\\"", -1)
@ -165,6 +167,8 @@ func buildAlertString(msg string, sub []string, path, avatar string, asid int) s
return sb.String() return sb.String()
} }
const AlertsGrowHint2 = len(`{"msg":"","sub":[],"path":"","avatar":"","id":}`) + 3 + 3 + 1 + 1 + 1
// TODO: Use a string builder? // TODO: Use a string builder?
func buildAlertSb(sb *strings.Builder, msg string, sub []string, path, avatar string, asid int) { func buildAlertSb(sb *strings.Builder, msg string, sub []string, path, avatar string, asid int) {
sb.WriteString(`{"msg":"`) sb.WriteString(`{"msg":"`)

View File

@ -2665,7 +2665,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
} }
req.URL.Path = "/s/favicon.ico" req.URL.Path = "/s/favicon.ico"
routes.StaticFile(w,req) routes.StaticFile(w,req)
co.RouteViewCounter.Bump(171) co.RouteViewCounter.Bump3(171, cn)
return nil return nil
case "opensearch.xml": case "opensearch.xml":
co.RouteViewCounter.Bump(170) co.RouteViewCounter.Bump(170)

View File

@ -651,41 +651,66 @@ func (a *MysqlAdapter) buildWhere(where string, sb *strings.Builder) error {
} }
// The new version of buildWhere() currently only used in ComplexSelect for complex OO builder queries // The new version of buildWhere() currently only used in ComplexSelect for complex OO builder queries
const FlexiHint1 = len(` < UTC_TIMESTAMP() - interval ? `)
func (a *MysqlAdapter) buildFlexiWhere(where string, dateCutoff *dateCutoff) (q string, err error) { func (a *MysqlAdapter) buildFlexiWhere(where string, dateCutoff *dateCutoff) (q string, err error) {
if len(where) == 0 && dateCutoff == nil { if len(where) == 0 && dateCutoff == nil {
return "", nil return "", nil
} }
q = " WHERE"
var sb strings.Builder
sb.WriteString(" WHERE")
if dateCutoff != nil { if dateCutoff != nil {
sb.Grow(6 + FlexiHint1)
sb.WriteRune(' ')
sb.WriteString(dateCutoff.Column)
switch dateCutoff.Type { switch dateCutoff.Type {
case 0: case 0:
q += " " + dateCutoff.Column + " BETWEEN (UTC_TIMESTAMP() - interval " + strconv.Itoa(dateCutoff.Quantity) + " " + dateCutoff.Unit + ") AND UTC_TIMESTAMP() AND" sb.WriteString(" BETWEEN (UTC_TIMESTAMP() - interval ")
q += strconv.Itoa(dateCutoff.Quantity) + " " + dateCutoff.Unit + ") AND UTC_TIMESTAMP()"
case 11: case 11:
q += " " + dateCutoff.Column + " < UTC_TIMESTAMP() - interval ? " + dateCutoff.Unit + " AND" sb.WriteString(" < UTC_TIMESTAMP() - interval ? ")
sb.WriteString(dateCutoff.Unit)
default: default:
q += " " + dateCutoff.Column + " < UTC_TIMESTAMP() - interval " + strconv.Itoa(dateCutoff.Quantity) + " " + dateCutoff.Unit + " AND" sb.WriteString(" < UTC_TIMESTAMP() - interval ")
sb.WriteString(strconv.Itoa(dateCutoff.Quantity))
sb.WriteRune(' ')
sb.WriteString(dateCutoff.Unit)
} }
} }
if dateCutoff != nil && len(where) != 0 {
sb.WriteString(" AND")
}
if len(where) != 0 { if len(where) != 0 {
for _, loc := range processWhere(where) { wh := processWhere(where)
sb.Grow((len(wh) * 8) - 5)
for i, loc := range wh {
if i != 0 {
sb.WriteString(" AND ")
}
for _, token := range loc.Expr { for _, token := range loc.Expr {
switch token.Type { switch token.Type {
case TokenFunc, TokenOp, TokenNumber, TokenSub, TokenOr, TokenNot, TokenLike: case TokenFunc, TokenOp, TokenNumber, TokenSub, TokenOr, TokenNot, TokenLike:
q += " " + token.Contents sb.WriteString(" ")
sb.WriteString(token.Contents)
case TokenColumn: case TokenColumn:
q += " `" + token.Contents + "`" sb.WriteString(" `")
sb.WriteString(token.Contents)
sb.WriteString("`")
case TokenString: case TokenString:
q += " '" + token.Contents + "'" sb.WriteString(" '")
sb.WriteString(token.Contents)
sb.WriteString("'")
default: default:
return q, errors.New("This token doesn't exist o_o") return sb.String(), errors.New("This token doesn't exist o_o")
} }
} }
q += " AND"
} }
} }
return q[0 : len(q)-4], nil return sb.String(), nil
} }
func (a *MysqlAdapter) buildOrderby(orderby string) (q string) { func (a *MysqlAdapter) buildOrderby(orderby string) (q string) {

View File

@ -892,7 +892,7 @@ func (r *GenRouter) routeSwitch(w http.ResponseWriter, req *http.Request, user c
} }
req.URL.Path = "/s/favicon.ico" req.URL.Path = "/s/favicon.ico"
routes.StaticFile(w,req) routes.StaticFile(w,req)
co.RouteViewCounter.Bump({{index .AllRouteMap "routes.Favicon"}}) co.RouteViewCounter.Bump3({{index .AllRouteMap "routes.Favicon"}}, cn)
return nil return nil
case "opensearch.xml": case "opensearch.xml":
co.RouteViewCounter.Bump({{index .AllRouteMap "routes.OpenSearchXml"}}) co.RouteViewCounter.Bump({{index .AllRouteMap "routes.OpenSearchXml"}})

View File

@ -151,6 +151,7 @@ func routeAPI(w http.ResponseWriter, r *http.Request, user c.User) c.RouteError
var ok bool var ok bool
var sb strings.Builder var sb strings.Builder
sb.Grow(c.AlertsGrowHint + (len(alerts) * c.AlertsGrowHint2))
sb.WriteString(`{"msgs":[`) sb.WriteString(`{"msgs":[`)
for i, alert := range alerts { for i, alert := range alerts {
if i != 0 { if i != 0 {