diff --git a/Makefile b/Makefile index 8f501c7..3bf8dd8 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,27 @@ -build-isupam: - tools/build_isupam.sh +.PHONY: main sysctl mysql nginx ctrl bench -.PHONY: build-isupam +main: sysctl mysql nginx ctrl link_init bench + echo "OK" + +sysctl: + sudo ln -sf $(PWD)/sysctl.conf /etc/sysctl.conf + sudo sysctl -a + +mysql: + sudo systemctl restart mysql + +nginx: + sudo rm -f /var/log/nginx/access.log /var/log/nginx/error.log + sudo touch /var/log/nginx/access.log /var/log/nginx/error.log + sudo systemctl reload nginx + +app: + cd /home/isucon/isucon6-qualify/webapp/go && make + sudo systemctl restart isutar.go + sudo systemctl restart isuda.go + +link_init: + sudo su - isucon -c 'ln -sf $(PWD)/init.sh init.sh' + +bench: + cd /home/isucon/gocode/src/github.com/isucon/isucon6-qualify/bench && ./bench --datadir=data -target=http://localhost diff --git a/webapp/go/isuda.go b/webapp/go/isuda.go index 20d4945..64d790b 100644 --- a/webapp/go/isuda.go +++ b/webapp/go/isuda.go @@ -23,8 +23,7 @@ import ( "github.com/gorilla/mux" "github.com/gorilla/sessions" "github.com/unrolled/render" - - ) +) const ( sessionName = "isuda_session" @@ -112,12 +111,13 @@ func topHandler(w http.ResponseWriter, r *http.Request) { panicIf(err) } entries := make([]*Entry, 0, 10) + reg := getKeywordRegExp() for rows.Next() { e := Entry{} // err := rows.Scan(&e.ID, &e.AuthorID, &e.Keyword, &e.Description, &e.UpdatedAt, &e.CreatedAt) err := rows.Scan(&e.Keyword, &e.Description) panicIf(err) - e.Html = htmlify(w, r, e.Description) + e.Html = htmlify(w, r, e.Description, reg) e.Stars = loadStars(e.Keyword) entries = append(entries, &e) } @@ -181,10 +181,10 @@ func keywordPostHandler(w http.ResponseWriter, r *http.Request) { // TODO: htmlの状態のやつも保存したい...? _, err := db.Exec(` - INSERT INTO entry (author_id, keyword, description, created_at, updated_at) - VALUES (?, ?, ?, NOW(), NOW()) + INSERT INTO entry (author_id, keyword, description, created_at, updated_at, keyword_length) + VALUES (?, ?, ?, NOW(), NOW(), CHARACTER_LENGTH(keyword)) ON DUPLICATE KEY UPDATE - author_id = ?, keyword = ?, description = ?, updated_at = NOW() + author_id = ?, keyword = ?, description = ?, updated_at = NOW(), keyword_length = CHARACTER_LENGTH(keyword) `, userID, keyword, description, userID, keyword, description) panicIf(err) http.Redirect(w, r, "/", http.StatusFound) @@ -207,7 +207,7 @@ func loginHandler(w http.ResponseWriter, r *http.Request) { func loginPostHandler(w http.ResponseWriter, r *http.Request) { name := r.FormValue("name") - // TODO: cocodrips nameにindex貼ってあるか確認  + // TODO: cocodrips nameにindex貼ってあるか確認 // TODO: cocodrips Id, Password, Saltのみ取得すれば良いので、Name/CreatedAtは取得しないでも良い row := db.QueryRow(`SELECT id, name, salt FROM user WHERE name = ?`, name) user := User{} @@ -288,7 +288,9 @@ func keywordByKeywordHandler(w http.ResponseWriter, r *http.Request) { notFound(w) return } - e.Html = htmlify(w, r, e.Description) + + reg := getKeywordRegExp() + e.Html = htmlify(w, r, e.Description, reg) e.Stars = loadStars(e.Keyword) // Html, Keyword, StarsのみでOK @@ -331,20 +333,13 @@ func keywordByKeywordDeleteHandler(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/", http.StatusFound) } -func htmlify(w http.ResponseWriter, r *http.Request, content string) string { - // TODO: 正規表現を引数で渡す - - // まず最初に治す - if content == "" { - return "" - } - +func getKeywordRegExp() (reg *regexp.Regexp) { // TODO:cocodrips Descriptionいる? 処理めちゃくちゃ重い // TODO: そもそもhtmlifyでなぜDBを叩く構造になっているんだ // TODO: ここでDB叩く必要が一切ないので外に出す. // TODO: * -> keyword だけでいい rows, err := db.Query(` - SELECT keyword FROM entry ORDER BY CHARACTER_LENGTH(keyword) DESC + SELECT keyword FROM entry ORDER BY keyword_length DESC `) panicIf(err) @@ -363,16 +358,27 @@ func htmlify(w http.ResponseWriter, r *http.Request, content string) string { for _, entry := range entries { keywords = append(keywords, regexp.QuoteMeta(entry.Keyword)) } - re := regexp.MustCompile("("+strings.Join(keywords, "|")+")") + reg = regexp.MustCompile("(" + strings.Join(keywords, "|") + ")") + return +} + +func htmlify(w http.ResponseWriter, r *http.Request, content string, reg *regexp.Regexp) string { + // TODO: 正規表現を引数で渡す + + // まず最初に治す + if content == "" { + return "" + } + kw2sha := make(map[string]string) - content = re.ReplaceAllStringFunc(content, func(kw string) string { + content = reg.ReplaceAllStringFunc(content, func(kw string) string { kw2sha[kw] = "isuda_" + fmt.Sprintf("%x", sha1.Sum([]byte(kw))) return kw2sha[kw] }) content = html.EscapeString(content) for kw, hash := range kw2sha { - u, err := r.URL.Parse(baseUrl.String()+"/keyword/" + pathURIEscape(kw)) + u, err := r.URL.Parse(baseUrl.String() + "/keyword/" + pathURIEscape(kw)) panicIf(err) link := fmt.Sprintf("%s", u, html.EscapeString(kw)) content = strings.Replace(content, hash, link, -1) diff --git a/webapp/go/type.go b/webapp/go/type.go index fc2c929..262b9cd 100644 --- a/webapp/go/type.go +++ b/webapp/go/type.go @@ -6,12 +6,13 @@ import ( ) type Entry struct { - ID int - AuthorID int - Keyword string - Description string - UpdatedAt time.Time - CreatedAt time.Time + ID int + AuthorID int + Keyword string + Description string + UpdatedAt time.Time + CreatedAt time.Time + KeywordLength int Html string Stars []*Star