Cache the tags on the database
This commit is contained in:
parent
c306e00867
commit
a574a38ccc
3 changed files with 75 additions and 58 deletions
39
config.go
39
config.go
|
@ -1,22 +1,25 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PORT = "8080"
|
PORT = "8080"
|
||||||
DB_IP = "127.0.0.1"
|
DB_IP = "127.0.0.1"
|
||||||
DB_NAME = "trantor"
|
DB_NAME = "trantor"
|
||||||
BOOKS_COLL = "books"
|
META_COLL = "meta"
|
||||||
USERS_COLL = "users"
|
BOOKS_COLL = "books"
|
||||||
PASS_SALT = "ImperialLibSalt"
|
TAGS_COLL = "tags"
|
||||||
TAGS_DISPLAY = 50
|
USERS_COLL = "users"
|
||||||
SEARCH_ITEMS_PAGE = 20
|
PASS_SALT = "ImperialLibSalt"
|
||||||
NEW_ITEMS_PAGE = 50
|
MINUTES_UPDATE_TAGS = 10
|
||||||
TEMPLATE_PATH = "templates/"
|
TAGS_DISPLAY = 50
|
||||||
BOOKS_PATH = "books/"
|
SEARCH_ITEMS_PAGE = 20
|
||||||
COVER_PATH = "cover/"
|
NEW_ITEMS_PAGE = 50
|
||||||
NEW_PATH = "new/"
|
TEMPLATE_PATH = "templates/"
|
||||||
CSS_PATH = "css/"
|
BOOKS_PATH = "books/"
|
||||||
JS_PATH = "js/"
|
COVER_PATH = "cover/"
|
||||||
IMG_PATH = "img/"
|
NEW_PATH = "new/"
|
||||||
RESIZE_CMD = "/usr/bin/convert -resize 300 -quality 60 "
|
CSS_PATH = "css/"
|
||||||
RESIZE_THUMB_CMD = "/usr/bin/convert -resize 60 -quality 60 "
|
JS_PATH = "js/"
|
||||||
|
IMG_PATH = "img/"
|
||||||
|
RESIZE_CMD = "/usr/bin/convert -resize 300 -quality 60 "
|
||||||
|
RESIZE_THUMB_CMD = "/usr/bin/convert -resize 60 -quality 60 "
|
||||||
)
|
)
|
||||||
|
|
75
database.go
75
database.go
|
@ -4,7 +4,11 @@ import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"labix.org/v2/mgo"
|
"labix.org/v2/mgo"
|
||||||
"labix.org/v2/mgo/bson"
|
"labix.org/v2/mgo/bson"
|
||||||
"sort"
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
META_TYPE_TAGS = "tags updated"
|
||||||
)
|
)
|
||||||
|
|
||||||
var db *DB
|
var db *DB
|
||||||
|
@ -35,7 +39,9 @@ type Book struct {
|
||||||
|
|
||||||
type DB struct {
|
type DB struct {
|
||||||
session *mgo.Session
|
session *mgo.Session
|
||||||
|
meta *mgo.Collection
|
||||||
books *mgo.Collection
|
books *mgo.Collection
|
||||||
|
tags *mgo.Collection
|
||||||
user *mgo.Collection
|
user *mgo.Collection
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +54,9 @@ func initDB() *DB {
|
||||||
}
|
}
|
||||||
|
|
||||||
database := d.session.DB(DB_NAME)
|
database := d.session.DB(DB_NAME)
|
||||||
|
d.meta = database.C(META_COLL)
|
||||||
d.books = database.C(BOOKS_COLL)
|
d.books = database.C(BOOKS_COLL)
|
||||||
|
d.tags = database.C(TAGS_COLL)
|
||||||
d.user = database.C(USERS_COLL)
|
d.user = database.C(USERS_COLL)
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
@ -169,25 +177,25 @@ func (d *DB) BookActive(id bson.ObjectId) bool {
|
||||||
return book.Active
|
return book.Active
|
||||||
}
|
}
|
||||||
|
|
||||||
type tagsList []struct {
|
func (d *DB) areTagsOutdated() bool {
|
||||||
Subject string "_id"
|
var result struct {
|
||||||
Count int "value"
|
Id bson.ObjectId `bson:"_id"`
|
||||||
|
}
|
||||||
|
err := d.meta.Find(bson.M{"type": META_TYPE_TAGS}).One(&result)
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
lastUpdate := result.Id.Time()
|
||||||
|
return time.Since(lastUpdate).Minutes() > MINUTES_UPDATE_TAGS
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t tagsList) Len() int {
|
func (d *DB) updateTags() error {
|
||||||
return len(t)
|
_, err := d.meta.RemoveAll(bson.M{"type": META_TYPE_TAGS})
|
||||||
}
|
if err != nil {
|
||||||
func (t tagsList) Less(i, j int) bool {
|
return err
|
||||||
return t[i].Count > t[j].Count
|
}
|
||||||
}
|
|
||||||
func (t tagsList) Swap(i, j int) {
|
|
||||||
aux := t[i]
|
|
||||||
t[i] = t[j]
|
|
||||||
t[j] = aux
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *DB) GetTags() (tagsList, error) {
|
|
||||||
// TODO: cache the tags
|
|
||||||
var mr mgo.MapReduce
|
var mr mgo.MapReduce
|
||||||
mr.Map = "function() { " +
|
mr.Map = "function() { " +
|
||||||
"if (this.active) { this.subject.forEach(function(s) { emit(s, 1); }); }" +
|
"if (this.active) { this.subject.forEach(function(s) { emit(s, 1); }); }" +
|
||||||
|
@ -197,10 +205,33 @@ func (d *DB) GetTags() (tagsList, error) {
|
||||||
"vals.forEach(function() { count += 1; });" +
|
"vals.forEach(function() { count += 1; });" +
|
||||||
"return count;" +
|
"return count;" +
|
||||||
"}"
|
"}"
|
||||||
var result tagsList
|
mr.Out = bson.M{"replace": TAGS_COLL}
|
||||||
_, err := d.books.Find(bson.M{"active": true}).MapReduce(&mr, &result)
|
_, err = d.books.Find(bson.M{"active": true}).MapReduce(&mr, nil)
|
||||||
if err == nil {
|
if err != nil {
|
||||||
sort.Sort(result)
|
return err
|
||||||
}
|
}
|
||||||
return result, err
|
|
||||||
|
return d.meta.Insert(bson.M{"type": META_TYPE_TAGS})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DB) GetTags(numTags int) ([]string, error) {
|
||||||
|
if d.areTagsOutdated() {
|
||||||
|
err := d.updateTags()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result []struct {
|
||||||
|
Tag string "_id"
|
||||||
|
}
|
||||||
|
err := d.tags.Find(nil).Sort("-value").Limit(numTags).All(&result)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tags := make([]string, len(result))
|
||||||
|
for i, r := range result {
|
||||||
|
tags[i] = r.Tag
|
||||||
|
}
|
||||||
|
return tags, nil
|
||||||
}
|
}
|
||||||
|
|
19
trantor.go
19
trantor.go
|
@ -82,24 +82,7 @@ type indexData struct {
|
||||||
func indexHandler(w http.ResponseWriter, r *http.Request) {
|
func indexHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
var data indexData
|
var data indexData
|
||||||
|
|
||||||
/* get the tags */
|
data.Tags, _ = db.GetTags(TAGS_DISPLAY)
|
||||||
tags, err := db.GetTags()
|
|
||||||
if err == nil {
|
|
||||||
length := len(tags)
|
|
||||||
if length > TAGS_DISPLAY {
|
|
||||||
length = TAGS_DISPLAY
|
|
||||||
}
|
|
||||||
data.Tags = make([]string, length)
|
|
||||||
for i, tag := range tags {
|
|
||||||
if i == TAGS_DISPLAY {
|
|
||||||
break /* display only 50 */
|
|
||||||
}
|
|
||||||
if tag.Subject != "" {
|
|
||||||
data.Tags[i] = tag.Subject
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data.S = GetStatus(w, r)
|
data.S = GetStatus(w, r)
|
||||||
data.S.Home = true
|
data.S.Home = true
|
||||||
data.Books, data.Count, _ = db.GetBooks(bson.M{"active": true}, 6)
|
data.Books, data.Count, _ = db.GetBooks(bson.M{"active": true}, 6)
|
||||||
|
|
Reference in a new issue