optimize avatar partitioning, cover with test
This commit is contained in:
@@ -33,7 +33,7 @@ Remark42 is a self-hosted, lightweight, and simple (yet functional) comment engi
|
||||
| --url | REMARK_URL | `https://remark42.com` | no | all | url to remark server |
|
||||
| --bolt | BOLTDB_PATH | `/tmp` | no | all | path to data directory |
|
||||
| --site | SITE | `remark` | yes | server | site name(s) |
|
||||
| --admin | ADMIN | | yes | server | admin(s) names (user id) |
|
||||
| --admin | ADMIN | | yes | server | admin names (list of user ids) |
|
||||
| --backup | BACKUP_PATH | `/tmp` | no | server | backups location |
|
||||
| --max-back | MAX_BACKUP_FILES | `10` | no | server | max backup files to keep |
|
||||
| --session | SESSION_STORE | `/tmp` | no | server | path to session store directory |
|
||||
@@ -50,6 +50,8 @@ Remark42 is a self-hosted, lightweight, and simple (yet functional) comment engi
|
||||
| --dbg | DEBUG | `false` | no | all | debug mode |
|
||||
| --dev-password | DEV_PASSWD | | no | all | password for `dev` user |
|
||||
|
||||
_all multi parameters separated by `,`_
|
||||
|
||||
#### Run modes
|
||||
|
||||
* `server` activates regular, server mode
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
@@ -25,6 +26,9 @@ type AvatarProxy struct {
|
||||
DefaultAvatar string
|
||||
RoutePath string
|
||||
RemarkURL string
|
||||
|
||||
once sync.Once
|
||||
ctcTable *crc64.Table
|
||||
}
|
||||
|
||||
const imgSfx = ".image"
|
||||
@@ -122,14 +126,15 @@ func (p *AvatarProxy) Routes() (string, chi.Router) {
|
||||
|
||||
// Default returns full default avatar url
|
||||
func (p *AvatarProxy) Default() string {
|
||||
return strings.TrimRight(p.RemarkURL, "/") + p.RoutePath + "/" + p.DefaultAvatar
|
||||
return path.Join(p.RemarkURL, p.RoutePath, p.DefaultAvatar)
|
||||
}
|
||||
|
||||
// get location for user id by adding partion to final path in order to keep files
|
||||
// in different subdirectories and avoid too many files in a single place.
|
||||
// the end result is a full path like this - /tmp/avatars.test/92
|
||||
func (p *AvatarProxy) location(id string) string {
|
||||
checksum64 := crc64.Checksum([]byte(id), crc64.MakeTable(crc64.ECMA))
|
||||
p.once.Do(func() { p.ctcTable = crc64.MakeTable(crc64.ECMA) })
|
||||
checksum64 := crc64.Checksum([]byte(id), p.ctcTable)
|
||||
partition := checksum64 % 100
|
||||
return path.Join(p.StorePath, fmt.Sprintf("%02d", partition))
|
||||
}
|
||||
|
||||
@@ -106,3 +106,20 @@ func TestRoutesDefault(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, int64(10), sz)
|
||||
}
|
||||
|
||||
func TestLocation(t *testing.T) {
|
||||
p := AvatarProxy{StorePath: "/tmp/avatars.test"}
|
||||
|
||||
tbl := []struct {
|
||||
id string
|
||||
res string
|
||||
}{
|
||||
{"abc", "/tmp/avatars.test/35"},
|
||||
{"xyz", "/tmp/avatars.test/69"},
|
||||
{"blah blah", "/tmp/avatars.test/29"},
|
||||
}
|
||||
|
||||
for i, tt := range tbl {
|
||||
assert.Equal(t, tt.res, p.location(tt.id), "test #%d", i)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user